netoxi

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
  27 Posts :: 0 Stories :: 19 Comments :: 0 Trackbacks

目录

· 概述

· Factory

    · What is the Factory Design Pattern?

    · Sample Code

· Abstract Factory

    · What is the Abstract Factory Design Pattern?

    · What can you do with an Abstract Factory Design Pattern?

    · Sample Code

· Singleton

    · What is the Singleton Design Pattern?

    · Sample Code

· Builder

    · What is the Builder Design Pattern?

    · Sample Code

· Prototype

    · What is the Prototype Design Pattern?

    · Sample Code


 

概述

最近在YouTube上看了一套不错的设计模式视频,同时翻看GOF的《设计模式 可复用面向对象软件的基础》,刷新了我对设计模式的认识。加之之前的一篇博文《设计模式笔记——GoF设计模式汇总》中未提及比较少用的解释器和访问者模式,以及大陆无法打开YouTube等原因,所以将这套视频所学到的主要内容记录成笔记,供未来需要时查阅和复习。

Factory

What is the Factory Design Pattern?

• When a method returns one of several possible classes that share a common super class.

• Create a new enemy in a game.

• Random number generator picks a number assigned to a specific enemy.

• The factory returns the enemy associated with that number.

• The class is chosen at run time.

Sample Code

• EnemyShip.java

 1 public abstract class EnemyShip {
 2     
 3     private String name;
 4     private double speed;
 5     private double directionX;
 6     private double directionY;
 7     private double amtDamage;
 8     
 9     public String getName() { return name; }
10     public void setName(String newName) { name = newName; }
11     
12     public double getDamage() { return amtDamage; }
13     public void setDamage(double newDamage) { amtDamage = newDamage; }
14     
15     public void followHeroShip(){
16         
17         System.out.println(getName() + " is following the hero");
18         
19     }
20     
21     public void displayEnemyShip(){
22         
23         System.out.println(getName() + " is on the screen");
24         
25     }
26     
27     public void enemyShipShoots() {
28         
29         System.out.println(getName() + " attacks and does " + getDamage() + " damage to hero");
30         
31     }
32     
33 }

• UFOEnemyShip.java

 1 public class UFOEnemyShip extends EnemyShip {
 2     
 3     public UFOEnemyShip(){
 4         
 5         setName("UFO Enemy Ship");
 6         
 7         setDamage(20.0);
 8         
 9     }
10     
11 }

• RocketEnemyShip.java

 1 public class RocketEnemyShip extends EnemyShip {
 2     
 3     public RocketEnemyShip(){
 4         
 5         setName("Rocket Enemy Ship");
 6         
 7         setDamage(10.0);
 8         
 9     }
10     
11 }

• EnemyShipTesting.java

 1 import java.util.Scanner;
 2 
 3 public class EnemyShipTesting {
 4 
 5     public static void main(String[] args){
 6         
 7         // Create the factory object
 8         EnemyShipFactory shipFactory = new EnemyShipFactory();
 9         
10         // Enemy ship object
11         
12         EnemyShip theEnemy = null;
13         
14         Scanner userInput = new Scanner(System.in);
15         
16         System.out.print("What type of ship? (U / R / B)");
17         
18         if (userInput.hasNextLine()){
19             
20             String typeOfShip = userInput.nextLine();
21         
22             theEnemy = shipFactory.makeEnemyShip(typeOfShip);
23             
24             if(theEnemy != null){
25                 
26                 doStuffEnemy(theEnemy);
27                 
28             } else System.out.print("Please enter U, R, or B next time");
29         
30         }
31         
32         /*
33         EnemyShip theEnemy = null;
34         
35         // Old way of creating objects
36         // When we use new we are not being dynamic
37         
38         EnemyShip ufoShip = new UFOEnemyShip();
39         
40         doStuffEnemy(ufoShip);
41         
42         System.out.print("\n");
43         
44         // -----------------------------------------
45         
46         // This allows me to make the program more dynamic
47         // It doesn't close the code from being modified
48         // and that is bad!
49         
50         // Defines an input stream to watch: keyboard
51         Scanner userInput = new Scanner(System.in);
52         
53         String enemyShipOption = "";
54         
55         System.out.print("What type of ship? (U or R)");
56         
57         if (userInput.hasNextLine()){
58             
59             enemyShipOption = userInput.nextLine();
60             
61         }
62         
63         if (enemyShipOption == "U"){
64             
65             theEnemy = new UFOEnemyShip();
66 
67             
68         } else 
69         
70         if (enemyShipOption == "R"){
71             
72             theEnemy = new RocketEnemyShip();
73             
74         } else {
75             
76             theEnemy = new BigUFOEnemyShip();
77             
78         }
79         
80         doStuffEnemy(theEnemy);
81         
82         // --------------------------------------------
83         */
84         
85     }
86     
87     // Executes methods of the super class
88     
89     public static void doStuffEnemy(EnemyShip anEnemyShip){
90         
91         anEnemyShip.displayEnemyShip();
92         
93         anEnemyShip.followHeroShip();
94         
95         anEnemyShip.enemyShipShoots();
96         
97     }
98     
99 }

