objA querying objB – vague OO-speak

Update — I think architects and “savvy communicators” often practice vague OO-speak to perfection. We may need to practice it.

In OO discussions, we often say “Look here, objectA will query objectB”, by calling getTimestamp(). This is a typical example of vague/misleading OO-speak. It’s as vague as a presidential candidate promising to “reduce deficit in 4 years” without any concrete details.  Note non-OO programmers don’t develope such vague communication habits.

Here are some of the fundamental amgiuities.

* A must get a handle on B before calling B’s non-static methods. The way to get the correct B instance is often non-trivial. That sentence invariably glosses over such details.

* It’s a method in A — methodA1 — not just “object A”, that queries B. This is a crucial point glossed over in that sentence.

** The original sentence implies A is some kind of active object that can initiate actions, but actually method A is called by another method, so the real initiator is often an external entity such as a GUI user, an incoming message, the main thread of a batch job, or a web-service/EJB request. ObjectA is NOT the initiator entity.

* Return value of the query is either saved in A or used on the fly in the methodA1. The original sentence doesn’t mention it and implies objectA has some kind of intelligence/bizlogic about how to use the return value. In some cases indeed the method in objectA has that “intelligence”, but it should not be glossed over. More often, methodA1 simplify passes the query result to the upstairs method above methodA1. The upstairs method may “belong” to a different object. All the details are glossed over in the original sentence.

Here’s an even more vague phrase – “A calling B”. This glosses over the essentials of the arguments and where they come from.


a "service" having exclusive know-how about a "resource&quot: eg@vague OO-speak

Here’s another eg of vague OO-speak (see other posts on vague OO-speak)

We often say “This intelligentService class KNOWS how to use this db/inet/MOM/calc-library, so a client can invoke this command/service method on intelligentService.”

What we mean is, intelligentService class 1) has a private field for locating the resource, and 2) the command method Body can intelligently use it to satisfy the request.

The private resource field and usage logic is not exposed to clients. Encapsulated, so intelligentService class alone “knows” about it.

It’s often assumed the intelligentService developer is the only person who needs that knowledge. In practice intelligentService developer is often the same developer of the client classes, but it’s good to conceptually separate the 2 roles.

All(?) OO methods are "static" under the hood

C++ supports “free functions”, static method and non-static method. 
– Static method are very similar to free functions. (Difference? Perhaps inheritance and access modifiers.)
– Non-static methods are implemented as free functions accepting “this” as first argument.

C++ is largely based on classic-C. Basically everything translates to classic-C code, which uses free functions only.

Once we understand the c++ world, we can look at java and c# — Essentially same as c++.

Looking deeper, any method, function or subroutine consists of a sequence of instruction — a “code object” if you like. This object is essentially singleton because there’s no reason to duplicate this object or pass it by value. This object has an address in memory. You get that address in C by taking the address of a function — so-called function pointers.

In a multi-threaded environment, this code object is kind of singleton and stateless (if you know what I mean!). Think of Math.abs(). The code object itself is never thread-unsafe, but invoking it as a non-static method often is. Indeed, Invoking it as a free function can also be thread-unsafe if the function uses a stateful object. Example — localtime().

Non-static method has to be implemented based on this code object.

superclass param, subclass argument

      Dog(Number o) {
      Dog(Integer s) {
      public static void main(String[] a) {
            Number ptr = new Integer(22);
             * won’t call the (Integer) ctor.
             * Won’t compile if you remove the (Number) ctor. Compiler doesn’t know
             * ptr points to an Interger object. Compiler only knows ptr is a Number (or
             * subclass) object. Runtime type of the pointer ptr is known only at runtime.
            new Dog(ptr);

has-a vs is-a — a fine point clarified

People say “Mortgage is-a Loan” — fine. You may say a HashMap has-a Entry — you mean a HashMap instance has-a Entry instance. The distinction between Class and Instance becomes critical when you study inner classes.

Generally, it’s more accurate to say an object (of class A) has-a pointer to another object (of class B). Usually, such a relationship is defined at compile time Before instance creation.

Therefore, we could afford to be imprecise as to say “class A has-a class B”.

In summary,
* is-a could be said of classes OR instances.
* has-a should be said of instances.

treat verb as noun(OO design

So many OO patterns and designs model a verb as a noun that we don't even notice them — we model an operation as an object, an
action, a process, a behaviour as a thingy….

In my projects, verb objects out-number nount objects. Bulk of business logic is in verb objects, so we often need to break each
into many objects and perhaps apply patterns.

* command pattern
* strategy pattern
* visitor pattern
* observer pattern
* factory pattern — object-creation
* processor objects
* loader objects
* controller in MVC
* message routers
* DAO — read operations and writes
* logger
* MessageDrivenBean
* listener, publisher, consumer

OO modelling to mirror real-world relationship@@

One of the OOM principles is “mirror real world relationships” — Be careful.

It’s fine to create a class for each real world entity. However, this principle is less important than other OOM principles such as

* testability
* flexibility, adaptability
* de-coupled

Real-world relationships show lots of IS-A but these are troublesome in OOM. Often you need to model them as HAS-A.

I think mature and sophisticated OOM often uses far more class than there are real world entities. In such cases, i think those classes are often required to support flexibility.

subsumption — mouse with 2 buttons

when you assign an actual Integer to a Number variable named “n1″[1], compiler compares the 2 pointers’ types [2]. Start with the “expected” type. If Expected type has 2 methods, then the actual type “received” must support these methods. So that the Integer received can stand in as a Number.

Conceptually, we can think of the expected type’s class object to expose those 2 methods. The actual object’s class object must expose the same methods.

As an analogy, a customer (compiler) expects a mouse with 2 buttons (ie methods), so any mouse given to the customer must expose these 2 named buttons (ie methods), and can optionally have 8 other buttons(methods).

How, how does this analogy compare to the onion and remote control analogies elsewhere in this blog?

When you assign an array of Integers to a reference declared as Number[], same thing. System knows the expected type and the actual type and is happy. But ArrayList is not array. When you assign an ArrayList of Integers to a reference declared as ArrayList, compiler breaks.

[1] or pass the reference to a method argument
[2] represented by 2 class objects. Even if the 2 types are 2 interface, still there are 2 class objects.

interface, dependency&&loose coupl`

If all of YOUR instance/local vars are declared as interfaces, then

1) I can more easily reuse YOUR class in my new project. I can instantiate your object more easily.

2) I can compile it with just those interface source files, without the class source files.

3) Your class doesn’t “depend” on those classes. When those classes change, your class need not recompile.

4 types of methods to instantiate a new object

1) constructor — invoked directly by client methods
2) factory
3) special instance[1] methods to return a new object of its own class. Could be public or private.
4) singleton’s getInstance(). Static

Example of (3): shortcut constructor method.

#1 key question: How do you control access to these methods?
3) you need to get an instance of this class before calling this method. Get a chicken, then an egg.
1) no control
4) no control due to staticity
2) a static factory method offers limited control.

[1] static? less common.