aspose file tools*
The moose likes OO, Patterns, UML and Refactoring and the fly likes IBM Test: Coupling question Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Engineering » OO, Patterns, UML and Refactoring
Bookmark "IBM Test: Coupling question" Watch "IBM Test: Coupling question" New topic
Author

IBM Test: Coupling question

Andrew Davidson
Greenhorn

Joined: Feb 12, 2002
Posts: 1
Can anyone please help me with the following question from the IBM 486 Mock exam:
In design #1, the Catalog object has a getProducts() method, which returns a collection object, such as a Dictionary or array, containing all the Products the company sells. In design #2, the Catalog object has a getProductNumbered(anIdentifier) method, which returns the Product with the specified unique identifier. Considering the objects returned, which of the following BEST characterizes the two designs?
a) Both designs maintain the objects' encapsulation and reduce coupling by accessing state data via methods only and not directly.
b) Both designs break the objects' encapsulation, adding brittle coupling.
c) Design #1 breaks the encapsulation of the Catalog, adding brittle coupling. Design #2 maintains the encapsulation of the Catalog, making future design changes easier
Choose one answer.
I think that design #2 would add brittle coupling because the object calling a Catlogue object would have to know how products are identified.
Therefore by process of elemination the answer must be B. But how does design #1 add brittle coupling.

Cheers
Andrew
David Roberts
Ranch Hand

Joined: Nov 03, 2000
Posts: 142
I hear what you're saying. Given the only available answers I would guess a is correct. I also would like this explained though.

------------------
David Roberts, SCJP2


David Roberts - SCJP2,MCP
Junilu Lacar
Bartender

Joined: Feb 26, 2001
Posts: 4699
    
    7

I remember this question being there the last time I took the mock exam. I got 90+% overall and I'm pretty sure that I got 100% in the section that this question belongs. I answered B. My reason: get/set methods in general break an object's encapsulation. Allen Holub wrote in one of his articles "Don't ask for the information that you need to do something; rather, ask the object that has that information to do the job for you." and "Get/set methods...are just elaborate ways to make the data public."
Whenever one class invokes a method of another class, a point of coupling is created. When a class invokes get method of another class, the coupling extends to the class that is returned, thus making the coupling a little tighter and thus more brittle. In the given scenario, any class that invokes the get methods that return either a collection of Products or a single Product becomes coupled to both the Catalog class and the Product class.
Right now you might be saying "Yeah, well then how do you propose to avoid the brittle coupling?" To be honest, I'm still trying to figure that one out. It may not be possible to avoid the extended coupling at all. Maybe the only thing we can do is to make the coupling less brittle. My initial thoughts on how this might be done involve the Typesafe Enum pattern (described by Joshua Bloch of IBM), the Command (GoF) or Capsule (Robert Martin, objectmentor.com) pattern, and delegation (asking Catalog to do something with a Product with the parameters encapsulated in a Command or Capsule).
J.Lacar

[This message has been edited by JUNILU LACAR (edited March 30, 2001).]


Junilu - [How to Ask Questions] [How to Answer Questions]
David Roberts
Ranch Hand

Joined: Nov 03, 2000
Posts: 142
I see. whew, everything I hear makes sense, but I still don't see the light. I'm to the point in Larman's book where he discusses this very thing. Maybe I'll pick up some new insight.

------------------
David Roberts, SCJP2
Paul Ralph
Ranch Hand

Joined: Aug 10, 2000
Posts: 312
Junilu: Can you point to the article by Allen Holub directly? I'm having a hard time finding it. Thanks
Paul R
Paul Ralph
Ranch Hand

Joined: Aug 10, 2000
Posts: 312
Is this the article you were referring to? http://www.holub.com/goodies/what_is_an_object.html
Paul R
David Roberts
Ranch Hand

Joined: Nov 03, 2000
Posts: 142
The key to this question is:

Considering the objects returned

Passing back a collection of products requires the client be coupled to the product class and know how to iterate through the collection.
Passing back a product requires the client to know the same thing.
I try and assume their are no trick questions.
The Catalog should have these methods since it is the information expert. I don't see any other way to get a products info without exposing the product class.
The only thing I could see is maybe using an iterator pattern in design 1, so that the client doesn't have to know how to move through the collection.
My guess is A or C. I believe they are comparing and contrasting the designs. Because of this belief, I think C is correct. I believe it offers a better solution.
------------------
David Roberts - SCJP2,MCP
Desai Sandeep
Ranch Hand

Joined: Apr 02, 2001
Posts: 1157
David,
Please let me know your views on the following approach to crack this problem.
As Larman suggests in Chapter 19:

As always, Expert should be the first pattern considered unless it is a controller or creation problem

Going by this rule, since Catalog contains Products, I believe Catalog as a good candidate for Creator of Products.Hence Catalog should define a Collection instance to hold the product objects.
So how can Catalog create Products?

  1. Using Design#1,the Product would be created in the Catalog constructor, by calling the Product's constructor and adding each Product created to the Collection Object.The getProducts() method would simply return the Collection Object.
  2. Using Design#2, where the Catalog has a method getProductNumbered(identifier) which returns a Product instance.This method may be implemented as returning the Product instance searching the Collection Object.

  3. Which Design would be the BEST from the view of low coupling and encapsulation?
    Larman states :

    [...]Coupling is probably not increased because the created class is likely already visible to the creator class,due to the existing associations that motivated its choice as creator.

    By the above rule, we can assume low coupling in both the designs.Also, since both the classes use their own information to fulfill their tasks, encapsulation is maintained.
    Hence I would opt for A.
    Regards,
    Sandeep

    • Sun Certified Programmer for Java 2 Platform Scored 93 per cent
    • Oracle JDeveloper Rel. 3.0 - Develop Database Applications with Java Scored 56 out of 59
    • IBM Enterprise Connectivity with J2EE Scored 72 per cent
    • Enterprise Development on the Oracle Internet Platform Scored 44 out of 56

    • [This message has been edited by Desai Sandeep (edited May 08, 2001).]