• BigUFOEnemyShip.java

 1 public class BigUFOEnemyShip extends UFOEnemyShip {
 2     
 3     public BigUFOEnemyShip(){
 4         
 5         setName("Big UFO Enemy Ship");
 6         
 7         setDamage(40.0);
 8         
 9     }
10     
11 }

• EnemyShipFactory.java

 1 // This is a factory thats only job is creating ships
 2 // By encapsulating ship creation, we only have one
 3 // place to make modifications
 4 
 5 public class EnemyShipFactory{
 6     
 7     // This could be used as a static method if we
 8     // are willing to give up subclassing it
 9     
10     public EnemyShip makeEnemyShip(String newShipType){
11         
12         EnemyShip newShip = null;
13         
14         if (newShipType.equals("U")){
15             
16             return new UFOEnemyShip();
17             
18         } else 
19         
20         if (newShipType.equals("R")){
21             
22             return new RocketEnemyShip();
23             
24         } else 
25         
26         if (newShipType.equals("B")){
27             
28             return new BigUFOEnemyShip();
29             
30         } else return null;
31         
32     }
33     
34 }

Abstract Factory

What is the Abstract Factory Design Pattern?

• It is like a factory, but everything is encapsulated.

• The method that orders the object.

• The factories that build the object.

• The final objects.

• The final objects contain objects that use the Strategy Design Pattern.

• Composition: Object class fields are objects.

What can you do with an Abstract Factory Design Pattern?

• Allows you to create families of related objects without specifying a concrete class.

• Use when you have many objects that can be added, or changed dynamically during runtime.

• You can model anything you can imagine and have those objects interact through common interfaces.

• The Bad: Things can get complicated.

Sample Code

• EnemyShipTesting.java

 1 public class EnemyShipTesting {
 2     
 3 public static void main(String[] args) {
 4         
 5         // EnemyShipBuilding handles orders for new EnemyShips
 6         // You send it a code using the orderTheShip method &
 7         // it sends the order to the right factory for creation
 8     
 9         EnemyShipBuilding MakeUFOs = new UFOEnemyShipBuilding();
10  
11         EnemyShip theGrunt = MakeUFOs.orderTheShip("UFO");
12         System.out.println(theGrunt + "\n");
13         
14         EnemyShip theBoss = MakeUFOs.orderTheShip("UFO BOSS");
15         System.out.println(theBoss + "\n");
16  
17     }
18     
19 }

• EnemyShipBuilding.java

 1 public abstract class EnemyShipBuilding {
 2     
 3     // This acts as an ordering mechanism for creating
 4     // EnemyShips that have a weapon, engine & name
 5     // & nothing else
 6     
 7     // The specific parts used for engine & weapon depend
 8     // upon the String that is passed to this method
 9  
10     protected abstract EnemyShip makeEnemyShip(String typeOfShip);
11  
12     // When called a new EnemyShip is made. The specific parts
13     // are based on the String entered. After the ship is made
14     // we execute multiple methods in the EnemyShip Object
15     
16     public EnemyShip orderTheShip(String typeOfShip) {
17         EnemyShip theEnemyShip = makeEnemyShip(typeOfShip);
18         
19         theEnemyShip.makeShip();
20         theEnemyShip.displayEnemyShip();
21         theEnemyShip.followHeroShip();
22         theEnemyShip.enemyShipShoots();
23         
24         return theEnemyShip;
25         
26     }
27 }

