1
Chapter 4. Patterns, the Visitor Pattern and Design
2
Patterns and the Visitor Pattern
“Somebody has already
solved your problem”
Page 331
3
What makes a great chess player?
They are not memorizing the
board and playing back a
game, they are recognizing
arrangements of pieces that
call for a specific strategy.
4
What is a Design Pattern?
It is: A pattern for how
objects and methods can be
laid out to solve a problem.
Not: A class library
Not: Standard superclasses
5
How they happened
Ever feel déjà vu when programming?
Many people do. So, they started looking
at good programs and seeing what
patterns or structures were occurring a lot.
They started to write them down and give
them a name.
Now you can avoid a big description and
just say “I used the observer pattern”.
6
Do you know what these are?
➢Inheritance
➢Polymorphism
➢Encapsulation
➢Abstraction
7
The Big 4 of Object-oriented Programming
➢Inheritance
The ability to form new classes that extend the capabilities
of existing classes
➢Polymorphism
The ability of one type to appear to be and be used as
another type
➢Encapsulation
Separating an interface from an implementation, hiding
details that may change
➢Abstraction
Reducing or factoring out details so we can focus on
concepts – objects are abstractions
8
But, More
➢Flexibility/Extendibility
It should be easy to add capability.
We should not have to always modify our core classes to
add a capability.
➢Maintainability
We like to avoid spreading code all over the project to do a
specific task.
9
Remember This? Add a menu option called "Count the
male animals". A bull is a male cow. A
boar is a male pig. Assume all chickens are
females
How did you implement this?
10
How you likely implemented this
class CAnimal
{
public:
CAnimal();
virtual ~CAnimal();
virtual void DisplayAnimal() {}
virtual bool IsMale() const {return false;}
};
bool CPig::IsMale() const
{
return mType == Boar;
}
bool CCow::IsMale() const
{
return mType == Bull;
}
int CFarm::NumberOfMaleAnimals() const
{
int cnt = 0;
for(list<CAnimal *>::const_iterator i=mInventory.begin();
i != mInventory.end(); i++)
{
CAnimal *animal = *i;
if(animal->IsMale())
cnt++;
}
} What’s bad about this approach?
4
11
What if I want to...
➢Determine how many chickens we have?
➢Total the milk production per day?
➢Determine how many animals have not been vaccinated?
➢Lots of other questions I might decide I want to ask later on.
12
How we have been doing it
virtual bool IsChicken() const {return false;}
virtual bool IsVaccinated() const = 0;
virtual double GetMilkProduction() const {return 0;}
virtual bool GetSomeOtherStupidThing() const=0;
virtual bool GetSomeGettingTiredOfThisNonsense() const=0;
virtual bool GettingReallyAnnoying() const=0;
Every time I want to ask a new question, I have to modify
all of the classes that store my data.
Bad for flexibly/extendibility
Code to answer a question in
many, many places.
13
The basic idea
Objects are things. Think of them like they are real
people or real cows and pigs. We want to ask our
farmer how many male animals he has.
14
The problem is...
Our farmer only knows he has animals, not what
type of animal they are.
15
The problem is... We had to create a way for our animals to tell
the farmer if they are male through the box.
I’m
Male I’m
Male Me Too
I’m not
sure
16
The problem is...
If we need more answers, we may end up having
to add more things that our box can tell us about
the animal.
I’m
Male I’m
Male Me Too
I’m not
sure
I’m
Brown
3 gallons
per day
VaccinatedPregnant
17
What do we know?
We can create virtual functions that are passed by the animal
box to the actual cow or pig.
We can create one for each question we need to ask.
But, can we create a more general-purpose message to pass
to our animals?
18
Suppose our farmer had a special employee called
a Visitor
19
She has the ability to look into the box and have
the actual animal talk to her.
I’m a
Cow
20
How we will implement this idea
21
The Process
Construct an object of type CountMalesVisitor
It is derived from AnimalVisitor
22
Now...
Call Accept on Farm with our
CountMalesVisitor object
23
The Process
For each animal, call Accept
Accept
Me
Accept
24
The Process
The Cow calls VisitCow
I’m a
Cow
VisitCow
25
The Process
Our Visitor now knows this is a Cow. She can ask
Cow questions, now.
I’m a Bull,
don’t you see
the horns?
What
type are
you?
26
Then we can deal
with the information
Bulls are boys,
so add one to
my count
27
And now the code
class CCow;
class CPig;
class CChicken;
class CAnimalVisitor
{
public:
CAnimalVisitor();
virtual ~CAnimalVisitor();
virtual void VisitCow(CCow *cow) {}
virtual void VisitPig(CPig *pig) {}
virtual void VisitChicken(CChicken *chicken) {}
};
Note the forward references!
28
CCountMalesVisitor
#include "CAnimalVisitor.h"
class CCountMalesVisitor: public CAnimalVisitor
{
public:
CCountMalesVisitor() {mCnt = 0;}
virtual ~CCountMalesVisitor();
virtual void VisitCow(CCow *cow);
virtual void VisitPig(CPig *pig);
int GetCount() const {return mCnt;}
private:
int mCnt;
};
void CCountMalesVisitor::VisitCow(CCow *cow)
{
if(cow->GetType() == CCow::Bull)
mCnt++;
}
void CCountMalesVisitor::VisitPig(CPig *pig)
{
if(pig->GetType() == CPig::Boar)
mCnt++;
}
Our visitor is holding a pad and is marking slash
marks for each male cow.
29
How this works
void CCountMalesVisitor::VisitCow(CCow *cow)
{
if(cow->GetType() == CCow::Bull)
mCnt++;
}
void CCountMalesVisitor::VisitPig(CPig *pig)
{
if(pig->GetType() == CPig::Boar)
mCnt++;
}
As each animal calls a visit function on the visitor, it checks to
see if male and, if so, increments a counter.
30
CAnimal::Accept
#include "CAnimalVisitor.h"
class CAnimal
{
public:
CAnimal();
virtual ~CAnimal();
virtual void DisplayAnimal() {}
virtual void Accept(CAnimalVisitor *) = 0;
};
31
CCow::Accept
#include "CAnimalVisitor.h"
class CCow : public CAnimal
{
public:
CCow();
virtual ~CCow();
// The types of cow we can have on our farm
enum Type {Bull, BeefCow, MilkCow};
virtual void Accept(CAnimalVisitor *visitor) {visitor->VisitCow(this);}
//...
};
32
CChicken::Accept
#include "CAnimalVisitor.h"
class CChicken : public CAnimal
{
public:
CChicken();
virtual ~CChicken();
void Accept(CAnimalVisitor *visitor) {visitor->VisitChicken(this);}
void DisplayAnimal();
//...
};
33
CFarm::Accept
void CFarm::Accept(CAnimalVisitor *visitor)
{
for(list<CAnimal *>::iterator i=mInventory.begin(); i != mInventory.end(); i++)
{
CAnimal *animal = *i;
animal->Accept(visitor);
}
}
34
Applying This
void CountMaleAnimals(CFarm &farm)
{
// Create the visitor object
CCountMalesVisitors visitor;
// Send it to the farm
farm.Accept(&visitor);
// Get the result
cout << "Number of male animals is " << visitor.GetCount() << endl;
}
35
This is called the Visitor Pattern
➢ We create an object of a type derived
from our visitor class
▪This is called a concrete visitor
➢ We call Accept on the class that has the collection (Farm)
➢ It calls Accept on every object in the collection
➢ Each Accept then calls a Visit function on the visitor
➢ The visitor can now do its work, knowing the type of the object
36
A Concrete Example
1. We create a visitor object.
2. We call farm.Accept(visitor).
3. farm.Accept(visitor) calls Accept on a cow
4. The cow calls visitor.VisitCow(this), passing a pointer to itself.
5. The visitor calls cow->GetType() to determine the type.
6. If the type is a Bull, the count is incremented.
7. farm.Accept(visitor) calls Accept on a chicken
8. The chicken calls visitor.VisitChicken(this), passing a pointer to itself.
9. The visitor did not override this function; the base class version does
nothing.
10.Repeat process for next cow
11.Repeat process for next pig
37
Suppose I want to know total milk production?
class CMilkProductionVisitor: public CAnimalVisitor
{
public:
CMilkProductionVisitor() {mTotalProduction = 0;}
virtual ~CMilkProductionVisitor();
virtual void VisitCow(CCow *cow);
private:
double mTotalProduction;
};
void CMilkProductionVisitor::VisitCow(CCow *cow)
{
mTotalProduction += cow->GetMilkProduction();
}
Could we have done the drawing with a visitor?
6
38
Process to create support for the visitor pattern
1. Create a visitor class with Visit functions for every type of object we may
visit.
2. In a superclass for every type of object we may visit, add an Accept
function.
3. In every derived class, provide an Accept function that calls the
appropriate Visit function.
4. In any class with a collection, create a loop over the collection, calling
accept on each object.
39
Advantages/Disadvantages of Visitors
Advantages
You can add new capability without changing the way the data is stored.
All of the functions for an operation end up in one place.
Disadvantages
Seems like a lot of code to support.
You’re always calling Accept – meaning is in the object, not the function call.
Have to add new Visit function when you add a new type.
Visitor pattern has its detractors, BTW
40
In the gang-of-four book
41
Another example use
OpenInventor
➢Rendering a scene
➢Mapping a mouse click (picking)
➢Searching
➢Input/output
➢Determining bounding boxes
42
Use the visitor pattern when...
➢An object structure contains many classes of objects with different
interfaces, and you want to perform operations on these objects
that depend on their concrete classes.
➢Many distinct and unrelated operations need to be performed on
objects in an object structure, and you want to avoid "polluting"
their classes with these operations. Visitor lets you keep related
operations together by defining them in one class.
➢The classes defining the object structure rarely change, but you
often want to define new operations over the structure.
43
Variations on the Theme
class CAnimalVisitor
{
public:
CAnimalVisitor();
virtual ~CAnimalVisitor();
virtual void VisitCow(CCow *cow) = 0;
virtual void VisitPig(CPig *pig) = 0;
virtual void VisitChicken(CChicken *chicken) = 0;
};
Pure Virtual Functions
44
Variations on the Theme
class CAnimalVisitor
{
public:
CAnimalVisitor();
virtual ~CAnimalVisitor();
virtual void VisitDefault(CAnimal *animal) {}
virtual void VisitCow(CCow *cow);
virtual void VisitPig(CPig *pig);
virtual void VisitChicken(CChicken *chicken);
};
void CAnimalVisitor::VisitCow(CCow *cow)
{
VisitDefault(cow);
}
Providing a default visit function
45
What about this case?
What might we want to do?
46
Design
See
ViewEdit
Frame
wxScrolledWindow
Document
Actor
Drawable
Draws document in window
Manages scrolling/scrollbars
Selects for moving/rotating
Move user interface
Rotate user interface
CRC Cards
UML
Scenarios
47
CRC Cards
See
http://c2.com/doc/oopsla89/paper.html
ViewEdit
Frame
wxScrolledWindow
Class-Responsibility-Collaborator Cards
Document
Actor
Drawable
Draws document in window
Manages scrolling/scrollbars
Selects for moving/rotating
Move user interface
Rotate user interface
Responsibilities
Class
Collaborators
http://www.extremeprogramming.org/rules/crccards.html
: Window
Inherits
From
48
Basic CRC ideas
➢Cards can be classes or objects of the class.
• Hold an object/set a class is common
➢Feel free to make extra cards for extra objects.
➢Feel free to discard cards and replace or start over.
➢Busy cards near center of table.
• Don’t place just in an empty spot.
➢Placement helps describe collaborations
• Overlap means close control
• Adjacent implies communications
• Groupings are important
➢Run simulations often
49
Design Example
You are asked to design a personal finance program. A person
can have multiple bank accounts. The common transactions
are deposits, withdrawals, and transfers. Every transaction
can be (optionally) assigned to a budget category such as
shopping or tax refund. Some transactions are split between
more than one budget category ($52 in groceries and $22 in
gas for example). Design a set of classes for this program.
See
Bank
Account
Customer
Bank name and information
Class
Responsibilities
Collaborations
50
Your company manages magazine subscriptions. You have
customers who have a name, address, and phone number.
They subscribe to magazines, each with a name. To subscribe,
you make a payment on a certain date and for a certain
amount. Each subscription needs to keep track of the
payments and when the subscription expires.
51
A Scenario for our Personal Finance SystemOne transaction to illustrate the case of a transfer on 2-12-10 from checking
account number 123485 to savings account number 123402 of $1000 split
between these budget categories: $750 to Rainy Day and $250 to Cancun.
The bank name for both accounts is BankMSU.
Scenario – A description on some use of our system we use as
an example.
52
A CRC Example
Design a way to represent the dining philosophers problem. We have
philosophers around a circular table. Each philosopher has access to 2 forks,
one on either side of them. Each fork is shared by two philosophers. A fork
can be either on the table or in use by one philosopher. A philosopher must
have 2 forks to eat. Your system should be able to represent all possible
configurations and answer the question “can I eat?” for every philosopher.
53
You are creating an email program. An email message has a date, time,
from address, to addresses, CC addresses, a subject, the text for the email
message, and a list of attachments, each of which has a size, a name, and
raw data for the attachment (an array of bytes). Addresses have an email
address and an optional name (if the system knows it). Email goes into
folders, which are in a hierarchical structure under an email account.
54
A library has books. Each book is either on the shelf in the library, checked
out by an individual, or missing. Customers have a name and address. We
maintain the history of every book including when it was checked out and
when it was returned and who the customer was. We maintain the history
for every customer as well.
55
You are asked to design a system to control an oil drilling platform and
associated equipment. The platform has over 100 motorized valves. Each
valve has a name, description, location, a sensor that tells how open it is (0
to 100%) and a motor to close or open the valve. There is also a specified
opening amount your program will tell the valve to set to. For example, if
valve BX37 is closed and the specified opening amount of set to 40%, the
motor will turn on and open until the sensor says the valve is 40% open.
The system also has over 200 fire detectors, each with a name, description,
location, and a status (inactive, active, fire). The location of equipment on
the platform consists of a level (what floor), section, and subsection (all
strings, for example level B3, section X24, subsection M). Your system has
named configurations. A configuration is a set of positions for all of the
valves (it is loaded from a file).
56
I’m working with an piece of equipment called a Biopac. It has
channels that can read things like skin resistance and muscle
activations. For each channel it reads 1000 samples (double)
per second. I want a program where I can have input channels
read from the Biopac, filters that can clean up data, and
windows on the screen to display the data. Note that data may
be displayed in more than one way. Design the classes for this
software for me.
57
END OF CHAPTER