<b>Sandeep</b> <br /> <br /><b>Sun Certified Programmer for Java 2 Platform</b><br /> <br /><b>Oracle Certified Solution Developer - JDeveloper</b><br /><b>-- Oracle JDeveloper Rel. 3.0 - Develop Database Applications with Java </b><br /><b>-- Object-Oriented Analysis and Design with UML</b><br /> <br /><b>Oracle Certified Enterprise Developer - Oracle Internet Platform</b><br /><b>-- Enterprise Connectivity with J2EE </b><br /><b>-- Enterprise Development on the Oracle Internet Platform </b>
David Roberts
Ranch Hand

Joined: Nov 03, 2000
Posts: 142
I see your point but the Catalog most definitly has a collection of products whether design 1 or 2 is used.
I think the question refers to how the collection is accessed. If the client has access to the collection, then it can now alter the collection and change the data, in design 2, even if the products are dereferenced by the client, they can still be referenced by the Catalog within the collection. All the client may need is the capability to iterate through the collection which tells me returning the collection would break encapsulation. Also in design to the "set" methods can be protected so non packaged components can't alter the contents.
I still tend to think c is the correct answer.
What other approaches might you have? Maybe if we look at this from enough angles we'll nail it down.

------------------
David Roberts - SCJP2,MCP
Desai Sandeep
Ranch Hand

Joined: Apr 02, 2001
Posts: 1157
David,
I had thought in these lines :

  1. Catalog has a container(Collection object) for all the Products.
  2. If the Client wants to change the Product data, he will have to get the Product Object first by

  3. Iterating through the Collection object
  4. Calling the getProductNumbered(productIdentifier).The implementation of this method could either be iterating through the Collection Object or sending a create message to the Product, which may invoke Product Constructor.
  5. Once the Product Object is obtained, the responsibility of changing the state data, will be possible only by the setter(mutator) methods of the Product Object.So the client will have to delegate the responsibility to the Product object, as the Catalog Object is ignorant about this information.

  6. Since the Product Object is setting its own data, encapsulation is maintained.Also, as the Creator pattern suggests to hold the Product Objects in the Catalog, low coupling will be maintained.
    Hence I prefer A)!!!
    Packaging (and thus protected nature of setter methods!!) should not be problem, because high related responsibilities are usually put in the same package.Hence it would be reasonable to assume Catalog and Product in the same package.
    - Sandeep
    [This message has been edited by Desai Sandeep (edited May 09, 2001).]
David Roberts
Ranch Hand

Joined: Nov 03, 2000
Posts: 142
Desai,
Set/Get methods don't offer encapsulation necessarily. Who should be responsible for altering a product? Probably the catalog since he knows about products. Wrapping private data in set methods is not exactly encapsulation to me. Encapsulation means hiding data, not just wrapping logic around it. I do know that the term is used loosely by most people.
So in other words, In this scenario I would say:
1. yes
2. Not exactly, we're not dictating how products get change in the questions, just want design breaks encapsulation.
3. This was my above point.
For this:

Packaging (and thus protected nature of setter methods!!) should not be problem, because high related responsibilities are usually put in the same package.Hence it would be reasonable to assume Catalog and Product in the same package.

I presumed the same. In fact this was my point. You could allow Catalog (or some other object) the ability to change a product and not the client.
I'm still with c because:

c) Design #1 breaks the encapsulation of the Catalog, adding brittle coupling. Design #2 maintains the encapsulation of the Catalog, making future design changes easier

The Catalog has a private member variable pointing to a multiobject. In design 1 Catalog hands this reference to the client, breaking encapsulation in my opinion. If anything the iterator pattern should be used rather then returning the collection.

------------------
David Roberts - SCJP2,MCP
David Roberts
Ranch Hand

Joined: Nov 03, 2000
Posts: 142
I forgot to mention, I'm still not 100% sure, but it may help to play the devils advocate so we can figure this out. I actually leaned toward A at first as well.
------------------
David Roberts - SCJP2,MCP
Desai Sandeep
Ranch Hand

Joined: Apr 02, 2001
Posts: 1157
David,
I have been working on this question continously, applying the principles that I have learnt reading Craig Larman. (BTW, managed to reach Chapter 34 today!!!)
Well, with our discussions we are atleast sure that it has to be A or C.
I have started thinking on this question from a different prospective.When I read the question many number of times, I am forced to believe that the examiner wants to check on a very particular concept - VISIBILITY.The question is about how much of visibility should you provide to Product object in the Catalog object, so that we can come out with the BEST design.
The examiner gives us 2 designs to play with - a Collection of Products AND a reference of a Product in the Catalog class.
Since the question demands to choose the BEST, we are left to select an option in which the Catalog object will have mimimum visibility and also least coupling with the Product object.
If we start thinking on these lines then :

  1. Design#1, allows the entire Product object to be visible in the Catalog object.
  2. Design#2, allows only ProductIdentifer - anIdentifier of the Product object to be visible in the Catalog object.

  3. So Design#2 appeals more than Design#1.
    With the above reasoning, I am convinced on the following points:

    • Design #1 breaks the encapsulation of the Catalog, adding brittle coupling -- Since the entire Product information is visible to Catalog Object - Hence no encapsulation and very high Coupling!!
    • Design #2 making future design changes easier - Perhaps!!Atleast it is a better design than Design#1 w.r.t. low coupling - Hence greater reuse.

    • But what do you make of this:

      Design #2 maintains the encapsulation

      Are you convinced?You are allowing the ProductIdentifier of the Product object to be visible in the Catalog object - Does that not break encapsulation?
      If it doesnot, I am with you on this, i.e, Option C!!!
      Appreciate your views.
      - Sandeep
      [This message has been edited by Desai Sandeep (edited May 12, 2001).]
