Win a copy of Functional Reactive Programming this week in the Other Languages forum!

# IBM question - Sequence diagram

Caroline Iux
Ranch Hand
Posts: 103
Which of the following is the BEST description of the sequence diagram in Figure Interaction? Single Select
http://certify.torolab.ibm.com/figures/test486F19.gif
When an instance of a:
a) Person is asked for its assets, it sums the balances of each of its asset Accounts.
b) Customer is asked for its assets, it sums the balances of each of its asset Accounts.
c) Person is asked for its assets, it returns the balance of its asset Account.
d) Customer is asked for its assets, it returns the balance of its asset Account.
First of all, it's an instance of Person. So b or d is incorrect.
My answer is a. But I can't explain why c is not right, it's sort of a gut feeling thing.
Any help is appreciated!

Desai Sandeep
Ranch Hand
Posts: 1157
Hi,
I would lean towards C.
B and D are incorrect for the reasons you mentioned - The instances are of Person not Customer.
A is incorrect.
The Person certainly asks for its assets.But when he does that, the Sequence diagram suggests that it first checks up if the Person has an account with them.If he has a account, then he simply returns the balance of its asset account, which is represented by getBalance() method.
Note that, if it had to sum up the balances, there should have been a method (before getBalance()), which calculates the sum.Absence of such a method suggests that sum of balances is not being done.
Hence, C is correct.
Hope this helps,
-- Sandeep
[This message has been edited by Desai Sandeep (edited May 17, 2001).]

Junilu Lacar
Bartender
Posts: 7786
62
The asterisks beside the messages sent by Person to Account indicate iteration (looping). The totalAssets() message sent by the actor (End User) to the Person also hints at this. The diagram says that Person iterates through all Accounts and asks each one if it is an Asset Account. If it is (the condition [isAssetAccount = "true"] is satisfied), then Person sends the getBalance() message to complete the task of calculating the totalAssets(). The summing up of the balances is implied and happens during the execution of totalAssets().
C implies that a Person has only one asset account, so it is incorrect.
BTW, going back to another issue pertaining to getters, this is a perfect example of getters breaking encapsulation. This is not a very object-oriented design. It's like going to a bank, asking a bank officer for your account records, then going through those and adding up the totals yourself. I would not put my money in that kind of bank.
A better design would have Person asking Account to give him back an Amount that indicated his totalAssets. This is like going to the bank and asking the bank officer "What are my total assets?" The bank officer goes into a secure (encapsulated) room and goes through your account records, comes back out and gives you an envelope marked "CONFIDENTIAL", saying "Your answer is in this envelope." That is the kind of professional service I would expect from a bank.
Junilu

[This message has been edited by JUNILU LACAR (edited May 17, 2001).]

Desai Sandeep
Ranch Hand
Posts: 1157
Hi,
I agree with Junilu on the answer A.Yes, the * signifies iteration and summation of all asset accounts for the Person.Thanks for correction. .
As regards encapsulation, IMHO,I should say there are lots of cobwebs in my mind. .I was reading Fundamentals of Object-Oriented Design in UML, Meiler Page-Jones today.
These are the excerpts from his book on encapsulation/information hiding/implementation hiding.

Object-Oriented encapsulation is the packaging of operations and attributes representing state into an object type so that the state is accessible or modifiable only via the interface provided by the encapsulation
In other words, it's the encapsulation of the state within the procedural mechanisms for accessing and modifying the state
The payoff of good encapsulation is supression in the public view of the myraid details to be seen in the private view.The supression takes two forms : information hiding and implementation hiding.
Information/implementation hiding is the use of encapsulation to restrict from external visibility certain information or implementation decisions that are internal to the encapsulation structure.
However, the term "information hiding" addresses only part of what a good encapsulation may hide.Encapsulation often reveals information but hides implementation.This aspect is vital to object orientation: The variable inside an object that remembers the information provided by the attribute doesnot need to be implemented the same way as the attribute itself, which is available to other objects.
In future redesign, we might decide to reveal the direction information and to provide an operation to export the direction attribute to other objects.But even then, we'd retain implementation hiding because we still wouldn't need to know whether the implementation within the object was the same as that of the public information.
For example, we may decide that the object should hold direction internally in the character form and - after converting it - export it publicly in angle form.In other words,the operation that provides the value of this attribute could convert it from an idiosyncratic internal representation to a numeric angle that most people would want to see as the attribute direction.
Information/implementation hiding is a powerful technique for taming software complexity.It means that the object appears as a black box to an external observer.In other words, the external observer has full knowledge of what the object can do, but has no knowledge of how the object may do it or how the object is constructed internally.