• UFOEnemyShipBuilding.java

 1 // This is the only class that needs to change, if you
 2 // want to determine which enemy ships you want to
 3 // provide as an option to build
 4 
 5 public class UFOEnemyShipBuilding extends EnemyShipBuilding {
 6 
 7     protected EnemyShip makeEnemyShip(String typeOfShip) {
 8         EnemyShip theEnemyShip = null;
 9         
10         // If UFO was sent grab use the factory that knows
11         // what types of weapons and engines a regular UFO
12         // needs. The EnemyShip object is returned & given a name
13         
14         if(typeOfShip.equals("UFO")){
15             EnemyShipFactory shipPartsFactory = new UFOEnemyShipFactory();
16             theEnemyShip = new UFOEnemyShip(shipPartsFactory);
17             theEnemyShip.setName("UFO Grunt Ship");
18             
19         } else 
20             
21         // If UFO BOSS was sent grab use the factory that knows
22         // what types of weapons and engines a Boss UFO
23         // needs. The EnemyShip object is returned & given a name
24             
25         if(typeOfShip.equals("UFO BOSS")){
26             EnemyShipFactory shipPartsFactory = new UFOBossEnemyShipFactory();
27             theEnemyShip = new UFOBossEnemyShip(shipPartsFactory);
28             theEnemyShip.setName("UFO Boss Ship");
29             
30         } 
31         
32         return theEnemyShip;
33     }
34 }

• EnemyShipFactory.java

 1 // With an Abstract Factory Pattern you won't
 2 // just build ships, but also all of the components
 3 // for the ships
 4 
 5 // Here is where you define the parts that are required
 6 // if an object wants to be an enemy ship
 7 
 8 public interface EnemyShipFactory{
 9     
10     public ESWeapon addESGun();
11     public ESEngine addESEngine();
12     
13 }

• UFOEnemyShipFactory.java

 1 // This factory uses the EnemyShipFactory interface
 2 // to create very specific UFO Enemy Ship
 3 
 4 // This is where we define all of the parts the ship
 5 // will use by defining the methods implemented
 6 // being ESWeapon and ESEngine
 7 
 8 // The returned object specifies a specific weapon & engine
 9 
10 public class UFOEnemyShipFactory implements EnemyShipFactory{
11 
12     // Defines the weapon object to associate with the ship
13     
14     public ESWeapon addESGun() {
15         return new ESUFOGun(); // Specific to regular UFO
16     }
17 
18     // Defines the engine object to associate with the ship
19     
20     public ESEngine addESEngine() {
21         return new ESUFOEngine(); // Specific to regular UFO
22     }
23 }

• UFOBossEnemyShipFactory.java

 1 // This factory uses the EnemyShipFactory interface
 2 // to create very specific UFO Enemy Ship
 3 
 4 // This is where we define all of the parts the ship
 5 // will use by defining the methods implemented
 6 // being ESWeapon and ESEngine
 7 
 8 // The returned object specifies a specific weapon & engine
 9 
10 public class UFOBossEnemyShipFactory implements EnemyShipFactory{
11 
12     // Defines the weapon object to associate with the ship
13     
14     public ESWeapon addESGun() {
15         return new ESUFOBossGun(); // Specific to Boss UFO
16     }
17 
18     // Defines the engine object to associate with the ship
19     
20     public ESEngine addESEngine() {
21         return new ESUFOBossEngine(); // Specific to Boss UFO
22     }
23 
24 }

• EnemyShip.java

 1 public abstract class EnemyShip {
 2     
 3     private String name;
 4     
 5     // Newly defined objects that represent weapon & engine
 6     // These can be changed easily by assigning new parts 
 7     // in UFOEnemyShipFactory or UFOBossEnemyShipFactory
 8     
 9     ESWeapon weapon;
10     ESEngine engine;
11     
12     public String getName() { return name; }
13     public void setName(String newName) { name = newName; }
14     
15     abstract void makeShip();
16     
17     // Because I defined the toString method in engine
18     // when it is printed the String defined in toString goes
19     // on the screen
20     
21     public void followHeroShip(){
22         
23         System.out.println(getName() + " is following the hero at " + engine );
24         
25     }
26     
27     public void displayEnemyShip(){
28         
29         System.out.println(getName() + " is on the screen");
30         
31     }
32     
33     public void enemyShipShoots(){
34         
35         System.out.println(getName() + " attacks and does " + weapon);
36         
37     }
38     
39     // If any EnemyShip object is printed to screen this shows up
40     
41     public String toString(){
42         
43         String infoOnShip = "The " + name + " has a top speed of " + engine + 
44                 " and an attack power of " + weapon;
45         
46         return infoOnShip;
47         
48     }
49     
50 }