Peter den Haan
author
Ranch Hand

Joined: Apr 20, 2000
Posts: 3252
Have been following this discussion with interest.
I'm half-convinced by David's argument that "in design 1 Catalog hands this [internal collection] reference to the client, breaking encapsulation". Half-convinced, because there is no a priori reason why the returned collection should be related to the way the catalog is represented internally. On the other hand, performance considerations may force you to use a data structure which can be efficiently turned into the required collection, which is a form of coupling.
But design 1 breaks encapsulation in subtler ways. Returning a collection of Products implies that all products must be loaded into memory. In a catalog which may eventually grow large, that is an assumption I would not want to expose - someday you may need to load parts of the catalog up from a database on demand.
Together, these makes me lean towards answer c.
Sandeep, I don't understand your last point? Design 2's getProductNumbered(anIdentifier) presumably returns a Product object, hence exposes as much information about the Product as design 1.
- Peter
Desai Sandeep
Ranch Hand

Joined: Apr 02, 2001
Posts: 1157
Hi,

Design #2 maintains the encapsulation

I am able to refute the above statement now!!It seems correct, if we think in terms of Product object as a whole, rather than considering its internal representation.
Design#2 exposes the ProductIdentifier- anIdentifier of Product Object to the Catalog Object.The Catalog Object still doesn't have the complete information of the Product Object.If it needs that, it has to ask/delegate the responsibility to the Product Object - hence encapsulation is maintained!!
The Conceptual Model of the two designs may yield to:



Peter,I got the following wrong!!

Design 2's getProductNumbered(anIdentifier) presumably returns a Product object,hence exposes as much information about the Product as design 1.

I am correcting myself to saying although Design#2 may return a Product object; the Catalog object tries to obtain the reference by only exposing the ProductIdentifier.Hence encapsulation of Product object is maintained in Design#2 - unlike Design#1, where the entire Product details is available to the Catalog Object (probably in one of its Collection attributes to manipulate by itself!!)
-- Sandeep
[This message has been edited by Desai Sandeep (edited May 13, 2001).]
Junilu Lacar
Bartender

Joined: Feb 26, 2001
Posts: 4699
    
    7

My $0.02:
I still stick to my original answer of B.
Going back to OO design basics and Larman's "desert island skill": Knowing how to properly assign responsibilities.
Who should be responsible for creating Products? Shouldn't it be the Product class? as in
Product p1 = new Product(aProductID);
What business does Catalog have with creating Products? None, I think. Sure, you can have the Catalog.addProduct(Product) or Catalog.deleteProduct(Product) or even Catalog.searchProduct(Product), but Catalog.getProduct(aProductID) smells like feature envy to me. Mind you, the addProduct() and deleteProduct() methods in Catalog only did so regarding Products listed in the Catalog. No actual Products are created or deleted in those calls. searchProduct() will do a search for a listing of a particular Product in the Catalog. That knowledge and responsibility is appropriate to Catalog.
Should Catalog really give out lists of Products? Again, shouldn't Product be responsible for giving out lists of itself? Of course, it could still collaborate with a Catalog, but still the main responsibility would be with Product. Also keep in mind Allen Holub's admonition to not ask the information to do a job from an object but ask the object that has the information to do the job.
Some possible code:
ProductList newProds = Product.listProducts;
Product could use a "helper" object that knows how to iterate though a list of Products. Tight coupling between a ProductList and Product would still be appropriate, I think. Then you could define ProductList as implementing the Iterator interface so you could go through the list. You won't be limited to having the whole list in memory: you are free to do the retrieval on-demand since you are defining the behavior of ProductList yourself.
With this scheme, you won't even have to make ProductList public: it could be an inner class that implements Iterator. So you would have the code:
Iterator productIterator = Product.getIterator();
while (productIterator.hasNext()) {
// process next Product
}
Junilu
P.S.
OK, I thought about this a bit more and maybe I'm a little off track on what <pre>Collection Catalog.getProducts() {}</pre> is about. I'll have to pick up later since I only have a few more hours left to get some sleep.

[This message has been edited by JUNILU LACAR (edited May 14, 2001).]
[This message has been edited by JUNILU LACAR (edited May 14, 2001).]
Peter den Haan
author
Ranch Hand

Joined: Apr 20, 2000
Posts: 3252
Originally posted by JUNILU LACAR:
Should Catalog really give out lists of Products? Again, shouldn't Product be responsible for giving out lists of itself? Of course, it could still collaborate with a Catalog, but still the main responsibility would be with Product.

Should a java.util.List really give out an Object? Shouldn't java.lang.Object be responsible for giving out Lists of itself?
Well, no, of course not -- even if it were our own class instead of a standard Java collection class.
Obviously, the Product class is responsible for creating Products in the narrow "new Product()" sense. It is equally fine for another class -- call it a Factory -- to be responsible for creating Products (using new Product()) or Product lists. To reject this is to reject the GoF, which surely counts as a heresy worthy of excommunication from the OO community.
Tight coupling between a ProductList and Product would still be appropriate, I think.

To the contrary, it would be very bad design to give the Product class the responsibility of encapsulating product information and business logic and the management of product collections. Product collections are really a step up from a single Product. More so if you remember that there will probably be database access code and product list caching involved. These responsibilities are quite separate from that of the Product class itself, and tightly coupling them is a mistake.
To illustrate that in a very practical way, what if we introduce a new type of Product (a PremiumProduct) with extra state and behaviour? A Catalog could easily be modified to accomodate this. The same modification would sit rather uneasily in the Product class.
- Peter

[This message has been edited by Peter den Haan (edited May 14, 2001).]
Junilu Lacar
Bartender

Joined: Feb 26, 2001
Posts: 4699
    
    7

Originally posted by Peter den Haan:
Should a java.util.List really give out an Object? Shouldn't java.lang.Object be responsible for giving out Lists of itself?
Well, no, of course not -- even if it were our own class instead of a standard Java collection class.