If I am right (would like to be corrected, though!!), this means, in the Catalog and Product case, the Product has the final say in deciding what it will expose.The getter/setter methods maynot decide, if encapsulation is broken.It is the implementation of the methods which decides this.Somewhere in the book, the author mentions that the operations represent a "protective wall" around the object's internal structure.
In the Catalog.getProduct(Id) method, the id may be some identifier (not necessarily the same which is stored!!) for the Client to request for, say "BOOK2001".When this request is passed to the Product (or its helper class), there may be a mapping of "BOOK2001" with an unique "ISBN No".If the match is found a Product instance is returned.IMHO, encapsulation is still maintained.Your views please!!
Coming to your methods Catalog.setProduct(Product), the implementation is hidden from the client, so encapsulation is not broken.
In the Person and the Account case, the implementation of the Account methods would decide the encapsulation.It may not reveal the individual account records to the Person (Note that, on addition it is only returning true.Also, it is not giving the individual account records).We really donot know the internals/implementation of the method.Since this aspect is hidden from us, encapsulation is maintained.
I am not sure on the state of your mind - wish I knew your "stateOfMind" attribute - Sincerely hope encapsulation is not maintained in this case. Am extremely sorry, if I am not able to catch up on what you are stressing on

-- Sandeep
PS :Caroline, just to keep you in the loop, this discussion has been triggered by the Coupling thread.I think, we have decided that this thread would be as long as that Thread .You are most welcome to join us.
-- Sandeep
[This message has been edited by Desai Sandeep (edited May 17, 2001).]

Junilu Lacar
Bartender
Posts: 7786
62
Sandeep,
No need to apologize for anything. It's all in the spirit of learning and sharing opinions.
One of the most interesting articles I read about OO, and one that was almost like an epiphany, was Allen Holub's first of six articles about creating a UI for OO systems and what he calls the "Visual-Proxy" pattern. I encourage you to go out to his website and read that article so you understand where I am coming from.
I can relate to Holub's complaint about the MVC architectural pattern because I have come across applications that had the same exact problems that he described. Perhaps it was just the execution that went bad, I don't know. What I do know is that those applications were pure hell to maintain and modify. We didn't have just ripple effects, we had tsunamis!
Basically, Holub says mutators (getters/setters) are "evil." I agree with him on the getters but I'm still out with the jury on setters.
Holub also says this about objects: (paraphrasing) forget what you learned about objects encapsulating data and operations. Poppycock! Objects are all about capabilities. Objects are about what they can do. Getters and setters are just fancy ways of getting to an object's inner implementation. The information that they encapsulate are part of how they do things (implementation details).
I have read other authors write things that support these claims. Getters and setters just take you back to being data-centric.
Try this: when you write a getter method, try to think about why you need that information. Then ask yourself why can't you just ask the object that has the information to do something for you?
I have found that doing this kind of role-reversal actually helps me to assign responsibilities more appropriately. And I have found that there are much fewer dependencies created when getters are avoided.
In the case of the Person and the Account, I would think: "Why do I need to ask Account for a balance, why don't I just get Account to calculate the balances for me?" That's when I realize that "Yeah, calculating account balances should be Account's responsibility, not Person's."
Junilu

Caroline Iux
Ranch Hand
Posts: 103
Originally posted by Desai Sandeep:
The variable inside an object that remembers the information rovided by the attribute doesnot need to be implemented the same way as the attribute itself, which is available to other objects.

Very interesting discussion. Thanks for keeping me in the loop and for answering my posts. I totally agree with the "implementation hiding" Desai mentioned. To give a simple example, I might have an attribute of type ArrayList in my class, but I only want to expose it to the outside world as an array. Here I hide the internal representation of my attribute.
Junilu, I haven't gone out to the website yet, so I can't say much about Allen Holub's opinions. As to the following quote from your post:

A better design would have Person asking Account to give him back an Amount that indicated his totalAssets. This is like going to the bank and asking the bank officer "What are my total assets?" The bank officer goes into a secure (encapsulated) room and goes through your account records, comes back out and gives you an envelope marked "CONFIDENTIAL", saying "Your answer is in this envelope." That is the kind of professional service I would expect from a bank.

I think if you look at the figure from another perspective. Look at the "end use" as a customer of a bank, the "person" in the figure as a bank officer. Then it is doing what you expect it to do. The "Person" doesn't just give the "end user" all the accounts back, and say "Here, you go figure out your balance yourself." Instead, the "Person" calculates the balance( sealed in an envelope if you like ), then give it back to the end user.

[This message has been edited by Caroline Iux (edited May 17, 2001).]

Desai Sandeep
Ranch Hand
Posts: 1157
Junilu,
I will go through Allen Holub articles very soon.Will post a separate thread on discussing his approach.
At the outset, I can only say Allen views contradict Larman and Meilir Page-Jones definition of encapsulation and information/implementation hiding.

Originally posted by Junilu Lacar: Try this: when you write a getter method, try to think about why you need that information. Then ask yourself why can't you just ask the object that has the information to do something for you?

I suppose, you want to suggest that if Catalog is responsible to hold the Product instances, why do we need to delegate the responsibily to the ProductHelper class?
According to Allen's(and your ) principle, the Catalog, is quite capable to give the Product instance.This sample code snipplet shows this principle:

According the Meilir Page-Jones and Larman, the design may have looked something like this:

On the face value, Design#1 looks to be a case of high coupling.This design requires the knowledge of all Product instances.According to Larman, Encapsulation and Low coupling go hand-in-hand.This means encapsulation is broken.
Design#2 doesn't require the Product class to be coupled with the Catalog object.Hence it is a case of low coupling and encapsulation is maintained.
I advocate Design#2 following the principles of Larman and Page-Jones.
If the Catalog had Product instances in it, it should have had a method isProductAvailable(Product) or getMoreProductInformation(Product) instead of getProduct(ID).
Why would you want to search for a Product with an ID, if the Product instance is already available in the Catalog?Why would you want to give the specifics, if you can talk in more abstract sense?
The methods may be implemented in this way:

Although, such methods are acceptable in Design#1, it may means coupling of the Catalog with the Product(s).Note that this design (unlike Design#2) requires knowledge of Product in the Catalog object - A high coupling case, which means a threat to encapsulation.
We can consider the Account and Person after we have solved the issue of Catalog and Product.
Thanks,
Sandeep
[This message has been edited by Desai Sandeep (edited May 18, 2001).]

Junilu Lacar
Bartender
Posts: 7786
62
Originally posted by Caroline Iux:
I think if you look at the figure from another perspective. Look at the "end use" as a customer of a bank, the "person" in the figure as a bank officer. Then it is doing what you expect it to do. The "Person" doesn't just give the "end user" all the accounts back, and say "Here, you go figure out your balance yourself." Instead, the "Person" calculates the balance( sealed in an envelope if you like ), then give it back to the end user.

The point I am trying to make is that the responsibility of going through Accounts, checking if they are assets or not, and summing up the balances, is more appropriately assigned to the Account class, not the Person class.
A quote from the section on "Feature Envy" in the Refactoring book, Chapter 3 - "Bad Smells in Code":
A classic smell is a method that seems more interested in a class other than the one it actually is in. The most common focus of the envy is data. We've lost count of the times we've seen a method that invokes a half-dozen getting methods on another class to calculate some value.

If you were to implement totalAssets() in Person, you would have code like this:
<pre>
Amount totalAssets() {
Account aAccount;
Amount amount = new Amount(0);
Iterator iterator = new AccountList(this);
while (iterator.hasNext()) {
aAccount = (Account)iterator.next();
if (aAccount.isAssetAccount())
}

return amount;
}
</pre>
Notice that the method isn't even interested in any features of Person. It's only interested in the features of Account as exposed by the getters isAssetAccount() and getBalance(). So what would such a method be doing in Person? That's a bad code smell! It needs to have the Move Method (142) refactoring applied.