• UFOEnemyShip.java

 1 public class UFOEnemyShip extends EnemyShip{
 2     
 3     // We define the type of ship we want to create
 4     // by stating we want to use the factory that 
 5     // makes enemy ships
 6     
 7     EnemyShipFactory shipFactory;
 8     
 9     // The enemy ship required parts list is sent to 
10     // this method. They state that the enemy ship
11     // must have a weapon and engine assigned. That 
12     // object also states the specific parts needed
13     // to make a regular UFO versus a Boss UFO
14     
15     public UFOEnemyShip(EnemyShipFactory shipFactory){
16         
17         this.shipFactory = shipFactory;
18         
19     }
20 
21     // EnemyShipBuilding calls this method to build a 
22     // specific UFOEnemyShip
23     
24     void makeShip() {
25         
26         System.out.println("Making enemy ship " + getName());
27         
28         // The specific weapon & engine needed were passed in
29         // shipFactory. We are assigning those specific part
30         // objects to the UFOEnemyShip here
31         
32         weapon = shipFactory.addESGun();
33         engine = shipFactory.addESEngine();
34         
35     }
36     
37 }

• UFOBossEnemyShip.java

 1 public class UFOBossEnemyShip extends EnemyShip{
 2     
 3     // We define the type of ship we want to create
 4     // by stating we want to use the factory that 
 5     // makes enemy ships
 6     
 7     EnemyShipFactory shipFactory;
 8     
 9     // The enemy ship required parts list is sent to 
10     // this method. They state that the enemy ship
11     // must have a weapon and engine assigned. That 
12     // object also states the specific parts needed
13     // to make a Boss UFO versus a Regular UFO
14     
15     public UFOBossEnemyShip(EnemyShipFactory shipFactory){
16         
17         this.shipFactory = shipFactory;
18         
19     }
20     
21     // EnemyShipBuilding calls this method to build a 
22     // specific UFOBossEnemyShip
23 
24     void makeShip() {
25         
26         // TODO Auto-generated method stub
27         
28         System.out.println("Making enemy ship " + getName());
29         
30         // The specific weapon & engine needed were passed in
31         // shipFactory. We are assigning those specific part
32         // objects to the UFOBossEnemyShip here
33         
34         weapon = shipFactory.addESGun();
35         engine = shipFactory.addESEngine();
36         
37     }
38     
39 }

• ESEngine.java

 1 // Any part that implements the interface ESEngine
 2 // can replace that part in any ship
 3 
 4 public interface ESEngine{
 5 
 6     // User is forced to implement this method
 7     // It outputs the string returned when the 
 8     // object is printed
 9     
10     public String toString();
11 
12 }

• ESWeapon.java

 1 // Any part that implements the interface ESWeapon
 2 // can replace that part in any ship
 3 
 4 public interface ESWeapon{
 5     
 6     // User is forced to implement this method
 7     // It outputs the string returned when the 
 8     // object is printed
 9 
10     public String toString();
11 
12 }

• ESUFOGun.java

 1 // Here we define a basic component of a space ship
 2 // Any part that implements the interface ESWeapon
 3 // can replace that part in any ship
 4 
 5 public class ESUFOGun implements ESWeapon{
 6     
 7     // EnemyShip contains a reference to the object
 8     // ESWeapon. It is stored in the field weapon
 9     
10     // The Strategy design pattern is being used here
11     
12     // When the field that is of type ESUFOGun is printed 
13     // the following shows on the screen
14     
15     public String toString(){
16         return "20 damage";
17     }
18     
19 }