As I said in the post script to my last post, I may have been off track with the Catalog and list of Products. It probably would be appropriate for a Catalog to give out a list of Products that were listed in it. But then again, it might be more appropriate to ask the Catalog to do something with the Products or a subset of Products that it has.
Surely, you don't think that the Java standard library is perfectly OO. Much of it is still not as OO as it could be (look at the Math class and a lot of things that are in java.util) and I think that's the reason for some things getting deprecated over time.

Obviously, the Product class is responsible for creating Products in the narrow "new Product()" sense. It is equally fine for another class -- call it a Factory -- to be responsible for creating Products (using new Product()) or Product lists. To reject this is to reject the GoF, which surely counts as a heresy worthy of excommunication from the OO community.

Is the Factory pattern applicable here? Would it be appropriate to make the Catalog a factory for Products? And why the sarcasm? "excommunication from the OO community"? Where did that come from?

To the contrary, it would be very bad design to give the Product class the responsibility of encapsulating product information and business logic and the management of product collections. Product collections are really a step up from a single Product. More so if you remember that there will probably be database access code and product list caching involved. These responsibilities are quite separate from that of the Product class itself, and tightly coupling them is a mistake.

You seem to have misunderstood me. The Product class collaborates with a "helper" class, the ProductList. Logic to manipulate lists of Products is encapsulated in the ProductList class, not the Product class. Peter Coad's models in his book "Java Modeling in Color" have classes giving out lists of themselves all the time. The only clean way I can think of to do this is to have a "helper" inner class that encapsulates the logic for manipulating lists. These helper classes would necessarily and appropriately be tightly coupled to their outer classes.

To illustrate that in a very practical way, what if we introduce a new type of Product (a PremiumProduct) with extra state and behaviour? A Catalog could easily be modified to accomodate this. The same modification would sit rather uneasily in the Product class.

That smacks of dependency. Remember the Liskov Substitution Principle? Shouldn't the Catalog class be able to handle any Product regardless of what kind it is, now and in the future? Why should you change the behavior of Catalog if you add a new Product? Would you change the behavior of a Canvas if you add a new Shape? And why would the change to Product sit uneasily in the Product class? I would think it would be rather comfortable there.
Junilu

[This message has been edited by JUNILU LACAR (edited May 14, 2001).]
Peter den Haan
author
Ranch Hand

Joined: Apr 20, 2000
Posts: 3252
Surely, you don't think that the Java standard library is perfectly OO.
No, but the collections generally struck me as pretty well thought out...
Is the Factory pattern applicable here?
No, Catalog is not a Factory. I tried to make a more general point: you seemed to imply for a moment that it was wrong for any class but a Product to create products. A common factory would violate that.
And why the sarcasm? "excommunication from the OO community"? Where did that come from?
From my weirdo sense of humour. It was just an attempt to inject a bit of wit in what seemed a dry discussion. Apparently it misfired, apologies.
You seem to have misunderstood me. The Product class collaborates with a "helper" class, the ProductList. Logic to manipulate lists of Products is encapsulated in the ProductList class, not the Product class.
Of course you would do that -- but that would just mean that Product delegates its persistence responsibility, without shedding it. Inner classes won't really reduce the complexity for the poor developer who has to maintain it.
What if you want to use Products in a context which requires a completely different persistence model? -- you want to send Product information as XML or whatever? Expand the Product class (with or without the aid of helper classed behind it?)
That smacks of dependency. Remember the Liskov Substitution Principle? Shouldn't the Catalog class be able to handle any Product regardless of what kind it is, now and in the future? Why should you change the behavior of Catalog if you add a new Product?
Well, in the Real World[tm] Catalog would delegate both creation and persistence to other classes. I don't really care whether a class delegates its responsibilities to underlying helper classes or factories, it just seems to clutter the discussion.
And why would the change to Product sit uneasily in the Product class? I would think it would be rather comfortable there.
Not a change of Product, but a new class of Product: a subclass called PremiumProduct. And I wouldn't be entirely comfortable putting code which creates PremiumProducts in the Product class (although some abstract classes in the Java library do similar things).
- Peter
Junilu Lacar
Bartender

Joined: Feb 26, 2001
Posts: 4699
    
    7

Going back to Larman, he discusses a framework at the back of the book. He uses Proxies to do the "dirty work" related to object persistence and such. These Proxies are inherently tightly coupled to the classes that they Proxy for. I find this very similar to Allen Holub's discussion of his so-called Visual-Proxy pattern. If the way object persistence works changes, a new Proxy is created, but the actual business object is left unchanged. Tight coupling is not always bad. Like with a lot of things in the Real World[tm], tight coupling is only bad if it is inappropriate.
To paraphrase Robert Martin, good OO design is about managing dependencies. The whole point of OO is not to reduce complexity, but to keep it manageable. Change happens, especially in the Real World[tm]. Good designs allow you to easily change programs without too much pain.
A quote from "The Elements of Java Style" by Vermeulen, Ambler, et. al., Rule #70 discussing the Liskov Substitution Principle:
Any design that requires code changes to handle the introduction of a newly derived class is a bad design.

In the Real World[tm], if Catalog were in any way, directly or indirectly through helper classes or factories, responsible for the creation or persisting of a Product class, it would still be one heck of a bad design.
I would not put code to create a subclass of Product in the Product class either. That code needs to be in the subclass or one of its helpers/factories.
Junilu

[This message has been edited by JUNILU LACAR (edited May 14, 2001).]
David Roberts
Ranch Hand