Chapter 4

  • 1.
    1 Chapter 4. Patterns,the Visitor Pattern and Design
  • 2.
    2 Patterns and theVisitor Pattern “Somebody has already solved your problem” Page 331
  • 3.
    3 What makes agreat chess player? They are not memorizing the board and playing back a game, they are recognizing arrangements of pieces that call for a specific strategy.
  • 4.
    4 What is aDesign Pattern? It is: A pattern for how objects and methods can be laid out to solve a problem. Not: A class library Not: Standard superclasses
  • 5.
    5 How they happened Everfeel déjà vu when programming? Many people do. So, they started looking at good programs and seeing what patterns or structures were occurring a lot. They started to write them down and give them a name. Now you can avoid a big description and just say “I used the observer pattern”.
  • 6.
    6 Do you knowwhat these are? ➢Inheritance ➢Polymorphism ➢Encapsulation ➢Abstraction
  • 7.
    7 The Big 4of Object-oriented Programming ➢Inheritance The ability to form new classes that extend the capabilities of existing classes ➢Polymorphism The ability of one type to appear to be and be used as another type ➢Encapsulation Separating an interface from an implementation, hiding details that may change ➢Abstraction Reducing or factoring out details so we can focus on concepts – objects are abstractions
  • 8.
    8 But, More ➢Flexibility/Extendibility It shouldbe easy to add capability. We should not have to always modify our core classes to add a capability. ➢Maintainability We like to avoid spreading code all over the project to do a specific task.
  • 9.
    9 Remember This? Adda menu option called "Count the male animals". A bull is a male cow. A boar is a male pig. Assume all chickens are females How did you implement this?
  • 10.
    10 How you likelyimplemented this class CAnimal { public: CAnimal(); virtual ~CAnimal(); virtual void DisplayAnimal() {} virtual bool IsMale() const {return false;} }; bool CPig::IsMale() const { return mType == Boar; } bool CCow::IsMale() const { return mType == Bull; } int CFarm::NumberOfMaleAnimals() const { int cnt = 0; for(list<CAnimal *>::const_iterator i=mInventory.begin(); i != mInventory.end(); i++) { CAnimal *animal = *i; if(animal->IsMale()) cnt++; } } What’s bad about this approach? 4
  • 11.
    11 What if Iwant to... ➢Determine how many chickens we have? ➢Total the milk production per day? ➢Determine how many animals have not been vaccinated? ➢Lots of other questions I might decide I want to ask later on.
  • 12.
    12 How we havebeen doing it virtual bool IsChicken() const {return false;} virtual bool IsVaccinated() const = 0; virtual double GetMilkProduction() const {return 0;} virtual bool GetSomeOtherStupidThing() const=0; virtual bool GetSomeGettingTiredOfThisNonsense() const=0; virtual bool GettingReallyAnnoying() const=0; Every time I want to ask a new question, I have to modify all of the classes that store my data. Bad for flexibly/extendibility Code to answer a question in many, many places.
  • 13.
    13 The basic idea Objectsare things. Think of them like they are real people or real cows and pigs. We want to ask our farmer how many male animals he has.
  • 14.
    14 The problem is... Ourfarmer only knows he has animals, not what type of animal they are.
  • 15.
    15 The problem is...We had to create a way for our animals to tell the farmer if they are male through the box. I’m Male I’m Male Me Too I’m not sure
  • 16.
    16 The problem is... Ifwe need more answers, we may end up having to add more things that our box can tell us about the animal. I’m Male I’m Male Me Too I’m not sure I’m Brown 3 gallons per day VaccinatedPregnant
  • 17.
    17 What do weknow? We can create virtual functions that are passed by the animal box to the actual cow or pig. We can create one for each question we need to ask. But, can we create a more general-purpose message to pass to our animals?
  • 18.
    18 Suppose our farmerhad a special employee called a Visitor
  • 19.
    19 She has theability to look into the box and have the actual animal talk to her. I’m a Cow
  • 20.
    20 How we willimplement this idea
  • 21.
    21 The Process Construct anobject of type CountMalesVisitor It is derived from AnimalVisitor
  • 22.
    22 Now... Call Accept onFarm with our CountMalesVisitor object
  • 23.
    23 The Process For eachanimal, call Accept Accept Me Accept
  • 24.
    24 The Process The Cowcalls VisitCow I’m a Cow VisitCow
  • 25.
    25 The Process Our Visitornow knows this is a Cow. She can ask Cow questions, now. I’m a Bull, don’t you see the horns? What type are you?
  • 26.
    26 Then we candeal with the information Bulls are boys, so add one to my count
  • 27.
    27 And now thecode class CCow; class CPig; class CChicken; class CAnimalVisitor { public: CAnimalVisitor(); virtual ~CAnimalVisitor(); virtual void VisitCow(CCow *cow) {} virtual void VisitPig(CPig *pig) {} virtual void VisitChicken(CChicken *chicken) {} }; Note the forward references!
  • 28.
    28 CCountMalesVisitor #include "CAnimalVisitor.h" class CCountMalesVisitor:public CAnimalVisitor { public: CCountMalesVisitor() {mCnt = 0;} virtual ~CCountMalesVisitor(); virtual void VisitCow(CCow *cow); virtual void VisitPig(CPig *pig); int GetCount() const {return mCnt;} private: int mCnt; }; void CCountMalesVisitor::VisitCow(CCow *cow) { if(cow->GetType() == CCow::Bull) mCnt++; } void CCountMalesVisitor::VisitPig(CPig *pig) { if(pig->GetType() == CPig::Boar) mCnt++; } Our visitor is holding a pad and is marking slash marks for each male cow.
  • 29.
    29 How this works voidCCountMalesVisitor::VisitCow(CCow *cow) { if(cow->GetType() == CCow::Bull) mCnt++; } void CCountMalesVisitor::VisitPig(CPig *pig) { if(pig->GetType() == CPig::Boar) mCnt++; } As each animal calls a visit function on the visitor, it checks to see if male and, if so, increments a counter.
  • 30.
    30 CAnimal::Accept #include "CAnimalVisitor.h" class CAnimal { public: CAnimal(); virtual~CAnimal(); virtual void DisplayAnimal() {} virtual void Accept(CAnimalVisitor *) = 0; };
  • 31.
    31 CCow::Accept #include "CAnimalVisitor.h" class CCow: public CAnimal { public: CCow(); virtual ~CCow(); // The types of cow we can have on our farm enum Type {Bull, BeefCow, MilkCow}; virtual void Accept(CAnimalVisitor *visitor) {visitor->VisitCow(this);} //... };
  • 32.
    32 CChicken::Accept #include "CAnimalVisitor.h" class CChicken: public CAnimal { public: CChicken(); virtual ~CChicken(); void Accept(CAnimalVisitor *visitor) {visitor->VisitChicken(this);} void DisplayAnimal(); //... };
  • 33.
    33 CFarm::Accept void CFarm::Accept(CAnimalVisitor *visitor) { for(list<CAnimal*>::iterator i=mInventory.begin(); i != mInventory.end(); i++) { CAnimal *animal = *i; animal->Accept(visitor); } }
  • 34.
    34 Applying This void CountMaleAnimals(CFarm&farm) { // Create the visitor object CCountMalesVisitors visitor; // Send it to the farm farm.Accept(&visitor); // Get the result cout << "Number of male animals is " << visitor.GetCount() << endl; }
  • 35.
    35 This is calledthe Visitor Pattern ➢ We create an object of a type derived from our visitor class ▪This is called a concrete visitor ➢ We call Accept on the class that has the collection (Farm) ➢ It calls Accept on every object in the collection ➢ Each Accept then calls a Visit function on the visitor ➢ The visitor can now do its work, knowing the type of the object
  • 36.
    36 A Concrete Example 1.We create a visitor object. 2. We call farm.Accept(visitor). 3. farm.Accept(visitor) calls Accept on a cow 4. The cow calls visitor.VisitCow(this), passing a pointer to itself. 5. The visitor calls cow->GetType() to determine the type. 6. If the type is a Bull, the count is incremented. 7. farm.Accept(visitor) calls Accept on a chicken 8. The chicken calls visitor.VisitChicken(this), passing a pointer to itself. 9. The visitor did not override this function; the base class version does nothing. 10.Repeat process for next cow 11.Repeat process for next pig
  • 37.
    37 Suppose I wantto know total milk production? class CMilkProductionVisitor: public CAnimalVisitor { public: CMilkProductionVisitor() {mTotalProduction = 0;} virtual ~CMilkProductionVisitor(); virtual void VisitCow(CCow *cow); private: double mTotalProduction; }; void CMilkProductionVisitor::VisitCow(CCow *cow) { mTotalProduction += cow->GetMilkProduction(); } Could we have done the drawing with a visitor? 6
  • 38.
    38 Process to createsupport for the visitor pattern 1. Create a visitor class with Visit functions for every type of object we may visit. 2. In a superclass for every type of object we may visit, add an Accept function. 3. In every derived class, provide an Accept function that calls the appropriate Visit function. 4. In any class with a collection, create a loop over the collection, calling accept on each object.
  • 39.
    39 Advantages/Disadvantages of Visitors Advantages Youcan add new capability without changing the way the data is stored. All of the functions for an operation end up in one place. Disadvantages Seems like a lot of code to support. You’re always calling Accept – meaning is in the object, not the function call. Have to add new Visit function when you add a new type. Visitor pattern has its detractors, BTW
  • 40.
  • 41.
    41 Another example use OpenInventor ➢Renderinga scene ➢Mapping a mouse click (picking) ➢Searching ➢Input/output ➢Determining bounding boxes
  • 42.
    42 Use the visitorpattern when... ➢An object structure contains many classes of objects with different interfaces, and you want to perform operations on these objects that depend on their concrete classes. ➢Many distinct and unrelated operations need to be performed on objects in an object structure, and you want to avoid "polluting" their classes with these operations. Visitor lets you keep related operations together by defining them in one class. ➢The classes defining the object structure rarely change, but you often want to define new operations over the structure.
  • 43.
    43 Variations on theTheme class CAnimalVisitor { public: CAnimalVisitor(); virtual ~CAnimalVisitor(); virtual void VisitCow(CCow *cow) = 0; virtual void VisitPig(CPig *pig) = 0; virtual void VisitChicken(CChicken *chicken) = 0; }; Pure Virtual Functions
  • 44.
    44 Variations on theTheme class CAnimalVisitor { public: CAnimalVisitor(); virtual ~CAnimalVisitor(); virtual void VisitDefault(CAnimal *animal) {} virtual void VisitCow(CCow *cow); virtual void VisitPig(CPig *pig); virtual void VisitChicken(CChicken *chicken); }; void CAnimalVisitor::VisitCow(CCow *cow) { VisitDefault(cow); } Providing a default visit function
  • 45.
    45 What about thiscase? What might we want to do?
  • 46.
    46 Design See ViewEdit Frame wxScrolledWindow Document Actor Drawable Draws document inwindow Manages scrolling/scrollbars Selects for moving/rotating Move user interface Rotate user interface CRC Cards UML Scenarios
  • 47.
    47 CRC Cards See http://c2.com/doc/oopsla89/paper.html ViewEdit Frame wxScrolledWindow Class-Responsibility-Collaborator Cards Document Actor Drawable Drawsdocument in window Manages scrolling/scrollbars Selects for moving/rotating Move user interface Rotate user interface Responsibilities Class Collaborators http://www.extremeprogramming.org/rules/crccards.html : Window Inherits From
  • 48.
    48 Basic CRC ideas ➢Cardscan be classes or objects of the class. • Hold an object/set a class is common ➢Feel free to make extra cards for extra objects. ➢Feel free to discard cards and replace or start over. ➢Busy cards near center of table. • Don’t place just in an empty spot. ➢Placement helps describe collaborations • Overlap means close control • Adjacent implies communications • Groupings are important ➢Run simulations often
  • 49.
    49 Design Example You areasked to design a personal finance program. A person can have multiple bank accounts. The common transactions are deposits, withdrawals, and transfers. Every transaction can be (optionally) assigned to a budget category such as shopping or tax refund. Some transactions are split between more than one budget category ($52 in groceries and $22 in gas for example). Design a set of classes for this program. See Bank Account Customer Bank name and information Class Responsibilities Collaborations
  • 50.
    50 Your company managesmagazine subscriptions. You have customers who have a name, address, and phone number. They subscribe to magazines, each with a name. To subscribe, you make a payment on a certain date and for a certain amount. Each subscription needs to keep track of the payments and when the subscription expires.
  • 51.
    51 A Scenario forour Personal Finance SystemOne transaction to illustrate the case of a transfer on 2-12-10 from checking account number 123485 to savings account number 123402 of $1000 split between these budget categories: $750 to Rainy Day and $250 to Cancun. The bank name for both accounts is BankMSU. Scenario – A description on some use of our system we use as an example.
  • 52.
    52 A CRC Example Designa way to represent the dining philosophers problem. We have philosophers around a circular table. Each philosopher has access to 2 forks, one on either side of them. Each fork is shared by two philosophers. A fork can be either on the table or in use by one philosopher. A philosopher must have 2 forks to eat. Your system should be able to represent all possible configurations and answer the question “can I eat?” for every philosopher.
  • 53.
    53 You are creatingan email program. An email message has a date, time, from address, to addresses, CC addresses, a subject, the text for the email message, and a list of attachments, each of which has a size, a name, and raw data for the attachment (an array of bytes). Addresses have an email address and an optional name (if the system knows it). Email goes into folders, which are in a hierarchical structure under an email account.
  • 54.
    54 A library hasbooks. Each book is either on the shelf in the library, checked out by an individual, or missing. Customers have a name and address. We maintain the history of every book including when it was checked out and when it was returned and who the customer was. We maintain the history for every customer as well.
  • 55.
    55 You are askedto design a system to control an oil drilling platform and associated equipment. The platform has over 100 motorized valves. Each valve has a name, description, location, a sensor that tells how open it is (0 to 100%) and a motor to close or open the valve. There is also a specified opening amount your program will tell the valve to set to. For example, if valve BX37 is closed and the specified opening amount of set to 40%, the motor will turn on and open until the sensor says the valve is 40% open. The system also has over 200 fire detectors, each with a name, description, location, and a status (inactive, active, fire). The location of equipment on the platform consists of a level (what floor), section, and subsection (all strings, for example level B3, section X24, subsection M). Your system has named configurations. A configuration is a set of positions for all of the valves (it is loaded from a file).
  • 56.
    56 I’m working withan piece of equipment called a Biopac. It has channels that can read things like skin resistance and muscle activations. For each channel it reads 1000 samples (double) per second. I want a program where I can have input channels read from the Biopac, filters that can clean up data, and windows on the screen to display the data. Note that data may be displayed in more than one way. Design the classes for this software for me.
  • 57.