• ESUFOEngine.java

 1 // Here we define a basic component of a space ship
 2 // Any part that implements the interface ESEngine
 3 // can replace that part in any ship
 4 
 5 public class ESUFOEngine implements ESEngine{
 6     
 7     // EnemyShip contains a reference to the object
 8     // ESWeapon. It is stored in the field weapon
 9         
10     // The Strategy design pattern is being used here
11         
12     // When the field that is of type ESUFOGun is printed 
13     // the following shows on the screen
14     
15     public String toString(){
16         return "1000 mph";
17     }
18     
19 }

• ESUFOBossGun.java

 1 // Here we define a basic component of a space ship
 2 // Any part that implements the interface ESWeapon
 3 // can replace that part in any ship
 4 
 5 public class ESUFOBossGun implements ESWeapon{
 6     
 7     // EnemyShip contains a reference to the object
 8     // ESWeapon. It is stored in the field weapon
 9         
10     // The Strategy design pattern is being used here
11         
12     // When the field that is of type ESUFOGun is printed 
13     // the following shows on the screen
14     
15     public String toString(){
16         return "40 damage";
17     }
18     
19 }

• ESUFOBossEngine.java

 1 // Here we define a basic component of a space ship
 2 // Any part that implements the interface ESEngine
 3 // can replace that part in any ship
 4 
 5 public class ESUFOBossEngine implements ESEngine{
 6     
 7     // EnemyShip contains a reference to the object
 8     // ESWeapon. It is stored in the field weapon
 9             
10     // The Strategy design pattern is being used here
11             
12     // When the field that is of type ESUFOGun is printed 
13     // the following shows on the screen
14     
15     public String toString(){
16         return "2000 mph";
17     }
18     
19 }

Singleton

What is the Singleton Design Pattern?

• It is used when you want to eliminate the option of instantiating more than one object.

• I'll Samplenstrate it using a class that holds all the potential Scrabble letters and spits out new ones upon request.

• Each player will share the same potential letter list.

• Each player has their own set of letters.

Sample Code

• Singleton.java

  1 import java.util.Arrays;
  2 import java.util.Collections;
  3 import java.util.LinkedList;
  4 
  5 public class Singleton {
  6     
  7     private static Singleton firstInstance = null;
  8     
  9     String[] scrabbleLetters = {"a", "a", "a", "a", "a", "a", "a", "a", "a",
 10             "b", "b", "c", "c", "d", "d", "d", "d", "e", "e", "e", "e", "e", 
 11             "e", "e", "e", "e", "e", "e", "e", "f", "f", "g", "g", "g", "h", 
 12             "h", "i", "i", "i", "i", "i", "i", "i", "i", "i", "j", "k", "l", 
 13             "l", "l", "l", "m", "m", "n", "n", "n", "n", "n", "n", "o", "o", 
 14             "o", "o", "o", "o", "o", "o", "p", "p", "q", "r", "r", "r", "r", 
 15             "r", "r", "s", "s", "s", "s", "t", "t", "t", "t", "t", "t", "u", 
 16             "u", "u", "u", "v", "v", "w", "w", "x", "y", "y", "z",};  
 17     
 18     private LinkedList<String> letterList = new LinkedList<String> (Arrays.asList(scrabbleLetters));
 19    
 20     // Used to slow down 1st thread
 21     static boolean firstThread = true;
 22     
 23     // Created to keep users from instantiation
 24     // Only Singleton will be able to instantiate this class
 25    
 26     private Singleton() { }
 27     
 28     // We could make getInstance a synchronized method to force 
 29     // every thread to wait its turn. That way only one thread
 30     // can access a method at a time. This can really slow everything
 31     // down though
 32     // public static synchronized Singleton getInstance()
 33     
 34     public static Singleton getInstance() {
 35         if(firstInstance == null) {
 36             
 37             // This is here to test what happens if threads try
 38             // to create instances of this class
 39             
 40             if(firstThread){
 41             
 42                 firstThread = false;
 43                 
 44                 try {
 45                     Thread.currentThread();
 46                     Thread.sleep(1000);
 47                 } catch (InterruptedException e) {
 48                 
 49                     e.printStackTrace();
 50                 }
 51             }
 52             
 53             // Here we just use synchronized when the first object
 54             // is created
 55             
 56             synchronized(Singleton.class){ 
 57             
 58                 if(firstInstance == null) {
 59                     // If the instance isn't needed it isn't created
 60                     // This is known as lazy instantiation
 61             
 62                     firstInstance = new Singleton();
 63             
 64                     // Shuffle the letters in the list
 65                     Collections.shuffle(firstInstance.letterList);
 66                     
 67                 }
 68             
 69             }
 70             
 71         }
 72         
 73         // Under either circumstance this returns the instance
 74         
 75         return firstInstance;
 76     }
 77     
 78     public LinkedList<String> getLetterList(){
 79         
 80         return firstInstance.letterList;
 81         
 82     }
 83     
 84     public LinkedList<String> getTiles(int howManyTiles){
 85         
 86         // Tiles to be returned to the user
 87         
 88         LinkedList<String> tilesToSend = new LinkedList<String>();
 89         
 90         // Cycle through the LinkedList while adding the starting
 91         // Strings to the to be returned LinkedList while deleting
 92         // them from letterList
 93         
 94         for(int i = 0; i <= howManyTiles; i++){
 95         
 96             tilesToSend.add(firstInstance.letterList.remove(0));
 97         
 98         }
 99         
100         // Return the number of letter tiles requested
101         
102         return tilesToSend;
103         
104     }
105     
106 }