Joined: Nov 03, 2000
Posts: 142
This is an incredible conversation. Very interesting. Let me start by saying my arguments pertained to what I thought the correct answer was, not the best design.
Here's a couple of things I've found:
1. I passed the IBM 486 test today (only 76%, bad in requirements), and I don't think this question would be an issue at all.
2. Java is a good example. It uses of the Iterator pattern for something like an ArrayList. The question asks, "Consider the object returned" and this is why I feel returning a collection as opposed to an iterator breaks encapsulation. This of course comes from GoF and not directly from Larman's book.
The designs don't say where the identifier came from, and Larman has classes in his book that do this. The question is, does the IBM test consider wrapping attributes in methods as encapsulation, or do the think it's more, like I do.
If you really want to know the answer, take the preassessment until you get 100%. I think I know the answer is C because I took the test, missed only 1 in design (93%) when I answered A, and I've gotten the other design questions correct when taking the test previous times.
I only got one question that related to this on the real test and it was easier. Although I thought the test itself was harder and not worded any better.
In any case I can see eveyones point of view, and I bet if we had the luxary of looking at the whole design, we'd probably agree.
------------------
David Roberts - SCJP2,MCP
Junilu Lacar
Bartender

Joined: Feb 26, 2001
Posts: 4699
    
    7

Congratulations!
Junilu
Desai Sandeep
Ranch Hand

Joined: Apr 02, 2001
Posts: 1157
Hats off to Junilu and Peter to carry on this fantastic discussion.You guys have an excellent reasoning ability.
Congratulations David!! on clearing Test 486.
When I started the discussion with David, we were more concerned at pinning down the right answer (or eliminating the wrong ones )
Junilu, it would be great if we could talk in terms of present problem domain - for instance if you think the answer is B - Could you please elaborate on why both the Designs have high coupling and no encapsulation.

Originally posted by JUNILU LACAR
What business does Catalog have with creating Products? None, I think. Sure, you can have the Catalog.addProduct(Product) or Catalog.deleteProduct(Product) or even Catalog.searchProduct(Product), but Catalog.getProduct(aProductID) smells like feature envy to me. Mind you, the addProduct() and deleteProduct() methods in Catalog only did so regarding Products listed in the Catalog. No actual Products are created or deleted in those calls. searchProduct() will do a search for a listing of a particular Product in the Catalog. That knowledge and responsibility is appropriate to Catalog.

In any of your aforementioned methods, if any of the Catalog methods is taking Product a parameter/argument, the coupling of the Product object with Catalog would be increased - which means more visibility(less encapsulation!!) and also high coupling of Product to the Catalog object - which is exactly want we donot want as per the question!!
On the other hand, Catalog.getProduct(aProductID), may be still be relying on the Product(or its helper class) to get its information (Since the Product Object itself is not passed as a parameter, it implies Catalog is not probably aware of the Product Object and hence it is trying to get the Product Object using a key - aProductID.In that case, it is reasonable to assume that this method would probably delegate the responsibility to some helper class to get the Product reference) - hence coupling is low and encapsulation (visibility) of Product object in the Catalog is maintained.
Given the current problem, we cannot be sure on Catalog.getProduct(aProductID) implementation - whether the Catalog is doing the job of getting the Product reference itself, or it is delegating this work to the Product (or its helper class!!) - It is best not to venture in the implementation of the methods to get the right answer.
However, as I mentioned above, since we are passing an identifier, we can be reasonably sure that Catalog is not having a Product object stored internally.
Peter, we believe that the answer is C -- Are you convinced/not convinced by my views on C - last 2 posts of mine!!
Thank you for your views,
Sandeep
[This message has been edited by Desai Sandeep (edited May 15, 2001).]
Junilu Lacar
Bartender

Joined: Feb 26, 2001
Posts: 4699
    
    7

The crux of the problem, as David pointed out, is what does IBM consider as "breaking encapsulation." If they consider getters and setters as methods that break encapsulation, then B would be correct. If not, perhaps C would be correct. I believe that IBM favors the former. Last night, I finally found the results of the last two times I took the pre-assessment exam and I got 4 out of 4 in the Designs and Implementation section each time. I know that the coupling question came out in at least one of them and I answered B.
You are right when you point out that passing Product as a parameter couples Catalog to Product. However, coupling does not imply breaking of encapsulation. Nor does it imply tight coupling. You are still dealing with high level concepts and you still don't know the details either Product or Catalog and what happens inside Catalog when you hand it a Product.
When you pass in an identifier for a Product, there may be a little break in encapsulation there resulting in more brittle coupling. Reason: what if you change the way you identify Products? What if you change it from an int to a String or vice versa? You'd have to go into Catalog and do some massaging of the parameter type, perhaps overloading methods to take in the new type of ProductID.
Passing in a Product does not have this problem. Catalog and Product would have a contract that defines how Catalog queries Products given some sort of identifier. If ProductID implementation changes, then it is the responsibility of Product to maintain its contract with Catalog. The change would be made in Product and Catalog would be shielded from that change by the contract.
As for the Catalog giving out a list of Products, I think that's more in the gray area: does it really break encapsulation? In a very strict sense, it does. But then again, if Catalog returns an Iterator or some kind of standard interface that can be used to go through the list, I think it is an acceptable design that would not be too hard to refactor if the need arose.
Junilu
Desai Sandeep
Ranch Hand

Joined: Apr 02, 2001
Posts: 1157

Originally posted by JUNILU LACAR
[..]However, coupling does not imply breaking of encapsulation. Nor does it imply tight coupling. You are still dealing with high level concepts and you still don't know the details either Product or Catalog and what happens inside Catalog when you hand it a Product.

I believe, if the Product object is to be passed as a parameter to any of the methods of Catalog object, the Catalog object has to have a visibility of Product object as a whole - and if does, it would be a case of high coupling.
According to Larman, low coupling supports encapsulation- hence passing Product object would imply breaking encapsulation.


Originally posted by JUNILU LACAR
When you pass in an identifier for a Product, there may be a little break in encapsulation there resulting in more brittle coupling. Reason: what if you change the way you identify Products? What if you change it from an int to a String or vice versa? You'd have to go into Catalog and do some massaging of the parameter type, perhaps overloading methods to take in the new type of ProductID.