Sandeep and Caroline,
We could discuss this by way of analogy and code snippets and go on for quite a while. In order to progress, we need to take the design, implement it, and put it in the context of a more real-world situation, where things change.
To paraphrase Robert Martin again, the whole point of OO is to minimize/manage dependencies. The reason you want to manage dependencies is so that you can change things easily without a lot of ripple effects and breaking of old code.
OO is not really about encapsulation, inheritance and all the other things normally associated with OO. These are merely the strategies used to achieve more cohesive and less coupled designs. Applied improperly, these strategies will not help much in managing dependencies.
That's what it all boils down to really: high cohesion and low coupling. These are the same things that you try to achieve with modular, structured programming in languages like COBOL. OO just helps us to do that in a different, and hopefully, better way.
My contention is that the designs that you propose will have more dependencies and thus will entail more pain during the change process. I think the design I propose will be much easier to refactor.
What I would like to propose is to actually implement the original design in Java, then see how easy it would be to make changes or new requirements. Then compare that to code based on my proposed design.
This would also be an excellent opportunity to discuss issues regarding refactoring.
Junilu
[This message has been edited by JUNILU LACAR (edited May 18, 2001).]
(modified totalAssets() code)
[This message has been edited by JUNILU LACAR (edited May 18, 2001).]
(rephrased some things)
[This message has been edited by JUNILU LACAR (edited May 18, 2001).]

Junilu Lacar
Bartender
Posts: 7786
62
Sandeep,
Going back to Catalog and Product...
I am of the opinion that both designs: getProducts() and getProduct(ProductID) are not very good designs because they both break Catalog's encapsulation.
Going by my principle of role-reversal: ask yourself why a user (another class or actor) would ask Catalog for a list of Products or a Product. What would a user of Catalog need the list or Product for? Will this lead to another case of feature envy or some other bad code smell? (see my previous post) Could the code smell be avoided by asking the Catalog to something with the Product/ProductList instead?
Junilu

[This message has been edited by JUNILU LACAR (edited May 18, 2001).]

David Roberts
Ranch Hand
Posts: 142
The answer is A. Keyword, BEST description. Between the word Total and the iteration marker, your best interpretation would be that it's a sum.
------------------
David Roberts - SCJP2,MCP

Desai Sandeep
Ranch Hand
Posts: 1157
Junilu,
Could you please put some code for Account and Person case as well as for the Product and Catalog example, which suggests a better design, as per Allen's principle and refactoring.

Originally posted by Junilu Lacar:
If you were to implement totalAssets() in Person, you would have code like this:
Amount totalAssets() {
Account aAccount;
Amount amount = new Amount(0);
Iterator iterator = new AccountList(this);
while (iterator.hasNext()) {
aAccount = (Account)iterator.next();
if (aAccount.isAssetAccount())
}
return amount;
}
Notice that the method isn't even interested in any features of Person. It's only interested in the features of Account as exposed by the getters isAssetAccount() and getBalance(). So what would such a method be doing in Person?

Code snipplet would be helpful for the following.Alternatively, could you modify my code (in the above post) to suggest Allen's principle?

Originally posted by Junilu Lacar:
Going by my principle of role-reversal: ask yourself why a user (another class or actor) would ask Catalog for a list of Products or a Product. What would a user of Catalog need the list or product for? Will this lead to another case of feature envy or some other bad code smell? (see my previous post) Could the code smell be avoided by asking the Catalog to something with the Product/ProductList instead?

I would say the user may request for Product Details from the Catalog.He may want to know about the specifics before he buys the Product.
If the Product information is stored in the Catalog, it wouldn't collaborate with the Product or its helper class (IMO, this shouldn't be a case of bad code smell - it is interested in the Catalog's feature - the Vector that stores Products)
On the other hand,if the details are not available in the Catalog, it would delegate the request to the helper class, which would give the information back to the Catalog - The Catalog would pass this information to the user.This should be a case of bad code smell.
But, I still don't understand how low coupling and encapsulation is broken in both the cases.
Thanks,
Sandeep
[This message has been edited by Desai Sandeep (edited May 18, 2001).]