• ScrabbleTest.java

 1 import java.util.LinkedList;
 2 
 3 public class ScrabbleTest {
 4     
 5     public static void main(String[] args){
 6         
 7         // How you create a new instance of Singleton
 8         
 9         Singleton newInstance = Singleton.getInstance();
10         
11         // Get unique id for instance object
12         
13         System.out.println("1st Instance ID: " + System.identityHashCode(newInstance));
14         
15         // Get all of the letters stored in the List
16         
17         System.out.println(newInstance.getLetterList());
18         
19         LinkedList<String> playerOneTiles = newInstance.getTiles(7);
20         
21         System.out.println("Player 1: " + playerOneTiles);
22         
23         System.out.println(newInstance.getLetterList());
24         
25         // Try to make another instance of Singleton
26         // This doesn't work because the constructor is private
27         
28         // Singleton instanceTwo = new Singleton();
29         
30         // Try getting a new instance using getInstance
31         
32         Singleton instanceTwo = Singleton.getInstance();
33         
34         // Get unique id for the new instance object
35         
36         System.out.println("2nd Instance ID: " + System.identityHashCode(instanceTwo));
37         
38         // This returns the value of the first instance created
39         
40         System.out.println(instanceTwo.getLetterList());
41         
42         // Player 2 draws 7 tiles
43         
44         LinkedList<String> playerTwoTiles = newInstance.getTiles(7);
45         
46         System.out.println("Player 2: " + playerTwoTiles);
47         
48     }
49     
50 }

• ScrabbleTestThreads.java

 1 public class ScrabbleTestThreads{
 2     
 3     public static void main(String[] args){
 4         
 5         // Create a new Thread created using the Runnable interface
 6         // Execute the code in run after 10 seconds
 7                 
 8         Runnable getTiles = new GetTheTiles();
 9                 
10         Runnable getTilesAgain = new GetTheTiles();
11                 
12         // Call for the code in the method run to execute
13                 
14         new Thread(getTiles).start();
15         new Thread(getTilesAgain).start();
16         
17     }
18     
19 }

• GetTheTiles.java

 1 import java.util.LinkedList;
 2 
 3 public class GetTheTiles implements Runnable {
 4     
 5     public void run(){
 6 
 7             // How you create a new instance of Singleton
 8             
 9             Singleton newInstance = Singleton.getInstance();
10             
11             // Get unique id for instance object
12             
13             System.out.println("1st Instance ID: " + System.identityHashCode(newInstance));
14             
15             // Get all of the letters stored in the List
16             
17             System.out.println(newInstance.getLetterList());
18             
19             LinkedList<String> playerOneTiles = newInstance.getTiles(7);
20             
21             System.out.println("Player 1: " + playerOneTiles);
22         
23         System.out.println("Got Tiles");
24     }
25     
26 }

Builder

What is the Builder Design Pattern?

• Pattern used to create objects made from a bunch of other objects.

• When you want to build an object made up from other objects.