If there is no break in encapsulation, it means coupling is low.I understand "brittle" as "high" coupling.With only ProductId exposed to the Catalog object, it would need to do less work to access the Product object (other information/data is not available to the Catalog!!).It may need to ONLY modify the ProductId to the required type to gain access to the Product object.This means coupling between the two objects is reduced drastically.

Originally posted by JUNILU LACAR
As for the Catalog giving out a list of Products, I think that's more in the gray area: does it really break encapsulation? In a very strict sense, it does. But then again, if Catalog returns an Iterator or some kind of standard interface that can be used to go through the list, I think it is an acceptable design that would not be too hard to refactor if the need arose.

Yes, that is correct.Having a standard interface in the Catalog is an acceptable design.But in the current problem context, it means all the Product(s) information is available to the Catalog.The Catalog may even break the contract by setting the Product's attribute to a different value - this feature should be exclusively with the Product object.Also, coupling would be very high in this case, especially if you compare with Design#2, where you are atleast dependent on the Product object to get information.


Originally posted by JUNILU LACAR
Last night, I finally found the results of the last two times I took the pre-assessment exam and I got 4 out of 4 in the Designs and Implementation section each time. I know that the coupling question came out in at least one of them and I answered B.

If IBM says it should still be B, then I have to rethink where I am wrong.
I think getters/setters should be looked at from the view-point of the object as a whole; not on its internal representation.If Catalog just has a key to the Product object, then I believe, encapsulation is maintained.However having full access (all the details) to a Product object should break encapsulation.Your views, please!!
Thanks for your response,
Sandeep
[This message has been edited by Desai Sandeep (edited May 15, 2001).]
Junilu Lacar
Bartender

Joined: Feb 26, 2001
Posts: 4699
    
    7

Originally posted by Desai Sandeep:
I think getters/setters should be looked at from the view-point of the object as a whole; not on its internal representation.If Catalog just has a key to the Product object, then I believe, encapsulation is maintained.However having full access (all the details) to a Product object should break encapsulation.Your views, please!!

Passing a Product as a parameter does not break encapsulation. The ProductID is still encapsulated inside the Product. If Catalog needs to compare the Product that was passed to the Products it has listed, it would do so using the equals() method as in
<pre>
// see if aProduct is listed in this Catalog
while (iterator.hasNext() && !found)
found = ((Product)iterator.next()).equals(aProduct);
</pre>
This code does not break the encapsulation of Product. Visibility of Product as a whole by Catalog is not high/tight/brittle coupling. It is loose coupling as long as Catalog only calls the public, non-getter/setter, methods of Product.
If Product has getters and Catalog invokes them then, yes, it would again break Product's encapsulation and make the coupling more brittle. But that's what this question is all about, isn't it?
Getters break encapsulation by exposing attributes of the object. Again, remember what Allen Holub said: Don't ask the object for information that you need to do something; rather, ask the object that has the information to do something for you.
As for ProductID, Catalog should never, not one little bit, ever have to be changed just because the implementation of a Product attribute (ProductID) changes. Think of it like this: Which is more encapsulated: a Windows shortcut to JavaRanch or the actual IP address (204.144.141.266)? Isn't the Windows shortcut more abstract than the IP address? Well, isn't a reference to a Product more abstract than the actual ProductID? The higher the abstraction you have, the lower the coupling.
Holub hints at a solution: don't use primitive types as IDs; identifiers should themselves be Objects. That way, you encapsulate the identifier implementation and shield other classes from changes in the implementation with a contract for using the identifier.
I hope I don't come across here as a "purist". I use getters and setters in my code and IMO, they won't be going away soon unless the language stops supporting them.
You just have to take things in the context of your problem domain. I still try to make things as simple as they can be, but no simpler (Einstein). Like I said, I myself use getters and setters in my code. If things don't look like they are likely to change, I go for the simpler design/implementation. If things are likely to change often, then I spend some time to make the design more flexible and less coupled.
Junilu

[This message has been edited by JUNILU LACAR (edited May 15, 2001).]
Junilu Lacar
Bartender

Joined: Feb 26, 2001
Posts: 4699
    
    7

Originally posted by Desai Sandeep:
On the other hand, Catalog.getProduct(aProductID), may be still be relying on the Product(or its helper class) to get its information (Since the Product Object itself is not passed as a parameter, it implies Catalog is not probably aware of the Product Object and hence it is trying to get the Product Object using a key - aProductID.In that case, it is reasonable to assume that this method would probably delegate the responsibility to some helper class to get the Product reference) - hence coupling is low and encapsulation (visibility) of Product object in the Catalog is maintained.

Just want to comment on this specifically. Coupling of Catalog and Product is inevitable. The question is, how loose do the different designs keep that coupling? Catalog has to know about Product. The conceptual diagram of these two would show a relationship like "Catalog lists available Products". So you are wrong to think that Catalog would not be aware of a Product object if it were passed just a ProductID.
What Catalog shouldn't know or care about is how Products are identified. If Catalog methods took ProductID as a parameter and ProductID were a primitive type such as int, then Catalog would know intimate details of Product and thus break Product's encapsulation. Again, a solution would be to make ProductID an Object in order to keep the coupling loose.
Junilu
Desai Sandeep
Ranch Hand

Joined: Apr 02, 2001
Posts: 1157
Junilu,
I am very much impressed by your reasoning.
BTW, this was an excellent example :

Originally posted by Junilu Lacar:
Which is more encapsulated: a Windows shortcut to JavaRanch or the actual IP address (204.144.141.266)? Isn't the Windows shortcut more abstract than the IP address?Well, isn't a reference to a Product more abstract than the actual ProductID? The higher the abstraction you have, the lower the coupling.

