[Skip Navigation] [ CSUSB ] / [CNS] / [Comp Sci & Engineering] / [R J Botting] / [CS375] [Search ]
[About] [Contact] [Grades] [Objectives] [Patterns] [Projects] [Question] [Schedule] [Syllabus]
Session: [01] [02] [03] [04] [05] [06] [07] [08] [09] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20]
[Text Version] 16q.html Mon Sep 28 15:44:37 PDT 2009

Contents


    Questions 16 -- More GRASP

      Administrative Question -- credit for code

      If we were to make our project a real project and make it executable would there be anyway to get credit from it possibly? senior project? independent study?

      Not in this class. Senior Project -- many senior projects start in CS375 -- if you can find a client! Independent study -- possibly -- never happened -- and whoever acted as advisor on the project would want something from it (we do independent studies. projects, theses, etc for free). For example -- I would want to incorporate it in the materials for this class.

      When does the first iteration end

      Each iteration starts with the team deciding how long the iteration will take -- one week, 2 weeks, .... and what will be analyzed+designed+coded+designed. This is called a time-box.

      When the time is up, that is it. Whatever work that has not been done is completed in a later iteration. The wise time, learns something about how fast they can work. They use this to schedule the work for the next iteration.

      Domain

      I am still a bit unsure as to what is explicitly part of the domain. How do we discern what is part of the domain and what is not?

      If you can kick it, it is real, and so in the domain.

      If it does not go away when you destroy the computer.... it is real and so in the domain.

      If it ceases to exist when your computer is destroyed then it is inside the software and not part of the domain.

      Which is the commonest of the last 5 GRASP patterns

      I don't know. I also don't think the information is important. They are are sophisticated. They are all used. And often they are used together in the more complex "Gang of Four" patterns.

      Chapter 25 pages 415 -- Polymorphism

      Is there another method other than polymorphism to execute the UML diagram on page 415?

      No. The UML "realisation" and "Generalization" arrows imply polymorphic behavior.

      Luckily, the code is easy, even in C++. See [ fig25_25_1.cpp ] and [ test.fig25_25_1.cpp ] plus stubs [ Sale.cpp ] and [ TaxLineItems.cpp ] for example.

      Note: I had hoped to use my log to figure how long the above code took to write and test. But I uncovered a bug in the logging script:-( Even so, I seem to have started just after 7am and finished linking the code into this page before 7:15am. So it took 15 minutes to encode and test Figure 25.1 including stubs for two dependent classes.

      Once done.... I wouldn't expect to change the interface again. I would have to replace the stubs for the concrete classes... After that I can create new Tax Calculator classes any time I like. compile them separately and use them without breaking the existing code. Priceless.

      Chapter 25 pages 416-435 -- Polymorphism

      What improvements does the landedOn method provide in the Monopoly Problem? What was lacking about the method used in the pseudocode?

      Switches are hard to get right, hard to modify, and a source of future problems.

      It is nearly always beetter to write code that automagically selects the right behavior with zero programming.

       	class Player
       	{
       		Square * location;
       		...
       		virtual Something takeTurn(....) //Fig 25.3 Page 417
       		{
       			...
       			location=board->getSquare(location, fvTot);
       			location->landedOn();
       		}
       		...
       	};

      I think we need another example of polymorphic C++ code... First think back to the beginning of the class when we simulated the Dice Game. Look at pages 8 to 11 of Larman. Remember that when we did this in class we had many ways of rolling the dice. As long as they fitted the same interface the game worked.

      Now look at the code I wrote: [ DiceGame.cpp ] [ Die.cpp ] [ testDiceGame.cpp ] [ testDie.cpp ]

      Polymorphism lets you extend ANY class with new behaviors without rewriting the original.

      To demonstrate polymorphism in C++ I edited Die2 to inherit from Die [ Die2.cpp ] and tested it [ testDie2.cpp ] (of course).

      I then generated a new version of DiceGame: [ DiceGame2.cpp ] that uses both kinds of dice... and tested it [ testDiceGame2.cpp ] and (of course) it worked (after removing one stupidity).

      Notice that I only changed one line of code in the DiceGame class

       < 	DiceGame(){die1 = new Die(); die2 = new Die(); }
       > 	DiceGame(){die1 = new Die(); die2 = new Die2(); }

      We could go further and switch dice as the program runs....

      Here are my notes [ polymorphism.html ] from CSci202.

      Chapter 25 pages 433 -- Information Hiding

      In Parnas' quote, he mentions that difficult design decisions, along with design decisions that are likely to change should be hidden. Considering that, if you have just a normal design decision, do you just leave those alone?

      Interesting question..... key point -- easy decisions are not likely to change and so you don't have to hide them in a special module. So, think about the probability that you might make the wrong decision and the the ammount of rewriting involved.

      For years I have separated the part of the design that handle the hardware from the core logic of the program. It has never caused a problem. Just a little extra thought.

      Chapter 25 pages 427-434 -- Protected Variations

      The section on protected variations confused me. Can you explain it more?

      When we analyse a problem area we can often spott things that vary. The stakeholders will mention that they are about to through out their old Spangling Server and replace it with a new faster, cheaper, and smaller version. Or you discover that one part of an organization insists on using 9 digit ISBNs and the rest 13 bit ISBN. Or, on a smaller sclae, the behavior of Wodgets change as time goes one. There are times when their state lets them execute the zark procedure, and their are times when they can't. Here we have a varying state. We would like instances of Wodget to change class... something that is not part of normal object technology. Again something varies and we need a wat to handle the variation. And so it goes on.

      When you have variations like this -- it wise to take a little time and ingenuity to find a way of containing the damage. Finding a way to stop the variation infecting the whole system. For example with every function testing to see which kind of ISBN is needed. Or which Spangling Server we have running... This is known as Protected Variation.

      It is one of the oldest design principles in the business.

      We had an example at the beginning of this class when I brought in a dozen ways of simulating a throw of the dice. Each group figured out a way of faking the behavior, even tho' some of them only hard dominoes of playing cards, not dice. We often need the same solution in real life problem areas.

      Protected Variation in Design

      The original way of hiding variations was to hide them behind a collection of functions.

      So, for example you would have half-a-dozen subprograms for controlling a plotter. These would be used in exactly the same way when the old Calcom Drum plotter was replaced by a new Wang flat bed plotter. You might even design a whole language for driving graphic devices which carefully disguised the different gadgets. Been here, done this.

      These days you think in terms of creating a class -- which contains a list of function, of course, that do the same thing. Only here we attach the function to objects, and can use inheritance and polymorphism to place difference behind a wall which presents a common interface.

      To summarize: PV implies the use of interfaces and abstraction in design. Often you can Indirection and Polymorphism.

      Chapter 25 pages 428 -- PV

      What is meant by the statement that an Operating System is an example of indirection to achieve PV?

      It means that because we have an operating system you don't have to worry about most of the administartive and physical details of the hardware. Example -- when was the last time you thouhgt about what that folder on your desktop actually is -- what the data structure is? When programming, do you worry about the hundreds of other processes running on your computer? Do you actually know what happens when you execute

       		stream.fopen("foobar.dat",ios::in);
      and does it matter?

      These are some of the many design decisions and physical VARIATIONS that the OS PROTECTS you from.

      Chapter 25.2 pages 421 -- Pure Fab

      Could you give a more detailed explanation on when or where a pure fabrication would be used?

      Breifly, when you can solve a problem (high coupling, low cohesion, variations, ...) by inventing a class of objects.

      More below...

      Chapter 25 pages 422-423 -- Pure fabrication

      As applications are pluggable, can Pure Fabrication Patterns be used as a strategy to introduce objects in the domain model at any layer in the design?

      Yes -- Protected Variation include pluggable components -- a component hides different implementations behind a common (standard?) interface.

      No. Pure Fabrication is defined as adding classes to the design that do not appear in the domain. They are classes invented to make the code better, not to reflect the real world, or to interface with the user interface.

      If, however you invent a class and you discover that it was in the domain already -- this is a "Duh" moment -- then you (1) slap your face, (2) add it to the domain model and (3) use Information Expert instead. Note: slapping your face is an important step because it discourages you from being lazy when domain modelling:-)

      Chapter 25 pages 424 -- decomposition

      can you explain behavioral decomposition

      See [ 15q.html#behaviorial decomposition ] (last class)

      Behaviorial decomposition and coupling

      Can you explain how using behavioral decompostion can affect coupling?

      Normally adding a class because it can hold a particular behavior (not to reflect the real world) can lower coupling. However, if it attracts behaviors that need data or operations that are in other classes then it becomes coupled to them and this raises the overall coupling.

      When you refactor the code you notice that the fabriactes class is always calling another class to get is work done.... perhaps it is time to remove the middle man? Or does it satisfy some other need such as Protected Variation?

      Chapter 25 pages 425 -- Pure Fabrication

      Pure fabrication seems to address a specific need and is used as a last resort. How would pure fabrication be overused if it was created for a specific need?

      PV is overused in several ways. (1) People try to handle variations that never actually happen. The counter to this is to say YAGNI -- You ain't Gonna Need It. (2) People use PV as an excuse for adding unreal ideas into the domian model. This muddles up things that are needed for technical reasons with ideas that the stakeholders are paying for.

      Chapter 26 pages 436-440 -- Factory and Adapter

      Are simple and concrete factory used like GoF adapter pattern?

      No. Factories are used to create objects. An alternative to Larman's Creator GRASP pattern.

      Adapters are organizational or structural patterns that hide variations behind a common pure fabrication. They are used in a different way.

      The only thing they have in common is that they are part of the design not that is not found in the real world. The solve technical problems not model domain issues.

      2008

      Chapter 25 pp 25.4 -- GRASP methods

      Has there been situations where one can use all the GRASP patterns with in interaction diagram? If so, is it recommended?

      I'm sure it will happen -- if the diagram is complex enough.

      The number you use is irrelevant -- what matters is if you come up with a maintainable working design.

      Chapter 25 pp 413 -- GRASP

      Out of the last four GRASP patterns Polymorphism, Indirection, Pure Fabrication, and Protected Variations which would you say is the most important or the one we should worry more about?

      All of them... equally. And they also have a habit of fitting together. These are the sophisticated tools of an OO designer's trade.

      In my experience, however, C++ students have more trouble figuring out one pattern more than any other....

      Chapter 25 pp 414 -- Polymorphism

      Can I understand the solution for Polymorphism is to create a controller to handle the alternatives?

      Not just a GRASP controller. Polymorphism is an invisible hand that helps the program execute the right code when a message is passed.

      Chapter 25 pp 414-421 -- GRASP: More Objects With Responsibilities -- Got

      Polymorphism When is polymorphism not needed?

      Small programs. Simple projects. No modifications. No class hierarchies.

      In other words -- programming in the 1960s.

      Chapter 25 pp 414-420 -- Polymorphism

      Should we write code first to locate our polymorphism cases or is it done in the OO/D phase?

      No. You should incorporate polymorphism in your designs before you discover it in code... it is part of the UML.

      Chapter 25 pp 413-135 -- Polymorphism

      How effective are polymorphic operations while replacing components in a client-server relationship?

      It should work OK. Especially if the client-server use the CORBA protocols that allow polymorphic message passing between remote objects.

      Similarly, I'm sure that Java Remote Messaging (or whatever they call it) is polymorphic.

      Not so sure about RPCs -- they predate objects.

      Chapter 25 pp 426 -- Indirection.

      "By adding a level of indirection and adding polymorphism, the adapter objects protect the inner design against variations in the external interfaces." I'm not clear on how exactly that is being done. It seems to me that a change to the TaxMasterSystem's interface would necessitate a change in the TaxMasterAdapter. If that adapter wasn't there, you'd just have to change code in whatever class (probably Sale) was responsible for tracking the taxes, wouldn't you? Could you go over this?

      The idea is to have fixed interfaces and variable internals. Your design should specify a fixed point behind which variation can occur.

      So you shouldn't change the Interface as much as add in new variation behind the indirect object.

      Question: do you change the way you drive when you get a new battery?

      Chapter 25 pp 427-433 -- Protected variation and Polymorphism

      Protected Variation and Polymorphism seem related. What is the difference between the two? Where would you apply one pattern over the other?

      Polymorphism is a powerful technology that is very useful for handling Protected Variation. Protected Variation gives one reason "why" for a particular use of Polymorphism.

      Chapter 25 pp 421 -- Pure Fabrication

      When (as the book states) is a solution by Expert not appropriate, thus causing me to use a Pure Fabrication pattern?

      You use it when expert, creator, controller, ... and all the others are not appropriate.

      Expert fails when there is no class in your design or in the domain model that has the data, or doesn't know where to find it. Sometimes it fails because you end up with bad coupling between experts. Sometimes you have two many partial experts. You have to use your brain.

      Chapter 20 pp 413-425 -- Pure Fabrication

      Would pure fabrication be a class that you create that has nothing to do with your original design except for the fact that it has code that is used several times throughout. Ex So instead of writing code several times for say adding two numbers, I could make an add class that would do the work and I would just pass the numbers?

      Yes. But you might also invent a class (with no inspiration from the domain) to reduce coupling or because it looks cohesive. It is not just a matter of needing the functionality more than once. It can be for other reasons.

      Chapter 25 pp 413-435 -- Pure Fabrication

      Why is Pure Fabrication even an option? Is it just named as a last resort or is it really used that often?

      Because there are some occasions when nothing else works.... for example you just didn't notice an important idea in the domain. Then the design process tells you that you missed something.... you Fabricate it and then discover that it was there all along!

      But sometimes the best way to make software easy to change is to add a class that acts as a hinge and separates one part from another by a flexible coupling... As an example, in the "Apollo 13" movie they have to connect a round hose to a square hole -- and use the cardboard cover of a manual to do it. This is very like fabricating a new object to make the system work with no reference to worls outside the system.

      Warning -- do not over do Pure Fabrication

      Chapter 25 pp 424-425 -- Decompositions

      Can you explain in better detail of what a representational decomposition and a behavioral decomposition is?

      Designing software is all about breaking the software into pieces that make some kind of sense. We call this process "decomposition". Then the different parts can be "composed" to make the software work. In OO projects we decompose the solution into classes. But where do these classes come from?

      When you create a class of objects -- why do you do it? Do you do it because the client is always talking about something like that? If so Larman would say you have a "representational decomposition". Do you discover it during design or coding -- and it makes the program more maintainable but has no meaning to your client? If so Larman would call this a "behavioral decomposition".

      For example, in my Login handout the "Finder" class is the result of behavioral decomposition, but using "Person" is from a representational one.

      Chapter 25 pp 413-435 -- Adapter/Bridge

      Can you provide examples(actual code if possible) of an adapter and bridge design pattern.

      For some reason everybody uses the stack as an example...

      Adapter: [ wiki?AdapterPattern ] (A stack in Java).

      Bridge -- the C++ STL stack and queue are bridges or wrappers for other STL classes. Here is an abbreviated version of the definition of a stack:

       class stack {
        ... //declares c as a suitable container
             bool      empty() const             { return c.empty(); }
             size_type size()  const             { return c.size(); }
             value_type&       top()             { return c.back(); }
             const value_type& top() const       { return c.back(); }
             void push(const value_type& x)      { c.push_back(x); }
             void pop()                          { c.pop_back(); }
           };

      Chapter 25 pp 425-427 -- Indirection

      My question is on Indirection, seems like a simple enough example in the book but is there any other examples that might be worth while in knowing?

      I'm sure there are.... does any body in the class have an example?

      Chapter 25 pp 426 -- De-couple

      Can you give an example on how to de-couple objects?

      See previous.

      I have a simple example of an object that decouples my code from some C++ library functions.

      Suppose I don't like the way we get random number is C++ then I can create a class of Random objects with this interface

       class Random
       { public:
       	Random(double lowest=0, double highest=1);
       	virtual double next();
         ...
       };
      I could test it like this
       	Random r(0,1);
       	for(...) cout << r.next() << endl;
      and implement it by including
         private:
       	double low, range;
      in the above class and then writing:
       Random::Random(double lowest=0, double highest=1)
       {
       	low = lowest;
       	range = highest - lowest;
       	srand(time(NULL));
       }
       double Random::next()
       {
       		return low+(range*rand())/RAND_MAX;
       }

      Chapter 25 pp 433 -- Information Hiding

      The book briefly covers information hiding. Give examples of information hiding and how it relates to protected variations?

      Parnas formulated Information Hiding in the 1970's. In his example he split a program into 3 modules: one handled the input device (a card punch), one handled the logic of problem, and one handling the output device ( a line printer). So when the user wanted to change the program to use magnetic tape... the input and output parts changed but not the middle. When the user got a disk drive the same thing happened. And so on.

      Our division of UI + Domain Layer + Services is inspired by this.

      Chapter 25 pp 433 -- Information Hiding

      Information hiding is good because it doesn't allow users to alter data.

      The clever idea is that you can know how to use a class without having to know how it works. Like your watch. So not only is the data hidden but so can the code!

      Parnas had a strong version of Information Hiding. If a programmer was using a data type (think class) then all you would be told about where the operations that you could do to it. All other code would be hidden from you. In C++ this tends to mean that you are given a header (Widget.h) file and a compiled (Widget.o) file but not the source code (Widget.cpp) of the whole file. Now this does share some information about the data in the Widget objects -- but this is inevitable given the way C++ works.

      Brookes argued that all code should be available for every body to read an modify. But later he stated he had rethought this to match Parnas.

      The XP people (as always) have their own extreme position: all code is open to the team: to read and to write at any time.... but you instantly test all changes.

      Chapter 25 pp 413-435 -- Open-Closed Principle

      I got confused when reading about the Open-Closed Principle. Could you please go over it.

      See next...

      Chapter 25.4 pp 434 -- OCP

      An example of an Open-Closed Principle is... X can be opened to Y and always Z. And it's only open to Y if it Y needs to access something and has permission to. While Z can always access it because it has permission to. That look right?

      I'd express it like this: if X uses Y in some way or other you don't want changes to Y to effect X, but you also want to be able to change Y in ways that don't change X.

      Chapter 26 pp 459-461 -- considering grasp and other principles in the

      design Should we avoid extracting child objects out of parent, and then passing around the child objects?

      Sounds like the law of Demeter to me.

      Previous

      Should we consider exceptions and errors in all projects

      Sadly, yes.

      An empirical law: the exceptional case is often as important as the normal one. (From a hospital project).

      Code smells and stenches -- in real working environments

      Do real companies talk about code smells?

      Depends how "hip" they are. The term "code smell" is a recent invention of the eXtreme Programming people.... but it has caught on in many forward looking workplaces. "Stench" is not as common and more of a joke or insult.

      Note. The more traditional, set-in-their-ways places may not have "got" this idea yet. But it usually catches on pretty fast when introduced.

      What are the best strategies used to apply polymorphism

      If you've got it in you implementation language -- use it.

      In design -- follow GRASP.

      How exactly does test-driven development work

      You write tests, you write code, you test the code and fix it until all tests are OK. Then stop.

      How well does that work? Very well -- if you choose your tests well.

      Hint: if you don't have a TDD environment like JUnit get into the habit of starting with a main program that defines a test of the classes you are about to write. For example, in C++ use main and cassert...

      I might start with this

       #include <iostream>
       #include <cassert>
       int main(int argc, char* argv[])
       {// test prime number function
       	assert( prime(2) );
       	assert( prime(3) );
       	assert( not prime(4) );
       	assert( prime(5) );
       	assert( not prime(9) );
       	assert( not prime(42));
       }//end main
      and the work on it (if time I'd do this in class) giving the following series of (failing) attempts: [ tp.cpp ] [ tp1.cpp ] [ tp2.cpp ]

      How does the implementation model differ from the use case model

      Use case models (requirements) define the problems, the Implementation models describe solutions -- in detail.

    . . . . . . . . . ( end of section Questions 16 -- More GRASP) <<Contents | End>>

    Standard Definitions

  1. CS202::= See http://cse.csusb.edu/dick/cs202/.
  2. CS372::= See http://cse.csusb.edu/dick/cs372/.

  3. DCD::diagram="Design Class Diagram", shows the classes that will be implemented in code.
  4. DRY::XP="Don't Repeat Yourself".

  5. ESSUP::Process= See http://www.ivarjacobson.com/essup.cfm, Ivar Jacobsen simplified "Essential" UP.

  6. Glossary::= See http://cse.csusb.edu/dick/cs375/uml.glossary.html.
  7. GoF::="Gang of Four", [ patterns.html#GoF ]
  8. GRASP::patterns="General Responsibility Assignment Software Patterns", a set of guidelines for designing objects and classes. They take a single event that the system must handle and determine a good class to carry it out. See [ patterns.html#GRASP -- General Responsibility Assignment Software Patterns ]
  9. Grades::= See http://cse.csusb.edu/dick/cs375/grading/.

  10. KISS::Folk_law="Keep It Simple, Stupid", in agile processes this means never drawing a diagram or preparing a document that doesn't provide value to the clients and stakeholders. In all processes it means never designing or coding what is not needed, see YAGNI.

  11. OO::shorthand="Object-Oriented".

  12. OOAD::="Object-Oriented Analysis and Design", See chapter 1 in text.
  13. patterns::="Documented families of problems and matching solutions", see Patterns.
  14. Patterns::= See http://cse.csusb.edu/dick/cs375/patterns.html.

  15. Process::="How to develop software".

  16. RJB::=The author of this document, RJB="Richard J Botting, Comp Sci Dept, CSUSB".
  17. RUP::Process="Rational UP", a proprietary version of UP.

  18. SSD::="System Sequence Diagrams", see chapter 10.

  19. TBA::="To Be Announced".

  20. UML::="Unified Modeling Language". [ Unified_Modeling_Language ]

  21. UP::="Unified Process", an iterative, risk-driven, and evolutionary way to develop OO software.

  22. YAGNI::XP="You Ain't Gonna Need It", an XP slogan that stops you planning and coding for things that are not yet needed. As a rule the future is not predictable enough to program a feature until the stakeholders actually need it now. In this class it means "It won't be on the final or in quizzes".

  23. XP::="Extreme Programming", the ultimate iterative code-centric, user-involved process.

End