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.
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.
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.
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”.
* is-a could be said of classes OR instances.
* has-a should be said of instances.
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
* listener, publisher, consumer
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
* flexibility, adaptability
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.