I am not sure, if the degree of abstraction determines the extent of coupling and encapsulation.Taking your example,a user with a Windows shortcut to JavaRanch, would sooner or later have an access to the actual IP address.How is encapsulation achieved in that case?
I believe, coupling is all about the extent of information one class has on another.More the information, higher the coupling.
In the Product and the Catalog case, if the Catalog object has access to the Product object, calling any(or all!) of the getter methods (which are always public!!) of the Product object would reveal all the information to the Catalog.
I would say, by passing the Product object in any of the Catalog methods, Product would be saying to the Catalog - "Hey,Catalog!, you are free to explore me as much as you want!!"
As you have also mentioned in your post, calling the getter methods defined in the Product class would break encapsulation.I agree - since, you are giving the chance to the Catalog to know about Product object as a whole
Now the question is how to avoid the Catalog Object to break encapsulation and also maintain low coupling between the two objects
Design#1, contains all the Products (not one probably many!!) -
Conceptual Model would reveal "Catalog contains Product(s)".So more information, high/brittle coupling and highest risk to encapsulation.
Design#2, which calls the getProduct method on ProductId, has higher probability to be designed on the Conceptual Model "Catalog references (doesn't contain!!) Product with ProductID".This means less information, low coupling and more encapsulation.
My views on your posts:

Originally posted by Junilu Lacar:
So you are wrong to think that Catalog would not be aware of a Product object if it were passed just a ProductID.

Yes, coupling would be inevitable between Product and Catalog.The question however is, how do I get the Product object by giving as little information as I can, to the Catalog.It can only be done by using an ProductId.
If I think terms of real objects, Catalog would have short description of the Product along with an ID.If the customer wants more information he would request for information from the Catalog by identifying the Product by the ProductID.This is what Design#2 is doing!!
On the other hand, Design#1 is overloading the Catalog with all the Product information- which is not desirable.

Originally posted by Junilu Lacar:
Again, remember what Allen Holub said: Don't ask the object for information that you need to do something; rather, ask the object that has the information to do something for you.

Design#2 has a fair chance to satisfy this principle.The fact that the Catalog is passing ProductId and not Product object means that it really doesnot has information of Product object, and hence must be collaborating with some other class (probably ProductHelper) to create an instance.


Originally posted by Junilu Lacar:
[..]As for ProductID, Catalog should never, not one little bit, ever have to be changed just because the implementation of a Product attribute (ProductID) changes.
[..]Holub hints at a solution: don't use primitive types as IDs; identifiers should themselves be Objects. That way, you encapsulate the identifier implementation and shield other classes from changes in the implementation with a contract for using the identifier.

In the present problem context, the type for the identifier is not mentioned.In that case, it is reasonable to assume that Catalog wouldn't tamper with the ProductId or probably we can assume that the passing parameter is an object - as Holub has mentioned.
With the above discussions, I would still lean towards C.
Thanks for your views.
Regards,
Sandeep
[This message has been edited by Desai Sandeep (edited May 15, 2001).]
Junilu Lacar
Bartender

Joined: Feb 26, 2001
Posts: 4699
    
    7

Sandeep,
This has been a lengthy discussion and I think I have reiterated my points quite a few times. Sorry if I can't let it go at that but I just have to add a little bit more...
The main point is: getter methods break encapsulation and are not particularly OO.
Originally posted by Desai Sandeep:

In the Product and the Catalog case, if the Catalog object has access to the Product object, calling any(or all!) of the getter methods (which are always public!!) of the Product object would reveal all the information to the Catalog.
I would say, by passing the Product object in any of the Catalog methods, Product would be saying to the Catalog - "Hey,Catalog!, you are free to explore me as much as you want!!"

Don't you see that you only support my main point with this statement? If your design relied on allowing Catalog to access Product's attributes through getters, that is not an OO design! A design that relies on getters does indeed have Product saying "Hey, Catalog, you are free to explore me as much as you want!"
On the other hand, an OO design would have Catalog collaborate with Product. That is, given a reference to a Product, Catalog can ask Product to help it do things it needs to do. IOW, if Product only exposed methods that reflected its capabilities (things it can do) rather than the information it has (its attributes), Product is saying "OK, here are the things I can do for you. Ask and I shall comply gladly." Notice that Product does not reveal any information about itself, i.e. encapsulation remains intact.

If I think terms of real objects, Catalog would have short description of the Product along with an ID.If the customer wants more information he would request for information from the Catalog by identifying the Product by the ProductID. This is what Design#2 is doing!!

So, instead of Catalog having just one piece of information about Product, you want to add another piece? Now you are breaking Product's encapsulation two times! I'm sorry but that's just wrong.
Just think of objects as highly jealous and possessive things. If you said "Hey, Catalog, do you have a Product that has this ID?" Catalog says "Yeah, see, here it is" and holds it up for you to see. Then you grab it, run away, and start fooling around with Catalog's Product, leaving Catalog feeling very violated because you took his Product and did something (who knows what ) with it. This is essentially what happens when you invoke Catalog.getProduct(anIdentifier).
On the other hand, if you had a Product and you went up to Catalog and said, "Hey, Catalog, do you have this Product?" (notice that you aren't even aware that Product had some sort of ID), and Catalog takes the product, goes away to his private stash of Products, comes back and says, "Yeah, I have it." Then you say, "Well, would you be kind enough to do something with it for me?" Catalog says "Sure, but I need to see that Product again while I do it." So, you give your Product to Catalog (still oblivious to the fact that Product has an ID) and Catalog goes away and does whatever it was you asked him to do (only he knows how he does it but you don't care as long as it gets done). Everything is nice and cordial and you aren't violating Catalog's private space because you ask him to do the work. This is essentially what happens when you invoke Catalog.doSomethingWith(Product).
Thanks for listening/reading...
Junilu

