1 Greg Wilson BA 4234 CSC407: Software Architecture Fall 2006 Refactoring.

Slides:



Advertisements
Similar presentations
1 Inheritance Classes and Subclasses Or Extending a Class.
Advertisements

Design Patterns.
Copyright © 2011, Elsevier Inc. All rights reserved. Chapter 5 Author: Julia Richards and R. Scott Hawley.
1 Copyright © 2010, Elsevier Inc. All rights Reserved Fig 2.1 Chapter 2.
Business Transaction Management Software for Application Coordination 1 Business Processes and Coordination.
11 Copyright © 2005, Oracle. All rights reserved. Using Arrays and Collections.
10 Copyright © 2005, Oracle. All rights reserved. Reusing Code with Inheritance and Polymorphism.
Jeopardy Q 1 Q 6 Q 11 Q 16 Q 21 Q 2 Q 7 Q 12 Q 17 Q 22 Q 3 Q 8 Q 13
Jeopardy Q 1 Q 6 Q 11 Q 16 Q 21 Q 2 Q 7 Q 12 Q 17 Q 22 Q 3 Q 8 Q 13
Title Subtitle.
DIVIDING INTEGERS 1. IF THE SIGNS ARE THE SAME THE ANSWER IS POSITIVE 2. IF THE SIGNS ARE DIFFERENT THE ANSWER IS NEGATIVE.
Addition Facts
Lecture 10 Flow of Control: Loops (Part 2) COMP1681 / SE15 Introduction to Programming.
ZMQS ZMQS
Lecture 15 Linked Lists part 2
BT Wholesale October Creating your own telephone network WHOLESALE CALLS LINE ASSOCIATED.
1 Chapter 10 - Structures, Unions, Bit Manipulations, and Enumerations Outline 10.1Introduction 10.2Structure Definitions 10.3Initializing Structures 10.4Accessing.
Black Jack in Objective-C
Math and Card Games By: Candace DiBiano.
Report Card P Only 4 files are exported in SAMS, but there are at least 7 tables could be exported in WebSAMS. Report Card P contains 4 functions: Extract,
Chris Morgan, MATH G160 January 30, 2012 Lecture 9 Chapter 4.1: Combinations 1.
Recursion Chapter 14. Overview Base case and general case of recursion. A recursion is a method that calls itself. That simplifies the problem. The simpler.
Linked Lists Chapter 4.
1/27 COP 3540 Data Structures with OOP Chapter 5 Linked Lists.
Data Structures ADT List
Chapter 24 Lists, Stacks, and Queues
ITEC200 Week04 Lists and the Collection Interface.
John Hurley Cal State LA
ABC Technology Project
1 CSE 331 Enumerated types ( enum ) slides created by Marty Stepp based on materials by M. Ernst, S. Reges, D. Notkin, R. Mercer, Wikipedia
Learn to Play Bridge A New Players Guide Partners Bridge Club CLUB (2582) m ico.ca Bridge for New Players.
2000 Prentice Hall, Inc. All rights reserved. 1 Chapter 10 - Structures, Unions, Bit Manipulations, and Enumerations Outline 10.1Introduction 10.2Structure.
Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes.
1 / / / /. 2 (Object) (Object) –, 10 (Class) (Class) –, –, – (Variables) [ Data member Field Attribute](, ) – (Function) [ Member function Method Operation.
© Glenn Rowe AC Lab 2 A simple card game (twenty- one)
Classes and Objects. What is Design? The parts of the software including – what information each part holds – what things each part can do – how the various.
Object Oriented Programming with Java
1 University of Utah – School of Computing Computer Science 1021 "Thinking Like a Computer"
1 public class Newton { public static double sqrt(double c) { double epsilon = 1E-15; if (c < 0) return Double.NaN; double t = c; while (Math.abs(t - c/t)
Object-Oriented Programming. 2 An object, similar to a real-world object, is an entity with certain properties, and with the ability to react in certain.
1 4 Square Questions B A D C Look carefully to the diagram Now I will ask you 4 questions about this square. Are you ready?
Squares and Square Root WALK. Solve each problem REVIEW:
1.A computer game is an example of A.system software; B.a compiler; C.application software; D.hardware; E.none of the above. 2.JVM stands for: A.Java Virtual.
CS12230 Introduction to Programming Lecture 4-x – Consolidation 1.
© 2012 National Heart Foundation of Australia. Slide 2.
1 User-Defined Classes The String class is a pre-defined class that is provided by the Java Designer. Sometimes programmers would like to create their.
Sets and Maps Part of the Collections Framework. 2 The Set interface A Set is unordered and has no duplicates Operations are exactly those for Collection.
1 Chapter 4 The while loop and boolean operators Samuel Marateck ©2010.
SIMOCODE-DP Software.
GG Consulting, LLC I-SUITE. Source: TEA SHARS Frequently asked questions 2.
Chapter 5 Loops Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All rights reserved.
Addition 1’s to 20.
25 seconds left…...
Week 1.
We will resume in: 25 Minutes.
©Brooks/Cole, 2001 Chapter 12 Derived Types-- Enumerated, Structure and Union.
A SMALL TRUTH TO MAKE LIFE 100%
Chapter 11 Component-Level Design
How Cells Obtain Energy from Food
Building Java Programs Chapter 14
Index Student Activity 1: Questions to familiarise students with the
L6:CSC © Dr. Basheer M. Nasef Lecture #6 By Dr. Basheer M. Nasef.
Interfaces CSC 171 FALL 2004 LECTURE 14. Project 1 review public class Rational { private int numerator, denominator; public Rational(int numerator, int.
Computer Science 313 – Advanced Programming Topics.
Design Example. Requirements Make a program that simulates the game of blackjack For now, we ignore money/betting…. just simulate game play But… this.
Chapter 5 Black Jack. Copyright © 2005 Pearson Addison-Wesley. All rights reserved. 5-2 Chapter Objectives Provide a case study example from problem statement.
Black Jack MVC By Jeremy DiPaolo. Introduction Goal: To create a Black Jack game that takes advantage of the MVC framework. Uses many of the components.
Poker UML and ADT design plan.
Chapter 5 Black Jack.
Task 2 Implementation help
Presentation transcript:

1 Greg Wilson BA 4234 CSC407: Software Architecture Fall 2006 Refactoring

2 Making Code Better The first lectures discussed principles that good object-oriented code should obey But what if the code you have doesnt? Refactoring is the process of reorganizing code to improve structure, or make room for future extension –Without changing functionality

3 Refactoring and Patterns Design patterns describe what code looks like when its standing still Refactoring patterns describe how code changes over time Usually (but not often) you refactor to patterns –I.e., move from poor or inappropriate organization to one or more recognized patterns

4 Blackjack A card game involving one or more players and a dealer –Start with two cards, and can ask for more –Players go first; dealer goes last Dealer must take a card when under 17 Must stand at 17 or over –Objective is to get as close to 21 as possible, without going over

5 A Blackjack Hand public class BlackjackHand { private ArrayList cards = new Arraylist (); public void addCard(Card card) { cards.add(card); } public List getCards() { return cards; } public boolean isBusted() { return getCount() > 21; } public int getResult(BlackjackDealer dealer) { // figure out if this hand beats the dealer } public int getCount() { // return the value of this hand } public String toString() { … } } Want to be able to re-use this in other card games Why do we depend on the dealer to figure out if we won?

6 Cards public class Card { public enum Suit { CLUBS, DIAMONDS, HEARTS, SPADES } public Suit suit; private int value; private BlackjackHand heldBy; public Card(Suit suit, int value) { … } public void setHand(BlackjackHand hand) { heldBy = hand; } public BlackjackHand getHand() { return heldBy; } public int getLowValue() { // value or 1 for ace, 10 for face cards } public int getHighValue() { // value or 11 for ace, 10 for face cards } Wont be able to use this in a poker game This is very specific to blackjack.

7 The Dealer public class BlackjackDealer { private BlackjackHand hand = new BlackjackHand(); public Card getUpCard() { return hand.getCards().get(1); } public BlackjackHand getHand() { return hand; } public boolean mustHit() { return hand.getCount() < 17; } OK so far, but…

8 Players public class ComputerBlackjackPlayer { private BlackjackHand hand = new BlackjackHand(); public BlackjackHand getHand() { return hand; } public boolean wantCard(BlackjackDealer dealer) { // artificial intelligence goes here… } public class HumanBlackjackPlayer { private BlackjackHand hand = new BlackjackHand(); public BlackjackHand getHand() { return hand; } public boolean wantCard() { // user interface goes here… } These two classes have nothing in common with each other, or with the dealer shown on the previous slide!

9 The Game public class Blackjack { public static void main(String[] args) { Blackjack bj = new Blackjack(); bj.playGame(); } public void playGame() { ArrayList deck = new ArrayList (52); for (Card.Suit suit : Card.Suit.values()) { for (int value=1; value<=13; ++value) { Card card = new Card(suit, value); deck.add(card); } This block is not specific to blackjack: we should make it reusable

10 …The Game Collections.shuffle(deck); ComputerBlackjackPlayer computer = new ComputerBlackjackPlayer(); HumanBlackjackPlayer human = new HumanBlackjackPlayer(); BlackjackDealer dealer = new BlackjackDealer(); for (int c=0; c<2; c++) { Card card = deck.remove(0); BlackjackHand computerHand = computer.getHand(); computerHand.addCard(card); card.setHand(computerHand); card = deck.remove(0); BlackjackHand humanHand = human.getHand(); humanHand.addCard(card); card.setHand(humanHand); card = deck.remove(0); BlackjackHand dealerHand = dealer.getHand(); dealerHand.addCard(card); card.setHand(dealerHand); } Deals two cards to each playersurely this can be simpler

11 …The Game System.out.println("Dealer has: " + dealer.getUpCard()); boolean computerBusted = false; while (computer.wantCard(dealer)) { Card card = deck.remove(0); BlackjackHand computerHand = computer.getHand(); computerHand.addCard(card); card.setHand(computerHand); if (computerHand.isBusted()) { computerBusted = true; break; } if (computerBusted) { System.out.println("*** Computer busted! ***"); } else { System.out.println("*** Computer stands ***"); } Scattered println statements as a user interface? Bleah… And haven't we seen the lines that give players cards before?

12 …The Game boolean humanBusted = false; System.out.println("Your hand: " + human.getHand()); while (human.wantCard()) { …basically the same code as above… } boolean dealerBusted = false; …basically the same code as above… The three players play in almost the same way; the only things that differ are what they're called, and how they decide whether or not to take another card

13 …The Game System.out.println("*** Results ***"); int compResult = computer.getHand().getResult(dealer); if (compResult > 0) { System.out.println("Computer wins"); } else if (compResult < 0) { System.out.println("Computer loses"); } else { System.out.println("Computer pushes"); } int humanResult = human.getHand().getResult(dealer); if (humanResult > 0) { System.out.println("You win!"); } else if (humanResult < 0) { System.out.println("You lose :-("); } else { System.out.println("You push"); } More repetition, more embedded printing… (Oh, and "push" is blackjackese for "tie")

14 Just How Bad Is This? Blackjack ComputerBlackjackPlayer HumanBlackjackPlayer BlackjackDealer BlackjackHandCard * 0…1 Eww…

15 Problems Every Card knows about the BlackjackHand that's holding it –Which makes the Card class hard to re-use in a poker program The Blackjack class runs everything –Creating a deck of cards and shuffling it ought to be reusable

16 …Problems Parts of the BlackjackHand class could be used for other kinds of "hands" There's a lot of duplicated code BlackjackHand depends on BlackjackDealer –Because one of BlackjackHand 's methods takes a BlackjackDealer as a parameter

17 …Problems BlackjackDealer has one big monolithic playGame method –Quick, tell me how you're going to test it The UI consists of scattered print statements –How are we going to build a GUI for this, or a web interface?

18 Step 1: Deblackjackification public class Card { public enum Suit { CLUBS, DIAMONDS, HEARTS, SPADES } public Suit suit; private int value; private BlackjackHand heldBy; public Card(Suit suit, int value) { … } public void setHand(BlackjackHand hand) { heldBy = hand; } public BlackjackHand getHand() { return heldBy; } public int getLowValue() { // value or 1 for ace, 10 for face cards } public int getHighValue() { // value or 11 for ace, 10 for face cards } References to BlackjackHand Other games don't give cards these values (or distinguish low and high values)

19 A Non-Solution Option 1: create an abstract Hand base class, and derive BlackjackHand from that But that still leaves this fragile code: computerHand.addCard(card); card.setHand(computerHand); Do cards really need to know what hands their in?

20 Our First Refactoring Pattern Change Bidirectional Association to Unidirectional Association –BDAs aren't intrinsically bad –But they are intrinsically harder to manage Remove getHand and setHand from Card, remove the setHand calls in Blackjack –…nothing breaks!

21 Moving Methods getLowValue and getHighValue are next –Can't delete them, since getCount needs the information they provide Options: –Move into an existing subclass –Create a subclass and move the methods down

22 Spotting Movable Methods If a method uses another object more than it uses itself, it's a candidate for moving public class X { public int meth(Y y) { int y1 = y.one(); int y2 = y.two(); int y3 = y.three(); return y1 + y2 + y3; } public class Y { public int meth() { return one() + two() + three(); }

23 What About Subclassing? The other option is to the logic into a new subclass –Have Card.getValue return the "raw" value –Have BlackjackCard wrap getValue in two new methods getLowValue and getHighValue –Then change references from Card to BlackjackCard Votes?

24 Open-Closed Principle public Deck() { cards = new ArrayList (52); for (Card.Suit suit : Card.Suit.values()) { for (int value=1; value<=13; ++value) { Card card = new Card(suit, value); cards.add(card); } public Deck() { cards = createCards(); } protected List createCards() { List cards = new ArrayList (52); for (Card.Suit suit : Card.Suit.values) { for (int value=1; value<=13; ++value) { Card card = createCard(suit, value); cards.add(card); } return cards; } protected Card createCard(Card.Suit s, int v) { return new Card(s, v); }

25 Why Is This Better? Most of the code looks the same But: –It'll be easier to create decks of 48 cards (for pinochle) –There's an obvious place to create a BlackjackCard instead of a basic Card Question: what about the 52 and 13?

26 Open For Extension Let's make sure that the blackjack program creates instances of BlackjackCard public class BlackjackDeck extends Deck { protected Card createCard(Card.Suit s, int v) { return new BlackjackCard(s, v); } public BlackjackCard dealCard() { return (BlackjackCard)super.dealCard(); } public class Deck { public Card dealCard() { return cards.get(nextCard++); } No need to override the createCard method Look up the meaning of "covariant return types" before next class

27 Impact public void playGame() { ArrayList deck = new ArrayList (52); for (Card.Suit suit : Card.Suit.values()) { for (int value=1; value<=13; ++value) { Card card = new Card(suit, value); deck.add(card); } Collections.shuffle(deck); …create players… for (int c=0; c<2; c++) { Card card = deck.remove(0); BlackjackHand computerHand = computer.getHand(); computerHand.addCard(card); card = deck.remove(0); BlackjackDeck deck = new BlackjackDeck(); deck.shuffle(); BlackjackCard card = deck.dealCard();

28 To Put It Another Way… CardDeck BlackjackHand 0…1 * 152

29 Our Next Target public class BlackjackHand { private ArrayList cards = new ArrayList ; public void addCard(Card card) { cards.add(card); } public List getCards() { return cards; } public boolean isBusted() { return getCount() > 21; } public int getResult(BlackjackDealer dealer) { // compute winner } public int getCount() { // figure out what the hand's worth } public String toString() { … } } Reusable Specific to blackjack Partially reusable?

30 Yet More Abstraction public abstract class Hand { private List cards = new ArrayList (); public void addCard(Card card) { cards.add(card); } public List getCards() { return Collections.unmodifiableList(cards); } public toString() { return cards.toString(); } public void clear() { cards.clear(); } } Look up what this does for next week We can probably improve this Since we're here…

31 …Yet More Abstraction public class BlackjackHand extends Hand { public boolean isBusted() { return getCount() > 21; } public int getResult(BlackjackDealer dealer) { // compute hand winner } public int getCount() { // figure out what hand's worth } public String toString() { return super.toString() + ": " + getCount(); } public Card getUpCard() { return getCards().get(1); } No longer explicitly managing cards The improved version Since we're here…

32 The Extended Design HandCard BlackjackHand 0..1 * 152 Deck BlackjackCard

33 Half the Changes We've now fixed the problems with cards, decks, and hands Still have to fix problems with players –Human, computer, and dealer overlap in many ways is required reading for this course

34 Questions? Fig. 1: Dialog (front view)Fig. 2: Dialog (side view)