Primary Noun

The PrimaryNoun requirement in many ObjectOrientedProgramming languages emphasizes one noun at the expense of the others. This leads to a loss of symmetry, and forces the programmer to make arbitrary decisions about program structure. Not all ObjectOrientedProgramming languages have the PrimaryNoun requirement (LispLanguage being the popular counter-example). --NonTopAnonymousDonor

Here is an example of the lack of symmetry caused by the PrimaryNoun requirement, followed by several examples of how to re-write it to regain the symmetry.
    result=a.add(b,c,d)
Procedural style.
    result=add(a,b,c,d)
Function as the primary noun, also known as CommandPattern.
    result=add.invoke(a,b,c,d)
Using operator overloading. Not all languages support this equally.
    result=a+b+c+d
Procedural with binary operations.
    result=add(a,add(b,add(c,d)))
Binary operations with objects.
    result=a.add(b.add(c.add(d)))
Using tuples or lists. This may not be supported in any current languages.
    result=[a,b,c,d].add
Accumulating the result with binary operations.
    int sum=0
    sum.add(a)
    sum.add(b)
    sum.add(c)
    sum.add(d)
Different types of nouns

The above example assumes that all of the nouns are of the same type. Similar problems appear when the nouns are of different types. Here is an example in which we need to keep track of employee office assignments. Note that this problem has more to do with the ownership of data than the above example.

Typical procedural style.

    assign(employee,site)
OOP style, with the employee as the PrimaryNoun.
    employee.assign(site)
OOP style, with the site as the PrimaryNoun.
    site.assign(employee)
The dilemma is which object owns the assignment data. There is usually some hint in the problem domain as to where the responsibility lies best. If not guided either way by the problem domain, a smart developer might introduce or find a third class to hold the responsibility - exactly to avoid an artificial choice of one or the other. This is the typical result with ResponsibilityDrivenDesign. For a counter-argument, see ResponsibilityDrivenDesignConflictsWithYagni.
    assignments.create(employee,site)

A many-to-many class, eh?


(Counter-point moved from ArgumentsAgainstOop)

Re:

(quote)

King Noun is Artificial - OO generally assumes there is one PrimaryNoun per action or operation. This assumption is often artificial. There is no such identifiable force of nature or human interaction. The nouns that participate in any given action are often numerous and changing. It is sometimes said that one should group code by the most stable factors. "Task" or "operation" is more stable than nouns or entities for the most part. One should be able to swap/change the noun(s) without changing the calling code. This is InformationHiding. In the real world, the relationship between nouns and actions is often many-to-many, and OO has generally been problematic with many-to-many relationships. ManyToManyChallenge.

(end-quote)

This is commonly solved by use of a class-per-task pattern, as with FunctorObject and StrategyPattern. MultipleDispatch is a language-level solution.

"Solved" by emulating non-OO is hardly "solved", and with the design overhead and complexity of the class/method system.

Reifying tasks is a fine example of OO. It isn't emulating non-OO. This particular case is closer to if OO ain't working, you aren't using enough of it.

I'd like to study a realistic scenario. StrategyPattern is not flexible to certain kinds of ChangePatterns.


See:


EditHint: Refactor the ResponsibilityDrivenDesignConflictsWithYagni ThreadMess and merge where appropriate.


EditText of this page (last edited October 4, 2011) or FindPage with title or text search