P.S. Even more disturbing imagery: Think of Product as being "private parts" of Catalog that it likes to keep in its pants. Catalog.getProduct(ProductID) and (Collection)Catalog.getProducts() would have Catalog exposing its Product(s) to you and then you sticking your hands into Catalog's pants and fooling around with his Product(s).
Catalog.doSomethingWith(Product) has you keeping your hands to yourself and having Catalog do the "dirty" work, so to speak. No need to call in the OO police because of inappropriate intimacy

[This message has been edited by JUNILU LACAR (edited May 16, 2001).]
Desai Sandeep
Ranch Hand

Joined: Apr 02, 2001
Posts: 1157
Junilu,
I am totally absorbed by this discussion.This is a perfect example of what happens when you have two persons thinking in different directions.
If you take the literal meaning of Encapsulation, it means "data hiding"."Data Hiding" as such is a relative term and could only be explained in terms of objects in question.For the sake of argument, let us take Product and Catalog objects.
Product would only want to say the Catalog "Hey, Catalog, you are free to explore me as much as you want!", if and only if, Catalog obtains permission from it.
If the Catalog is using the setter/getter methods after obtaining permission of the Product, then Catalog hasn't broken encapsulation.On the other hand, if Catalog calls any public methods (whether it is atrribute related or functionality related!!), without seeking the permission(or getting the reference!!) from the Product(or its helper), the Catalog would be responsible to break encapsulation.
Encapsulation is like being an "invited guest" rather than an "uninvited one".The Catalog has to ask for the reference of the Product (be an invited guest!!) before using the setter/getter methods."Uninvited guests" would be having access to Product object against the wishes of the Product(or its helper class).
If you have the Product Object being passed as a parameter, you are giving full liberty to the Catalog to access the Product internal data, even if the Product doesnot like it.The Product would always be concerned about misuse of its instance.This is exactly what we need to avoid!!"Uninvited guests" will never be welcome!!
In other words, the Product object must have a say in who can obtain its reference.He can be reasonably sure that there would be no misuse, if he is party to giving an instance. The Product would be giving its instance only to trusted parties or "invited guests".

Originally posted by Junilu Lacar:
If your design relied on allowing Catalog to access Product's attributes through getters, that is not an OO design! A design that relies on getters does indeed have Product saying "Hey, Catalog, you are free to explore me as much as you want!"

If my design relied on getting the reference of the Product using the ProductID (which is a getter method), a request message would be sent by the Catalog to the Product(or its helper!) to get the Product's reference.The Product(or its helper class) may or may not oblige the Catalog.If it does, the Catalog would be free to access any of Product's getter/setter methods.The Product wouldn't mind this, since it has given the reference to the Catalog to precisely do this.
Note that it is again at the discretion of the Product to decide what the Catalog would do with the reference.If it wants the Catalog to access its internal representation, it would make the getter/setter methods public.If it decides, it should only expose the capabilities, it would make those methods public, and informational methods private.
To sum up, I am laying stress on the fact, that encapsulation would be decided by the context of the object in question.You have to give the responsibility to the Product object to finally decide whether the Catalog would be able to have access to its reference or not.
Essentially, if the Product gives permission to the Catalog to allow the calls to its setter/getter methods, encapsulation is maintained.
If you put the Product's reference as a parameter in any of the Catalog methods, without the knowledge of the Product, you are not only breaking encapsulation (since the calls may not be to the liking of the Product!!) but also increasing coupling (since you are overloading the Catalog with lots of information!!)

By passing ProductId you are delegating the responsibility to the Product(or its helper) class to get the reference.If the ID is not in the format the Product expected, it may not return its reference - so the getProduct(id) would return null, which is OK!!


Originally posted by Junilu Lacar:
So, instead of Catalog having just one piece of information about Product, you want to add another piece? Now you are breaking Product's encapsulation two times! I'm sorry but that's just wrong.

As I said earlier,I am against overloading the Catalog with the whole lot of Product information.Instead, I believe in keeping an id as an attribute in the Catalog object, that can request for information from the Product or its helper class.This is the best way I can think of in which the two objects can collaborate - one of the principles of OO, which will not only support encapsulation but also reduce coupling.

Originally posted by Junilu Lacar:
Just think of objects as highly jealous and possessive things. If you said "Hey, Catalog, do you have a Product that has this ID?" Catalog says "Yeah, see, here it is" and holds it up for you to see. Then you grab it, run away, and start fooling around with Catalog's Product, leaving Catalog feeling very violated because you took his Product and did something (who knows what ) with it. This is essentially what happens when you invoke Catalog.getProduct(anIdentifier).

I understand your view-point.You are saying that identifying a Product by its ID is like getting into the internal representation of the Product.
Junilu, in any case if the Catalog has a Product instance, it also means that it has its internal representation.
I would entrust the responsibility of giving a reference of the Product object to the Product Object itself or its helper object.If the Product (or its helper) based on some validation feels that there is no harm in giving the reference, then it is OK.In other words, leave it to the Product or the its helper class to decide if I am trustworthy.If Product has faith in me, he would give me the reference.
Once I have the reference, I can invoke any of the publically available methods made available to the Catalog by the Product object.This is not against the rules of encapsulation.
Additionally, for more security, the Product may also keep its getter/setter methods for any of its attributes private, if he smells something fishy.The Product would be the final judge on which method the acquired reference by the Catalog can invoke - and that too only for the reference that has been given to the Catalog by the Product. Reiterating once again - "Invited references, not Uninvited ones!!"
Hope you understand my view-point.
Thanks for your Patience ,
-- Sandeep
PS: Thanks to JavaRanch for bring interesting people like Junilu,Peter, David (my apologies,if I missed out some names ) to the forum.You guys are doing a great job.Keep up the good work!!
-- Sandeep
[This message has been edited by Desai Sandeep (edited May 16, 2001).]
Desai Sandeep
Ranch Hand

Joined: Apr 02, 2001
Posts: 1157
The correct answer is B.
Please refer to the Thread by Junilu Lacar here
Thanks,
Sandeep
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: IBM Test: Coupling question