• When you want the creation of these parts to be independent of the main object.

• Hide the creation of the parts from the client so both aren't dependent.

• The builder knows the specifics and nobody else dose.

Sample Code

• RobotPlan.java

 1 // This is the interface that will be returned from the builder
 2 
 3 public interface RobotPlan{
 4     
 5     public void setRobotHead(String head);
 6     
 7     public void setRobotTorso(String torso);
 8     
 9     public void setRobotArms(String arms);
10     
11     public void setRobotLegs(String legs);
12     
13 }

• Robot.java

 1 // The concrete Robot class based on the RobotPlan interface
 2 
 3 public class Robot implements RobotPlan{
 4 
 5     private String robotHead;
 6     private String robotTorso;
 7     private String robotArms;
 8     private String robotLegs;
 9     
10     public void setRobotHead(String head) {
11         
12         robotHead = head;
13         
14     }
15     
16     public String getRobotHead(){ return robotHead; }
17 
18     
19     public void setRobotTorso(String torso) {
20         
21         robotTorso = torso;
22         
23     }
24     
25     public String getRobotTorso(){ return robotTorso; }
26 
27     
28     public void setRobotArms(String arms) {
29         
30         robotArms = arms;
31         
32     }
33     
34     public String getRobotArms(){ return robotArms; }
35 
36     
37     public void setRobotLegs(String legs) {
38         
39         robotLegs = legs;
40         
41     }
42     
43     public String getRobotLegs(){ return robotLegs; }
44     
45     
46     
47 }

• RobotBuilder.java

 1 // Defines the methods needed for creating parts 
 2 // for the robot
 3 
 4 public interface RobotBuilder {
 5     
 6     public void buildRobotHead();
 7     
 8     public void buildRobotTorso();
 9     
10     public void buildRobotArms();
11     
12     public void buildRobotLegs();
13     
14     public Robot getRobot();
15     
16 }

• OldRobotBuilder.java

 1 // The concrete builder class that assembles the parts 
 2 // of the finished Robot object
 3 
 4 public class OldRobotBuilder implements RobotBuilder {
 5 
 6     private Robot robot;
 7     
 8     public OldRobotBuilder() {
 9         
10         this.robot = new Robot();
11         
12     }
13     
14     public void buildRobotHead() {
15         
16         robot.setRobotHead("Tin Head");
17         
18     }
19 
20     public void buildRobotTorso() {
21         
22         robot.setRobotTorso("Tin Torso");
23         
24     }
25 
26     public void buildRobotArms() {
27         
28         robot.setRobotArms("Blowtorch Arms");
29         
30     }
31 
32     public void buildRobotLegs() {
33         
34         robot.setRobotLegs("Rollar Skates");
35         
36     }
37 
38     public Robot getRobot() {
39         
40         return this.robot;
41     }
42     
43     
44     
45 }

• RobotEngineer.java

 1 // The director / engineer class creates a Robot using the
 2 // builder interface that is defined (OldRobotBuilder)
 3 
 4 public class RobotEngineer {
 5     
 6     private RobotBuilder robotBuilder;
 7     
 8     // OldRobotBuilder specification is sent to the engineer
 9     
10     public RobotEngineer(RobotBuilder robotBuilder){
11         
12         this.robotBuilder = robotBuilder;
13         
14     }
15     
16     // Return the Robot made from the OldRobotBuilder spec
17     
18     public Robot getRobot(){
19         
20         return this.robotBuilder.getRobot();
21         
22     }
23     
24     // Execute the methods specific to the RobotBuilder 
25     // that implements RobotBuilder (OldRobotBuilder)
26     
27     public void makeRobot() {
28         
29         this.robotBuilder.buildRobotHead();
30         this.robotBuilder.buildRobotTorso();
31         this.robotBuilder.buildRobotArms();
32         this.robotBuilder.buildRobotLegs();
33         
34     }
35     
36 }