David Roberts
Ranch Hand
Posts: 142
I'll psuedo code the first one here.

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

David Roberts
Ranch Hand
Posts: 142
My code is actually a little flawed. it's actually anAccount.isAssetAcount() per the diagram. But who's to say an asset account might not be a specialization. I thinkt he code you guys have already written is correct.
As far as the encapsulation and coupling issue. I'm not really sure what they want. If I've learned anything about test taking, the important part of the question is "Consider the Object returned". Does the caller already know about the product class? You don't really know everything you need to know to decide whether you're increasing coupling or not. What if the caller already has a reference to a product class, then design 2 would probably be fine. If not maybe both are bad, or maybe the get/set is exactly what IBM is looking for when it states encapsulation. I really don't like the question, I would be interested in knowing the real answer and could take the pre-assessment a few more times to figure it out, but I'm not sure I'd be convinced of any answer given the lack of info they give you.
------------------
David Roberts - SCJP2,MCP

Junilu Lacar
Bartender
Posts: 7786
62
I will start another thread to show how I would refactor the totalAssets() method using the Move Method refactoring.
The problem with Catalog and Product is that we don't have a context. The point I am trying to make is that getters should be regarded with suspicion because they often lead us to write more data-centric code, the leading cause of feature envy. Sooner or later, all those getters are going to cause dependency problems.
Robert Martin has an article on his website that discusses OO Design Principles and Design Patterns. I suggest you read this and understand his views about using OO to manage dependencies.
Junilu

[This message has been edited by JUNILU LACAR (edited May 18, 2001).]

Peter den Haan
author
Ranch Hand
Posts: 3252
Originally posted by JUNILU LACAR:
The point I am trying to make is that the responsibility of going through Accounts, checking if they are assets or not, and summing up the balances, is more appropriately assigned to the Account class, not the Person class.

Junilu, I agree that the summing of Accounts sits more happily inside Accounts than inside Customer. But are you sure there are no better places? You could argue that a set of accounts - call it a Portfolio - is a new concept in its own right, with its own capabilities (calculating the total balance only being the simplest of them). The individual accounts could be considered to be mere attributes of a Portfolio in the same way that a primitive float balance is an attribute of an Account.
Generally, I completely agree that getters and setters are widely abused (in what way are setters better than getters, by the way?). Also I do not take issue against the concept of seeing a class primarily as a bundle of capabilities. I do however strongly disagree with seizing this concept as an excuse to pile large numbers of unrelated responsibilities onto a class, no matter whether these are further delegated to helper classes or not.
Take the ubiquitous printing example. You appear to argue that, if you have an object A which should be printed, implementing A.print() is preferable to println("x=" + a.getX() + " y=" + a.getY()). Probably true. But, in more sophisticated cases, what if you want a different presentation of A's internal state than a canned print() can supply? Implement another print() method? Should A really encapsulate absolutely everything you can do with an A, from persisting it to a database to producing a rendered representation for a .pdf report, or should we distinguish between what I'd like to call "intrinsic" operations, which concern things which an A can intrinsically do (accrue interest, perhaps), and "extrinsic" operations, capabilities which would diminish A's cohesion? But if other objects are responsible for such extrinsic capabilities, they need some kind of access to an A; preferably at a higher level of abstraction than getters and setters, and through a well-defined & small interface, but access nevertheless. You cannot avoid such coupling. You should not want to. You can try to keep it as loose and well-defined as possible.
To draw an analogy, I can write the book of my life and print the document if I want, but ultimately I go to the printer who knows far more about typesetting and book-printing than I do. He takes my text (without needing to understand it) and does his work. Exposing the document to the printer does add coupling, but it's a hell of a lot better than learning how to print myself. Am I someone with a "print" capability which delegates to the printer? Absolutely not. The document then? That too would be a mistake; the fact that it can be printed is really not intrinsic to the document.
Ok, flawed analogy probably, but you get the drift. Maybe I'm misinterpreting your argument anyway.
By the way, I enjoy reading these discussions (and participating occasionally) just so much - you are great, all of you.
- Peter

