Re: Design question: Multiplying singletons



Responding to KelvSYC...

1 R1 *
[A] ------------- [B]
| 1
|
| R2
|
| *
[C]

where the requirements dictate that only one A may exist no matter how many [B] or [C] objects there are (i.e., R1 and R2 always have the same A on the 1-side for every B and C). So one implements [A] as a Singleton pattern.

All that A::getInstance() is doing is providing reference for [B] or [C] objects to use to instantiate their R1 or R2 relationship. Then A::getB() and A::getC() just provides navigation through A when a B needs to collaborate with a C or vice versa.

The problem is that if there are multiple [B] or [C] objects, one can't provide that navigation with your implementation of A::getB() and A::getC(). That is because the single A instance is actually related to multiple Bs and Cs. So long as the [B] or [C] side is *, then one needs a collection to manage the 1:* relationship and the accessors need to know which particular B or C one is after within the collection: A::getB(bID) and A::getC(cID). So...


This is a valid concern in one-to-many relationships - I'd have to take
note of that.

But suppose the relationships were one-to-one - that is, you could fold
everything in B (or C) back to A, but then A would simply balloon in
size or manageability (B or C may or may not be singleton, which would
be moot). Going back to the original question, with the one-to-one
relationship in mind, how would you keep track of the A associated with
a B (or C) if A was no longer singleton? Would the controller idea
work?

Ok, let's take a look at it:

1 R1 1
[A] ------------- [B]
| 1
|
| R2
|
| 1
[C]

If the relationships are 1:1 as above, then a given A can only be related to exactly one B and one C at a time. Since A is a Singleton, there can only be one instance of A. So exactly one B and one C is accessible from that single instance of A.

Similarly, a B can be related to only one A and a C can be related to only one A. Since there is only one A, then the model says that there can only be on B and one C as well.

That changes as soon as A is not restricted to be a Singleton. Now if there are N As, there can be N Bs and N Cs. Each A instance can be related to a different B and C instance. As it happens, since the relationship is unconditional on both ends, there must be exactly N Bs and exactly N Cs and each A must be connected to different Bs and Cs. [If, say, two As were related to the same B, then that B would be related to two As, violating the A-side 1 multiplicity. If there were more Bs than As, then some Bs would be unrelated to an A. If there were less Bs than As, then some As would be unconnected to a B.]

Thus a 1:1 relationship is a very, very strong constraint on the structure of set connectivity. (A tad pedantic, but I wanted to make sure we were on the same page.)

So to answer your question, one would usually instantiate each relationship with a pointer in each class (two in A). To ensure referential integrity, that pointer would need to be instantiated before any participant was accessed. That effectively means that one must create an A, a B, and a C at the same time and assign the four pointers at that time. ("At the same time" typically means within a single method scope; otherwise one has to provide other infrastructure to ensure access will not be premature.)

Typically one would do that with some sort of "factory" object that created the triplet. That factory object would map to your controller. But its responsibilities would be limited to instantiation and its heavy-duty responsibility would be understanding that A, B, anc C needed to be created as a triplet so that referential integrity could be enforced by instantiating their relationships.

Collections are a fairly easy extension; one just replaces the pointer with a collection handle. However, referential integrity now involves making sure the collection has the /right/ instances at the time of collaboration. (Once there is one instance available, multiplicity and conditionality are no help in determining which particular ones must be around at a given moment in time.)

If the relationships become conditional, then things get messier. The rules for instantiation get more complicated (Whether a participant needs to be available). Referential integrity needs careful management (When participants are added). Finally, one needs specific "overhead" code for every collaboration to be ensure there is a relationship there to navigate. So generally one seeks to minimize conditional relationships whenever possible by seeking out alternative navigation paths with unconditional associations or changing the rules of participation to always include at least one participant.

class B {
private int foo(C c);
public int bar() { return foo(A.getInstance().getC()); }
}

There's a typo: bar() returns a C. This needs to change to:


I don't get it. A.getInstance().getC() returns a C, but calling foo on
it returns an int, which bar returns.

You are right. I've been a translationist for two decades, so I very rarely deal with 3GL code anymore. That's my excuse and I'm sticking to it; substance abuse was not involved.


*************
There is nothing wrong with me that could
not be cured by a capful of Drano.

H. S. Lahman
hsl@xxxxxxxxxxxxxxxxx
Pathfinder Solutions
http://www.pathfindermda.com
blog: http://pathfinderpeople.blogs.com/hslahman
"Model-Based Translation: The Next Step in Agile Development". Email
info@xxxxxxxxxxxxxxxxx for your copy.
Pathfinder is hiring: http://www.pathfindermda.com/about_us/careers_pos3.php.
(888)OOA-PATH



.



Relevant Pages

  • Re: Error Logging Framework
    ... Responding to Goyal... ... > - This logger is a Singleton ... seems like your logger is going to be an entire subsystem. ... verifying that you have identified all the features such a facility needs? ...
    (comp.object)
  • Re: the wise use of singleton
    ... Responding to Phl... ... > the fields singleton in my other classes in my business logic a little ... There are two quite orthogonal issues here: whether to use a Singleton ... information is about collaboration among objects that are already ...
    (comp.object)
  • Re: the wise use of singleton
    ... Responding to Phl... ... > the fields singleton in my other classes in my business logic a little ... There are two quite orthogonal issues here: whether to use a Singleton ... information is about collaboration among objects that are already ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Singleton
    ... Responding to Mingins... ... > question was more to do with alternatives to the Singleton pattern. ... there are multiple contexts where it can instantiated. ...
    (comp.object)