• TestRobotBuilder.java

 1 public class TestRobotBuilder {
 2     
 3     public static void main(String[] args){
 4         
 5         // Get a RobotBuilder of type OldRobotBuilder
 6         
 7         RobotBuilder oldStyleRobot = new OldRobotBuilder();
 8         
 9         // Pass the OldRobotBuilder specification to the engineer
10         
11         RobotEngineer robotEngineer = new RobotEngineer(oldStyleRobot);
12         
13         // Tell the engineer to make the Robot using the specifications
14         // of the OldRobotBuilder class
15         
16         robotEngineer.makeRobot();
17         
18         // The engineer returns the right robot based off of the spec
19         // sent to it on line 11
20         
21         Robot firstRobot = robotEngineer.getRobot();
22         
23         System.out.println("Robot Built");
24         
25         System.out.println("Robot Head Type: " + firstRobot.getRobotHead());
26         
27         System.out.println("Robot Torso Type: " + firstRobot.getRobotTorso());
28         
29         System.out.println("Robot Arm Type: " + firstRobot.getRobotArms());
30         
31         System.out.println("Robot Leg Type: " + firstRobot.getRobotLegs());
32         
33     }
34     
35 }

Prototype

What is the Prototype Design Pattern?

• Creating new objects (instances) by cloning (copying) other objects.

• Allows for adding of any subclass instance of a known super class at run time.

• When there are numerous potential classes that you want to only use if needed at runtime.

• Reduces the need for creating subclasses.

Sample Code

• Animal.java

 1 // By making this class cloneable you are telling Java
 2 // that it is ok to copy instances of this class
 3 // These instance copies have different results when
 4 // System.identityHashCode(System.identityHashCode(bike))
 5 // is called 
 6 
 7 public interface Animal extends Cloneable {
 8     
 9     public Animal makeCopy();
10     
11 }

• Sheep.java

 1 public class Sheep implements Animal {
 2 
 3     public Sheep(){
 4         
 5         System.out.println("Sheep is Made");
 6         
 7     }
 8     
 9     public Animal makeCopy() {
10         
11         System.out.println("Sheep is Being Made");
12         
13         Sheep sheepObject = null;
14         
15         try {
16             
17             // Calls the Animal super classes clone()
18             // Then casts the results to Sheep
19             
20             sheepObject = (Sheep) super.clone();
21             
22         }
23         
24         // If Animal didn't extend Cloneable this error 
25         // is thrown
26         
27         catch (CloneNotSupportedException e) {
28               
29             System.out.println("The Sheep was Turned to Mush");
30             
31             e.printStackTrace();
32               
33          }
34         
35         return sheepObject;
36     }
37     
38     public String toString(){
39         
40         return "Dolly is my Hero, Baaaaa";
41         
42     }
43     
44 }

• CloneFactory.java

 1 public class CloneFactory {
 2     
 3     // Receives any Animal, or Animal subclass and
 4     // makes a copy of it and stores it in its own
 5     // location in memory
 6     
 7     // CloneFactory has no idea what these objects are
 8     // except that they are subclasses of Animal
 9     
10     public Animal getClone(Animal animalSample) {
11         
12         // Because of Polymorphism the Sheeps makeCopy()
13         // is called here instead of Animals
14         
15         return animalSample.makeCopy();
16         
17     }
18     
19 }

• TestCloning.java

 1 public class TestCloning {
 2     
 3     public static void main(String[] args){
 4         
 5         // Handles routing makeCopy method calls to the 
 6         // right subclasses of Animal
 7         
 8         CloneFactory animalMaker = new CloneFactory();
 9         
10         // Creates a new Sheep instance
11         
12         Sheep sally = new Sheep();
13         
14         // Creates a clone of Sally and stores it in its own
15         // memory location
16         
17         Sheep clonedSheep = (Sheep) animalMaker.getClone(sally);
18         
19         // These are exact copies of each other
20         
21         System.out.println(sally);
22         
23         System.out.println(clonedSheep);
24         
25         System.out.println("Sally HashCode: " + System.identityHashCode(System.identityHashCode(sally)));
26         
27         System.out.println("Clone HashCode: " + System.identityHashCode(System.identityHashCode(clonedSheep)));
28     }
29     
30 }

 

作者:netoxi
出处:http://www.cnblogs.com/netoxi
本文版权归作者和博客园共有,欢迎转载,未经同意须保留此段声明,且在文章页面明显位置给出原文连接。欢迎指正与交流。

 

posted on 2018-12-10 10:08 netoxi 阅读(...) 评论(...) 编辑 收藏