• 设计模式教程(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("
    ");
    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 + "
    ");
    13         
    14         EnemyShip theBoss = MakeUFOs.orderTheShip("UFO BOSS");
    15         System.out.println(theBoss + "
    ");
    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
    本文版权归作者和博客园共有,欢迎转载,未经同意须保留此段声明,且在文章页面明显位置给出原文连接。欢迎指正与交流。

  • 相关阅读:
    VMware安装Centos7超详细过程
    Linux部署Web项目
    Entity Framework快速入门IQueryable与IEnumberable的区别
    ASP.NET MVC3中的路由系统(Routes)
    C# Lambda表达式概述
    WCF大数据量传输解决要点
    div滚动条样式设计
    ASP.NET MVC 自定义路由
    C# Lambda表达式学习笔记
    C# 操作excel
  • 原文地址:https://www.cnblogs.com/netoxi/p/10088900.html
Copyright © 2020-2023  润新知