[This message has been edited by Peter den Haan (edited May 18, 2001).]

Junilu Lacar
Bartender
Posts: 7786
62
Peter,
You know, it's funny (in a good way) you should think that because I was going to put that same exact class name in my refactoring example: Portfolio. And you are right, an Account can be considered as a feature of a Portfolio. This becomes apparent when Move Method refactoring is applied to totalAssets() and put in Account instead of Person.
When you complete the refactoring, you realize that it actually makes a little more sense to make totalAssets() a static (class) method of Account rather than an instance method. You are still invoking the Account getters but at least the code is more cohesive than when totalAssets() was in Person.
And that's the thing about refactoring: taken separately, each refactoring seems trivial and almost inconsequential. It will take several refactorings and new or changed requirements before you will see/reap the benefits of the restructuring.
As for getters and presentation, Allen Holub's Visual-Proxy pattern is the answer.
I encourage you to go out to Allen Holub's site and read his six articles about OO User Interfaces and the Visual-Proxy pattern. They were published in JavaWorld. The pattern takes a little getting used and some trying out but once you understand it, it makes you wonder just how you never thought about it before.
The premise behind the Visual-Proxy pattern is that objects should know how to present themselves. I know it might sound very wrong and that was my first reaction too. What?! Presentation logic and business logic together?! No, that's where the "Proxy" comes in. The Proxy is appropriately tightly coupled to the business object. The business object is, for the most part, happily unaware of the Proxy. If the business object needs to be presented, a Proxy does it for you. If you need to present the business object in another way, write another Proxy to do it. Meanwhile, the business object remains unchanged and still focused on just the business rules. I was re-reading Robert Martin's article on OO Design Principles and Patterns last night and was reassured to find that the Visual-Proxy pattern actually stays true to the principles mentioned: Open-Closed Principle, Liskov Substitution Principle and the Dependency Inversion Principle, to name a few.
It does add some complexity to the code and is probably overkill for presenting little things like the value of a variable and things that do not change often. For non-trivial things that do change, however, Visual-Proxy is a lifesaver.
Like I said in another thread, I should in no way be considered a "purist". I use getters and setters myself. It's just that I have learned to treat getters with suspicion and when I apply the role-reversal questions, I often end up changing my design for the better.
I am enjoying these discussions too. It gives me a chance to test my understanding and beliefs. It's great having you guys as devil's advocates. I just hope you folks don't think I'm some whacko OO purist/extremist, or worse, somebody who just has the wrong ideas about OO.
Junilu
It isn't what you don't know that gets you into trouble. It's what you know for sure that ain't so. -Samuel Clemens

[This message has been edited by JUNILU LACAR (edited May 19, 2001).]

Junilu Lacar
Bartender
Posts: 7786
62
Check out this great JavaWorld article:
"Encapsulation is not information hiding" by Wm. Paul Rogers
Read the whole thing through though. Towards the end, the author gets rid of getters and setters. The issues that the author talks about are the things that you catch when you are suspicious of getters and setters. Again, I'm not saying do away with them, just use them wisely.
Junilu

Desai Sandeep
Ranch Hand
Posts: 1157
Hi,

Originally posted By David Roberts:
You don't really know everything you need to know to decide whether you're increasing coupling or not.

In Design#2, since Catalog is using getProduct(id), it may not have/list a Product object reference in it(Catalog).
Reason: Why will Catalog want to refer the Product with specifics like an Identifier, when it has the entire Product with it?It only goes to show that it might be collaborating with some other class to get the reference.If that is correct, it implies absence of Product knowledge in the Catalog, which means low oupling.
I am not sure on encapsulation though.Since Larman suggests low coupling and encapsulation go hand-in-hand, I believe encapsulation is not broken.
See my above post which has code snipplets.I have taken both the Designs into consideration and discussed which method would look appropriate in each case.
Do you feel, that this assumption is appropriate, given the lack of information?
If it is, I would go for C. (Caroline, this is for the Coupling question - See my forecast is coming true - This thread is going to be as long as the Coupling Thread ).
Thanks,
Sandeep
[This message has been edited by Desai Sandeep (edited May 19, 2001).]