设计模式教程(Design Patterns Tutorial)笔记之一 创建型模式(Creational Patterns)

目录

· 概述

· 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 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/netoxi/p/10088900.html

设计模式教程(Design Patterns Tutorial)笔记之一 创建型模式(Creational Patterns)...相关推荐

  1. java 23种设计模式详尽分析与实例解析_Java 23种设计模式详尽分析与实例解析之一--创建型模式...

    模式分析:在工厂方法模式中,核心的工厂类不再负责所有产品的创建,而是将具体创建工作交给子类去做.这个核心类仅仅负责给出具体工厂必须实现的接口,而不负责哪一个产品类被实例化这种细节,使得工厂方法模式允许 ...

  2. 《大话设计模式》笔记(1)——创建型模式

    1.简单工厂模式/静态工厂方法 定义:简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例. UML: PS:这个设计模式太简单了,没什么好解说的,简单来说就是通过传入一个标识到工厂类方法中,返回 ...

  3. 设计模式基于C#的实现与扩展——创建型模式(三)

    3. 抽象工厂 Provide an interface for creating familyes of related or dependent objects. 提供一个创建一系列相关或相互依赖 ...

  4. 23种设计模式介绍(一)---- 创建型模式

    由于设计模式篇幅比较大,如果在一篇文章讲完所有的设计模式的话不利于阅读.于是我把它分为三篇文章 23种设计模式介绍(一)---- 创建型模式 23种设计模式介绍(二)---- 结构型模式 23种设计模 ...

  5. 创建型模式、结构型模式和行为型模式_设计模式之创建型模式

    设计模式GOF23(Group of Four) 设计模式可分为三种类型: 创建型模式:单例模式,工厂模式,抽象工厂模式,建造者模式,原型模式. 结构型模式:适配器模式,桥接模式,装饰模式,组合模式, ...

  6. 《设计模式:可复用面向对象软件的基础》——面向对象设计原则、创建型模式(笔记)

    文章目录 二.面向对象设计原则(补充) 2.1 重新认识面向对象 2.2 面向对象设计原则 2.2.1 依赖倒置原则(DIP) 2.2.2 开放封闭原则(OCP) 2.2.3 单一职责原则(SRP) ...

  7. 《深入设计模式》笔记 -创建型模式三、生成器模式(建造者模式)

    生成器模式 亦称:建造者模式.Builder 意图 生成器模式是一种创建型设计模式, 使你能够分步骤创建复杂对象. 该模式允许你使用相同的创建代码生成不同类型和形式的对象. 问题 假设有这样一个复杂对 ...

  8. 《设计模式》读书笔记——创建型模式

    设计模式 创建模式 定义: 创建型模式抽象了实例化过程.他们帮助一个系统独立于如何创建.组合和表示它的那些对象 一个类创建型模式使用继承改变被实例化的类,而一个对象创建模式是将实例化委托给另一个对象 ...

  9. 《设计模式:可复用面向对象软件的基础》——创建型模式(2)(笔记)

    文章目录 三.创建型模式 3.4 PROTOTYPE(原型) 1.意图 补充部分 2.动机 3.适用性 4.结构 5.参与者 6.协作 7.效果 8 实现 9.代码示例 10.相关模式 3.5 SIN ...

最新文章

  1. 掌握这几种 Markdown 语法你就够了
  2. “众所周知,视频不能P”,GAN:是吗?
  3. linux下kodi没有声音的解决
  4. 盘点|2021最受开发者欢迎和最具行业影响力的文章
  5. VB.NET程序如何巧妙释放内存
  6. 产品问答 | PM该陪技术加班吗?要怎样培养技术认知?
  7. java 文件 递归_JAVA实现遍历文件夹下的所有文件(递归调用和非递归调用)
  8. html文字简单动画效果,CSS3一个简单的按钮悬停波浪文本动画效果
  9. 前端学习(3041):vue+element今日头条管理-控制用户的访问权限
  10. arm for asterisk1.8
  11. 第43课 最大公约数 动动脑 第2题《小学生C++趣味编程》
  12. python 网络编程_python网络编程示例(客户端与服务端)
  13. filestream streamreader
  14. 2017《JAVA》预备作业 计科1501班 王奕开
  15. DropDownList 递归绑定分子公司信息
  16. 简易旋转倒立摆设计报告
  17. 色彩特征提取-色彩属性HSV空间
  18. 发出商品杀手锏之SAP在途库存解决方案
  19. lh服务器注册,登不进去的人请看这里:LH服无法登录问题官方解释
  20. 微信小程序 scroll-view详解

热门文章

  1. python中等于列表的某一个值为真,python – 获取值等于特定值的列表中的所有元素...
  2. 设置Mysql5.6允许外网访问详细流程
  3. C# List的克隆
  4. Ubuntu18.04安装Docker并构建JDK1.8镜像
  5. Android开发笔记(一百五十三)OpenGL绘制三维图形的流程
  6. 启动的时候闪退_APP突然闪退怎么办?学会这五个妙招比换手机实用,看完望周知...
  7. 大数据从入门到就业的四个必备常识
  8. SQL 个版本下载地址
  9. windbg sx命令与简单应用
  10. 美利财务平台数据库架构进阶