Frequently Asked Questions
Index
General
Object Think
Collaboration Patterns
Collaboration Rules
GENERAL
Why is it called Streamlined Object Modeling?
Index
Streamlined object modeling pares down object modeling to just the bare essentials necessary
to model business domains, business rules, and business services. What gets eliminated are the
many notations and diagrams that support code generation and detailed design. These have their
places during later development stages, but get in the way when gathering business requirements.
As a wise man once said, "The ability to simplify
means to eliminate the unnecessary so that the necessary may speak." What is necessary for
modeling a business domain is to find the objects, their relationships, the business rules
governing them, and the business services performed by them. By simplifying the notation,
streamlined object models communicate the domain to business experts as well as to developers.
And although simplified in notation, streamlined object models capture complex business rules
and business services, which can be readily translated into prototype code to validate these
rules and services.
What are collaboration patterns?
Index
Collaboration patterns are the fundamental patterns underlying streamlined object modeling.
Each collaboration pattern contains two objects and represents a real world relationship within
or between one of the four categories: people, places, things, or events. Because most business
rules govern the conditions for establishing real world relationships - such as adding a
customer to an order, scheduling a flight arrival at a gate - collaboration patterns help find
business rules and organize them around the objects.
What are design molecules?
Index
Design molecule is another name for a collaboration pattern. We used this analogy instead of
the common "building block" analogy. Collaboration patterns are more like chemical
molecules
than "building blocks" because each part of the pattern - called a pattern player - has
unique
properties that determine exactly which other pattern players it can pair up with to form a
collaboration pattern. Ultimately, only 12 pairs of the pattern players form stable molecules
called collaboration patterns. However, like molecules, collaboration patterns can be combined
to form compound collaboration molecules. These larger molecules come in two varieties:
snap-togethers and overlays. Snap-together collaboration molecules connect two or more
collaboration patterns into a larger structure. Overlay collaboration molecules merge pattern
players from two or more collaboration patterns, creating new kinds of pattern players, with
new characteristics derived from the originals.
How did you discover the collaboration patterns?
Index
From our years of object modeling for commercial applications we knew most object modeling
concerns modeling four categories of objects: people, places, things, and events. We realized
that if we discovered the optimal principles for modeling each of these categories, then we
could develop a set of fundamental patterns from which we could derive all other patterns.
This inquiry into the meaning of objects yielded a collection of object selection principles
and pattern player objects. Evaluating existing patterns with the object selection principles
and the pattern players revealed that many of our favorite object modeling patterns could be
expressed in terms of the pattern player objects. In fact, many patterns that appeared unrelated
because they contained different objects were shown to contain objects that were several pattern
players combined. These combination patterns were considered second-generation. In the end, only
12 patterns were irreducible; from these or combinations of these, we theorized that we could
model nearly all real-world entities and their interactions.
As proof to ourselves, which became material for the Streamlined Object Modeling book, we
used the 12 patterns to build object models for commercial applications. In doing so, we
determined that not only could object models be constructed from the patterns, but also that
the patterns simplified the construction, organization, and coding of the object model. We were
then enable to create strategies for organizing behaviors, properties, and business rules, and
further strategies for implementing those behaviors, properties, and rules. All of these
strategies were made much easier to remember and verify when they were based upon and described
in term of the small set of collaboration patterns.
How do collaboration patterns compare to design patterns?
Index
The goal of the collaboration patterns is knowledge representation using object think
principles: personification, first-person think, localized decision-making, and encapsulation.
Collaboration patterns help quickly model a business domain by identifying the objects, object
relationships, and business rules, and distributing the business services among objects. The
resulting model is easily understandable by the domain experts as well as by developers, and
the model still exhibits good object model characteristics such as extensibility, and
scalability. Design patterns enforce design goals such as reuse, efficiency, and pluggability.
Because they extract properties, business services and rules into abstract reusable objects,
design patterns vastly increase the size and complexity of the object model, which in turn
decreases the understandability for non-technical domain experts. Use collaboration patterns
to create an analysis object model that is understandable by domain experts, and then refactor
this model with design patterns to increase its reuse, efficiency, and pluggability.
OBJECT THINK
In the Peanut Butter - Jelly example why not
let the bread apply the ingredient?
Index
This question refers to the peanut butter and jelly
sandwich object model
on p.99 in chapter five. The questioner wants to know why couldn’t the bread slice
think, “I am a bread slice. I apply an ingredient to myself in either a light or heavy
amount.”, and why couldn’t the ingredient think, “I am an
ingredient. I am applied to a bread slice in either a light or heavy
amount.”? Thus the action of applying ingredient would be
first-person for the bread slice and third-person for an ingredient, which is
the opposite of the example in the book.
Later in the book, (pg 169) we introduce the principle
“The Most Specific Carries the Load.” When trying to decide which
object to put the work in choose the one that is most specific. Most specific
is easy between collaborators ...role is more specific than actor, part is more
specific than assembly etc, member is more specific than group. Here we have to
distribute work among indirect collaborators the bread slice (place) and the
ingredient (specific item). They are indirect because they collaborate through
the transaction.
Then you have to look at the particulars of the problem. In
our example there are more varieties of ingredient ...so there are more
characteristics of ingredients to consider. Since there are more types of ingredients
than bread, the ingredient is “more specific” than the bread.
In the future, different types of ingredients may require specializations of
the Application, or have special requirements.
In our experiences the specific item (ingredient) is usually
more varied than the place (bread). A loading dock receives all sorts of
deliveries of many different types of things. How a thing is delivered depends
on its characteristics (fragile, perishable, etc.) So the thing being delivered
should make the proper kind of delivery transaction tailored to its needs.
In general the thing being acted upon should make the
transaction describing the action since it has the majority of the
characteristics that determine if the transaction is valid.
In the object world which method is best for milking a cow?
Index
In the real world, the farmer milks a milking cow. In the object world, the milking
cow offers up a milk method that creates a transaction recording how much milk
was delivered to the farmer. There are two possibilities for the milk method in the
MilkingCow class:
public MilkingTransaction milk(long millilitersRequested){ ... }
or
public MilkingTransaction milk(long millilitersRequested,
Farmer aFarmer){ ... }
The second choice is what we prefer. The cow’s milk
service creates the transaction because an old cow may have not be able to
crank out milliliters requested. So the cow knows its limits of production and
can validate milliliters requested better than the farmer. If the milliliters
requested is too much then an exception can be thrown. The farmer is also a parameter
because the transaction should not be created if the farmer does not have the proper
privileges to milk the cow.
In our methodology we localize all the testing rules in the
services involved in adding collaboration. So to test the milliliters requested
would actually be a collaboration property rule (See Ch 4) of the cow called
when the cow was added to a MilkingTransaction, and to test the farmer has the
proper privileges would be a conflict rule of the cow called when both the cow
and the farmer are added to the transaction. (See pps. 257 - 267 for a detailed
example of collaboration and conflict rules in Java).
Testing rules are invoked when the collaborations are established in case another
scenario creates a MilkingTransaction and adds the cow without going through
the cow’s milk service. If the rule to validate the milliliters requested
and the farmer were only in the cow’s milk service then they would not be
called in the alternative scenario. We want the rules called every time a cow and a farmer are added to a MilkingTransaction
regardless of which services added them. (See also:
How to Implement Collaboration Rules)
COLLABORATION PATTERNS
Why not a role and place collaboration pattern?
Index
Typically when you associate a person or thing (role or
specific item) to a place you want to record history about when the association
was made, for how long it is expected to last, etc. We record history using an
event (transaction) object. Examples are assigning an employee to an office or
assigning an piece of equipment to a production facility.
The patterns would be:
(Role
- Transaction) + (Transaction - Place). [person at place]
(Specific
Item - Transaction) + (Transaction - Place). [thing at place]
(See Figure 1.)

