Download presentation
Presentation is loading. Please wait.
1
Refactoring and Reuse (Chapter 12)
2
The System As It Stands ProblemSolverQueue ActionListActionItemPriorityQueueFrontQueue RearQueue State MaxPriorityQueueMinPriorityQueue Note: the ``Info'' suffix is assumed for all class names
3
A New Problem A farmer and his wolf, goat, and cabbage come to the edge of a river they wish to cross. There is a boat at the river's edge that only the farmer can row. The farmer can take at most one other object besides himself on a crossing. If the wolf is ever left with the goat, the wolf will eat the goat If the goat is ever left with the cabbage, the goat will eat the cabbage Devise a sequence of crossings of the river so that all four characters arrive safely on the other side.
4
FWGC State Space FWGCFWGC WGCWGC F GCGC WCWC WGWG FWFW FGFG FCFC Illegal FWCFWC G C FWGFWG W FGCFGC FCFC WGWG FGCFGC W FWFW GCGC FWGFWG C
5
Desired Output 3% farmer F|| W|| G|| C|| ||F W|| ||G C|| F|| W|| ||G C|| ||F ||W ||G C|| F|| ||W G|| C|| ||F ||W G|| ||C F|| ||W G|| ||C ||F ||W ||G ||C Number of actions: 7 Number of items added to queue: 18 Number of items removed from queue: 15
6
Reusing What We Have We have designed the system so that only Problem and State know any 8-puzzle details Therefore, the rest of the classes can be reused as they are. How can we reuse Problem and State ?
7
Options for Reusing Problem and State 1)Copy them to FarmerProblem and FarmerState and make appropriate changes (quickest and dirtiest) 2)Write FarmerProblem as an extension of Problem and FarmerState as an extension of State (requires making some methods virtual) 3)Make Problem and State abstract, and define both puzzle and farmer classes to extend them
8
Option 1 ProblemSolverQueue ActionListActionItemPriorityQueueFrontQueue RearQueue State MaxPriorityQueueMinPriorityQueue FarmerProblem FarmerState
9
Notes On Option 1 Quickest to do: just copy files and change code having to do with problem domain Causes a major increase in complexity: The two new classes must interact with the rest of the system in exactly the same way Error-prone: if we make a change to Solver, Item, or ActionList, it might affect twice as many classes as before
10
Option 2 ProblemSolverQueue ActionListActionItemPriorityQueueFrontQueue RearQueue State MaxPriorityQueueMinPriorityQueue FarmerProblem FarmerState
11
Notes On Option 2 Requires identifying common methods Requires identifying overrideable (nonpure virtual) methods Problem and State classes remain nonabstract Minimizes increase in complexity Changes to Solver, Item, or ActionList do not affect new classes Susceptible to the rampaging kangaroos problem Violates natural hierarchy: farmer domain is not a subtype of the 8-puzzle domain
12
Option 3 ProblemSolverQueue ActionListActionItemPriorityQueueFrontQueue RearQueue State MaxPriorityQueueMinPriorityQueue PuzzleProblemFarmerProblem FarmerStatePuzzleState
13
Notes On Option 3 Requires identifying common methods Requires identifying abstract (pure virtual) methods Problem and State classes become abstract Minimizes increase in complexity Changes to Solver, Item, or ActionList do not affect new classes Not susceptible to the rampaging kangaroos problem Does not violate natural hierarchy
14
Refactoring Option 3 is an example of refactoring: Changing a system in such a way that its behavior is unchanged but some nonfunctional quality has been enhanced: simplicity (remove duplication) flexibility (make easy to extend) understandability performance ``If you see a one-hour ugly way to get something working, and a ten-hour way to get it working with a simpler design, spend the ten hours!!'' -- from Extreme Programming Explained
15
A Current Definition of StateInf o class StateInfo{ private: Integer intRep; // internal representation Integer blankPosition; // details static const Integer NUM_TILES = 8; public: StateInfo(StringArray tileNums); StateInfo(State cur, Integer newBlankPos); void display(); Boolean equals(State state); static State blankUp(State state); // state changing static State blankDown(State state); // methods static State blankLeft(State state); static State blankRight(State state); Integer getTileNum(Integer sqnum); private: void showBlankOrNum(Integer sqnum); };
16
Proposed Definition of FarmerStateInfo enum Side {WEST, EAST}; // sides of the river class FarmerStateInfo{ private: Side f_pos, w_pos, g_pos, c_pos; // positions of the characters public: FarmerStateInfo(Side, Side, Side, Side); void display(); Boolean equals(State state); static State self(State state); // state changing methods static State wolf(State state); static State goat(State state); static State cabbage(State state); private: void displayLine(String, Side); Boolean isSafe(); Boolean goatVulnerable(); Boolean cabbageVulnerable(); Boolean sameSideFarmerWolf(); Boolean sameSideWolfGoat(); Boolean sameSideFarmerGoat(); Boolean sameSideGoatCabbage(); Boolean sameSideFarmerCabbage(); static Side opposite(Side); };
17
What's In Common: A New, Abstract StateInfo Class class StateInfo { public: virtual void display() =0 ; virtual Boolean equals(State state) =0 ; }; Since the class is abstract, there is no constructor. Since there is no constructor, no attribute members, and no nonpure methods, this class is also known as an interface.
18
StateInfo As An Interface ProblemInfo StateInfo PuzzleStateInfoFarmerStateInfo StateInfo acts as an interface between domains and problem solving code.
19
A New PuzzleStateInfo Subclass class PuzzleStateInfo : public StateInfo{ private: Integer intRep; Integer blankPosition; static const Integer NUM_TILES = 8; public: PuzzleStateInfo(StringArray tileNums); PuzzleStateInfo(PuzzleState cur, Integer newBlankPos); void display(); Boolean equals(State state); static State blankUp(State state); static State blankDown(State state); static State blankLeft(State state); static State blankRight(State state); Integer getTileNum(Integer sqnum); private: void showBlankOrNum(Integer sqnum); };
20
FarmerStateInfo As A Subclass class FarmerStateInfo : public StateInfo{ private: Side f_pos, w_pos, g_pos, c_pos; // positions of the characters public: FarmerStateInfo(Side, Side, Side, Side); void display(); Boolean equals(State state); static State self(State state); // state changing methods static State wolf(State state); static State goat(State state); static State cabbage(State state); private: void displayLine(String, Side); Boolean isSafe(); Boolean goatVulnerable(); Boolean cabbageVulnerable(); Boolean sameSideFarmerWolf(); Boolean sameSideWolfGoat(); Boolean sameSideFarmerGoat(); Boolean sameSideGoatCabbage(); Boolean sameSideFarmerCabbage(); static Side opposite(Side); };
21
A Current Definition of ProblemInfo const Integer DEPTH_LIMIT = 1000; class ProblemInfo { private: State startState; State finalState; ActionList actionList; Integer depthLimit; public: ProblemInfo(StringArray startTileNums, Integer d=DEPTH_LIMIT); State getStartState(); State getFinalState(); ActionList getActionList(); Integer getDepthLimit(); Integer computeHeuristic(State s); private: Integer misplacedTiles(PuzzleState s); Integer sumManhattan(PuzzleState s); };
22
Proposed Definition of FarmerProblemInfo class FarmerProblemInfo { private: State startState; State finalState; ActionList actionList; Integer depthLimit; public: FarmerProblemInfo(Integer d=DEPTH_LIMIT); State getStartState(); State getFinalState(); ActionList getActionList(); Integer getDepthLimit(); Integer computeHeuristic(State s); };
23
What's In Common: A New, Abstract ProblemInfo Class class ProblemInfo { protected: State startState; State finalState; ActionList actionList; Integer depthLimit; public: ProblemInfo(Integer d); State getStartState(); State getFinalState(); ActionList getActionList(); Integer getDepthLimit(); virtual Integer computeHeuristic(State s) =0 ; };
24
A New PuzzleProblemInfo Subclass class PuzzleProblemInfo : public ProblemInfo { public: PuzzleProblemInfo(StringArray startTileNums, Integer d = DEPTH_LIMIT); Integer computeHeuristic(State s); private: Integer misplacedTiles(PuzzleState s); Integer sumManhattan(PuzzleState s); };
25
FarmerProblemInfo As A Subclass class FarmerProblemInfo : public ProblemInfo { public: FarmerProblemInfo(Integer d = DEPTH_LIMIT); Integer computeHeuristic(State s); };
26
ProblemInfo As An Abstract Class ProblemInfo SolverInfo PuzzleProblemInfoFarmerProblemInfo Since ProblemInfo has attributes of its own, and not all methods are pure, it is not, strictly speaking, an interface, but it acts like one.
27
Effects on the State-Changing Methods State StateInfo::blankUp(State state) { Integer bp = state->blankPosition; if (bp == 0 || bp == 1 || bp == 2) return NULL; else { Integer newBp = bp - 3; return new StateInfo(state, newBp);; } Consider a tile-moving method before making PuzzleStateInfo a subclass of StateInfo :
28
Effects on the State-Changing Methods (cont'd) Recall that the ActionInfo class must know nothing about particular problem domains: State ActionInfo::execute(State state) { return (*actionFun)(state); } Therefore, the blankUp 's signature must remain the same as before.
29
Effects on the State-Changing Methods (cont'd) However, the code must be changed in two ways: 1. Since the parameter is of type Stat e, it must be cast to type PuzzleState, and 2. A PuzzleState object must be created and returned, which is legal State PuzzleStateInfo::blankUp(State state) { Integer bp = ((PuzzleState)state)->blankPosition; if (bp == 0 || bp == 1 || bp == 2) return NULL; else { Integer newBp = bp - 3; return new PuzzleStateInfo((PuzzleState)state, newBp);; }
30
Abstract Classes and Program Maintenance Abstracting the problem from the various domains allows for easy file management: /home/volc/41/tcolburn/courses/cs2511/assignments/new: used 324 available 20140525 drwx------ 9 tcolburn 512 Oct 9 15:14. drwx------ 9 tcolburn 512 Sep 22 21:10.. drwx------ 2 tcolburn 512 Oct 9 00:19 Action drwx------ 5 tcolburn 512 Oct 9 00:19 Domain drwx------ 2 tcolburn 512 Oct 9 09:45 Item drwx------ 2 tcolburn 512 Oct 9 00:41 Main drwx------ 2 tcolburn 1536 Oct 9 00:19 Queue drwx------ 2 tcolburn 512 Oct 9 09:49 Search drwx------ 3 tcolburn 512 Sep 20 19:39 UserSolve -rwx------ 1 tcolburn 146192 Oct 9 09:45 farmer -rw------- 1 tcolburn 4966 Oct 9 00:18 makefile -rwx------ 1 tcolburn 146277 Oct 9 09:45 puzzle -rw------- 1 tcolburn 1078 Oct 8 16:50 typedefs.H
31
Abstract Classes and Program Maintenance (cont'd) /home/volc/41/tcolburn/courses/cs2511/assignments/new/Domain: used 20 available 20140515 drwx------ 5 tcolburn 512 Oct 9 00:19. drwx------ 9 tcolburn 512 Oct 9 15:14.. -rw------- 1 tcolburn 467 Oct 6 19:27 ProblemInfo.H -rw------- 1 tcolburn 358 Oct 6 19:24 ProblemInfo.cc -rw------- 1 tcolburn 12224 Oct 9 00:19 ProblemInfo.o -rw------- 1 tcolburn 183 Oct 4 22:29 StateInfo.H drwx------ 2 tcolburn 512 Oct 9 09:45 farmer drwx------ 2 tcolburn 512 Oct 9 13:31 puzzle Note that since StateInfo is an interface, there is no code for it.
32
Abstract Classes and Program Maintenance (cont'd) /home/volc/41/tcolburn/courses/cs2511/assignments/new/Domain/farmer: used 55 available 20140499 drwx------ 2 tcolburn 512 Oct 9 09:45. drwx------ 5 tcolburn 512 Oct 9 00:19.. -rw------- 1 tcolburn 290 Oct 8 23:57 FarmerProblemInfo.H -rw------- 1 tcolburn 575 Oct 8 23:19 FarmerProblemInfo.cc -rw------- 1 tcolburn 15512 Oct 9 00:19 FarmerProblemInfo.o -rw------- 1 tcolburn 819 Oct 8 23:59 FarmerStateInfo.H -rw------- 1 tcolburn 3569 Oct 9 00:44 FarmerStateInfo.cc -rw------- 1 tcolburn 22780 Oct 9 09:45 FarmerStateInfo.o /home/volc/41/tcolburn/courses/cs2511/assignments/new/Domain/puzzle: used 52 available 20140501 drwx------ 2 tcolburn 512 Oct 9 00:41. drwx------ 5 tcolburn 512 Oct 9 00:19.. -rw------- 1 tcolburn 388 Oct 6 19:27 PuzzleProblemInfo.H -rw------- 1 tcolburn 2043 Oct 6 19:26 PuzzleProblemInfo.cc -rw------- 1 tcolburn 18244 Oct 9 00:19 PuzzleProblemInfo.o -rw------- 1 tcolburn 706 Oct 6 14:11 PuzzleStateInfo.H -rw------- 1 tcolburn 2384 Oct 9 00:41 PuzzleStateInfo.cc -rw------- 1 tcolburn 21996 Oct 9 00:41 PuzzleStateInfo.o
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.