Patterns where a single object acts as multiple pattern
players are called Snap-Together patterns and described in Chapter Nine. (See
pp. 278-291)
These patterns work fine as long as the history of the
association is all you care about. If however your system is also tracking the
interactions of the person or thing at the place then you need an object to
describe the person or thing in the context of the place. We describe a person
or thing interacting within a specialized context using a role object. For
example if our system wanted to track the production runs a piece of equipment
made at a particular facility we would need an equipment facility role to
desribe how the machine was configued for that facility, its production
schedule, etc. When the equipment moved to a new facility it would require a
new equipment facility role for that new facility. In this example the specific
item (equipment) is also behaving like an actor object. Patterns where a
single object participates as different collaborators are called Overlay
Patterns. They are also described in Chapter Nine. (See pp. 283-296 )
Also, when a person or thing is assigned to a place and has
a role for that place, we often combine the assignment and role object into
one. (See Figure 2.). The FacilityEquipment object has both the description of
the equipment in the facility and its history of assignment. It is not
necessary to combine the two but often more convenient.

Benefits of having a separate FacilityEquipment object for
each facility are (1) that it allows for change if different facilities begin
to require different information for each machine, and (2) that it allows for
customization of behavior for each facility. For example, due to the differing
environmental conditions, a machine may require different settings or
maintenance schedules for each facility. Preferences for settings and
maintenance schedules times could be retained with the FacilityEquipment
object.
COLLABORATION RULES
Must collaboration rules be implemented
as code within their objects?
Index
No. We implemented them using programming code within our
objects to show how everything fits together. Trying to explain it in words was
difficult when some snippets of code could say it so clearly.
We recognize business rules can be in rules databases,
stored procedures, or whatever. The important fact is that the object knows how
to get to the rules and decides when to run them, rather than some centralized
manager deciding when the rules should run. Similar to telling an object
to save itself and the object knowing which data manager to contact to do the
persistence.
In fact, keeping the rules stored externally is a great
mechanism for allowing updates. The important part is when are the rules
invoked and who invokes them, wherever they are located. Those are the issues
we are trying to address.
Please explain how to implement collaboration
rules.
Index
One approach for implementing collaboration rules is shown in Chapter 8,
and the source code
provided with the book has an example similar to the
milking cow example.
In the book example a document is nominated for publication on a corporate online site by a
committee team
member. The document is the thing being acted on so it creates the nomination
with the team member through a nominate service. The “nominate” service of
the Document class is very similar to the “milk” service of the
MilkingCow class.
Collaboration rules are implemented in
“testAdd” and “testRemove” services described in detail
in Ch 8. These methods are always called when a collaboration is established or
dissolved between objects.
The constructor for MilkingTransaction looks like this:
public MilkingTransaction (long millilitersRequested, MilkingCow aCow, Farmer
aFarmer) throws BusinessRuleException
{
this.quantity = millilitersRequested;
this.addFarmer(aFarmer);
try { this.addCow(aCow); }
catch(BusinessRuleException excptn)
{
aFarmer.doRemoveMilkingTransaction(this);
throw excptn;
}
}
The MilkingTransaction addCow service calls (1) its own testAddCow method that directs the
checks for conflicts between the farmer and the cow and (2) the MilkingCow
testAddMilkingTransaction service that tests whether the cow can handle the transaction:
/* MilkingTransaction service */
public void addCow (MilkingCow
aCow) throws BusinessRuleException
{
if (aCow == null)
throw new BusinessRuleException("Tried to add null
cow");
this.testAddCow(aCow);
aCow.testAddMilkingTransaction(this);
this.doAddCow(aCow);
aCow.doAddMilkingTransactionn(this);
}
/* MilkingTransaction service */
public void testAddCow (MilkingCow aCow) throws BusinessRuleException
{
if (this.cow != null)
throw new BusinessRuleException("Cow already exists.");
if (this.farmer != null)
aCow.testAddMilkingTransactionConflict(this, this.farmer);
}
/* MilkingCow service */
public void testAddMilkingTransaction( MilkingTransaction aMTransaction)
throws BusinessRuleException
{
if (aMTransaction.getMillilitersRequested() >
this.getMaxMillimeters())
throw new BusinessRuleException ("moo...too
much...");
}
So now however a MilkingTransaction is created, the business
rules are enforced when a cow is added to it. Here’s our preferred
technique for creating the MilkingTransaction in the milk service:
/* MilkingCow service */
public MilkingTransaction milk(long millilitersRequested, Farmer
aFarmer) throws BusinessRuleException
{
return new MilkingTransaction(millilitersRequested, this, aFarmer);
}
Why don't the doAdd & doRemove methods test business
rules?
Index
The rationale about the add, testAdd, and doAdd methods is
explained in-depth in the book on pp. 241 –245, and in our article Putting
Business Rules into Business Objects.
In a nutshell, we don’t put the tests in the doAdds
and doRemoves because we want the flexibility of bypassing rules in special
cases—when restoring an object from persistent storage, or for special
trusted business services. The reason for having the doAdds is the encapsulate
the implementation of the assignment in case other things need to happen when
the object changes state, in case the assignment implementation changes, in
case specializations want to change the assignment implementation, etc.
Doesn't this mean we need to trust
our developers of the add method to call the tests?
Index
Yes. But our rational is that the add services make up the
public access layer of services for changing an object’s state. These
methods always invoke business rule checking they are the methods available to
object editors, methods of other objects, and internal methods needing business
rule checking. The doAdds are the internal methods for bypassing rule checking,
but that should be done very selectively.
Should the add service always invoke a doAdd service?
Index
Yes. The doAdd encapsulates the assignment implementation of the collaboration. For example,
how a farmer is stored within a MilkingTransaction. (See also:
How to Implement Collaboration Rules).
In fact the addFarmer method should look like this:
/* MilkingTransaction service */
public void addFarmer(Farmer Farmer) throws BusinessRuleException
{
if (Farmer == null)
{
throw new
BusinessRuleException("Tried to add null farmer");
}
this.testAddFarmer(aFarmer);
aFarmer.testAddMilkingTransaction(this);
this.doAddFarmer(aFarmer);
aFarmer.doAddMilkingTransaction(this);
}
Do you include the testAdd method when there are no
collaboration rules for that collaborator?
Index
For extensibility, we put all the test methods in even if they are no-ops.
Later if the problem domain changes so that there are collaboration
rules associated with that collaborator, less code is affected.
Why are tests for null in the add methods and not the
testAdd methods?
Index
Tests for null are logic tests as opposed to business rule
tests. Business rule tests depend upon the semantics of the
business domain and are isolated in separate test methods
to encapsulate them for maintenance and extension. Specializations may extend or
override the testAdd
methods to implement new business rules. Specializations rarely if never override
logic tests so we put that check in the add method. (See also our article Putting Business Rules
into Business Objects).
Is a BusinessRuleException a checked or unchecked
exception?
Index
Short answer: checked.
Long answer:
In the book we have BusinessRuleException as a checked
exception, but the alternative is not entirely verboten. The rationale is that
the typical Java rule for when to use RuntimeException is that you should do it
only if the exception is unlikely in a properly configured and written system.
For example, a NullPointerException should not happen because a user did not
enter something; the programmer has the option to check for null or ensure that
values are always initialized. Since business rule exceptions can and generally
do happen based upon user interaction they do not fall under this category. For
example, a user might try to have a farmer milk a cow that was milked too
recently. On the other hand, some people like to make everything a
RuntimeException. They feel this makes their code “cleaner” in that
they do not require try/catch blocks and “throws” clauses in their
code. The problem here is that someone needs to catch the exception so that the
system can recover gracefully. In the end, the choice is yours.
|