• jQuery火箭图标返回顶部代码


    为了面向接口编程,而不是面向实现编程,所以此时我么就不能再直接使用new了,因

    为当看到“new”时,我们就会想到“具体”。

    下面来看一个例子,假如你有一个披萨店,你的代码可能这么写:

     1     Pizza orderPizza(){
     2         Pizza pizza = new Pizza();
     3         
     4         pizza.prepare();
     5         pizza.bake();
     6         pizza.cut();
     7         pizza.box();
     8         
     9         return pizza;
    10     }

    但是此时你需要更多披萨类型,所以你就要修改代码,如下所示:

     1     Pizza orderPizza(String type){
     2         Pizza pizza = new Pizza();
     3 
     4         if (type.equals("cheese")) {
     5             pizza = new CheesePizza();
     6         } else if (type.equals("pepperoni")) {
     7             pizza = new PepperoniPizza();
     8         } else if (type.equals("clam")) {
     9             pizza = new ClamPizza();
    10         } else if (type.equals("veggie")) {
    11             pizza = new VeggiePizza();
    12         }
    13 
    14         pizza.prepare();
    15         pizza.bake();
    16         pizza.cut();
    17         pizza.box();
    18 
    19         return pizza;
    20     }

    但是此时由于产业竞争问题,你想加入一些其他口味的pizza或者删除某几种pizza,那么

    你就不得不修改orderPizza(String type)里的4-12行,所以随着时间的推移,这个类就必

    须一改再改,这毫无疑问是不好的!所以我们现在来把创建对象的代码封装起来,如下所

    示:

    这时我们称这个新对象(SimplePizzaFactory)为“工厂”,用来处理创建对象的细节。

    现在让我们创建一个简单的披萨工厂:

    先从工厂本身开始,封装创建对象的代码(SimplePizzaFactory.java)

     1 public class SimplePizzaFactory {
     2     public Pizza createPizza(String type) {
     3         Pizza pizza = null;
     4 
     5         if (type.equals("cheese")) {
     6             pizza = new CheesePizza();
     7         } else if (type.equals("pepperoni")) {
     8             pizza = new PepperoniPizza();
     9         } else if (type.equals("clam")) {
    10             pizza = new ClamPizza();
    11         } else if (type.equals("veggie")) {
    12             pizza = new VeggiePizza();
    13         }
    14         return pizza;
    15     }
    16 }

    重做PizzaStore(PizzaStore.java):

     1 public class PizzaStore {
     2     SimplePizzaFactory factory;
     3 
     4     public PizzaStore(SimplePizzaFactory factory) {
     5         this.factory = factory;
     6     }
     7 
     8     public Pizza orderPizza(String type) {
     9         Pizza pizza;
    10 
    11         pizza = factory.createPizza(type);
    12 
    13         pizza.prepare();
    14         pizza.bake();
    15         pizza.cut();
    16         pizza.box();
    17 
    18         return pizza;
    19     }
    20 }

    测试类(Main.java):

     1 public class Main {
     2 
     3     public static void main(String[] args) {
     4         SimplePizzaFactory factory = new SimplePizzaFactory();
     5         PizzaStore store = new PizzaStore(factory);
     6 
     7         Pizza pizza = store.orderPizza("cheese");
     8         System.out.println("We ordered a " + pizza.getName() + "
    ");
     9         System.out.println(pizza);
    10 
    11         pizza = store.orderPizza("veggie");
    12         System.out.println("We ordered a " + pizza.getName() + "
    ");
    13         System.out.println(pizza);
    14     }
    15 }

    结果展示:

    好啦,这个示例完成了,这个其实叫做简单工厂,他其实不是一个设计模式,而更像是一

    种编程习惯。这里只列举了这个项目的关键代码,至于这个简单工厂的完整代码,读者可

    到:https://github.com/Stray-Kite/Design-Pattern/tree/master/src/headfirst/designpatterns/factory/pizzas

    下载

    好了,下载聊完了简单工厂,那么让我们进入正题,聊一聊两个重量级的模式,他们都是

    工厂!

    现在我们要建立几个加盟店。

    有了这个图,你开始有一个想法啦,那就是:

    1 NYPizzaFactory nyFactory = new NYPizzaFactory();
    2 PizzaStore nyStore = new PizzaStore(nyFactory);
    3 nyStore.orderPizza("Veggie");
    4 
    5 ChicagePizzaFactory chicageFactory = new ChicagePizzaFactory();
    6 PizzaStore chicageStore = new PizzaStore(chicagoFactory);
    7 chicagoStore.orderPizza("Veggie");

    但是,你想要多一些质量控制:在推广SimpleFactory时,你发现加盟店的确是采用你的工

    厂创建披萨,但是其他部分,却开始采用他们自创的流程:烘烤的做法有些差异、不要切片

    、使用其他厂商的盒子。

    再想想这个问题,你真的希望能够建立一个框架,把加盟店和创建披萨捆绑在一起的同时又

    保持一定的弹性。

    所以开始使用框架啦:

    首先,看看PizzaStore(PizzaStore.java)所做的改变;喔嚯,变成抽象的了,也就是把创

    建对象的工作移交给子类做决定了:

     1 public abstract class PizzaStore {
     2     abstract Pizza createPizza(String item);
     3 
     4     public Pizza orderPizza(String type) {
     5         Pizza pizza = createPizza(type);
     6         System.out.println("--- Making a " + pizza.getName() + " ---");
     7         pizza.prepare();
     8         pizza.bake();
     9         pizza.cut();
    10         pizza.box();
    11         return pizza;
    12     }
    13 }

    接下来,轮到子类给PizzaStore做决定了!(NYPizzaStore.java和ChicagePizzaStore.java

    ,这是两个披萨店):

     1 public class ChicagoPizzaStore extends PizzaStore {
     2     Pizza createPizza(String item) {
     3         if (item.equals("cheese")) {
     4             return new ChicagoStyleCheesePizza();
     5         } else if (item.equals("veggie")) {
     6             return new ChicagoStyleVeggiePizza();
     7         } else if (item.equals("clam")) {
     8             return new ChicagoStyleClamPizza();
     9         } else if (item.equals("pepperoni")) {
    10             return new ChicagoStylePepperoniPizza();
    11         } else return null;
    12     }
    13 }
     1 public class NYPizzaStore extends PizzaStore{
     2     Pizza createPizza(String item) {
     3         if (item.equals("cheese")) {
     4             return new NYStyleCheesePizza();
     5         } else if (item.equals("veggie")) {
     6             return new NYStyleVeggiePizza();
     7         } else if (item.equals("clam")) {
     8             return new NYStyleClamPizza();
     9         } else if (item.equals("pepperoni")) {
    10             return new NYStylePepperoniPizza();
    11         } else return null;
    12     }
    13 }

    差点忘记了,我们还得写一个比萨本身(Pizza.java):

     1 import java.util.ArrayList;
     2 
     3 public abstract class Pizza {
     4     String name;
     5     String dough;
     6     String sauce;
     7     ArrayList<String> toppings = new ArrayList<String>();
     8 
     9     void prepare() {
    10         System.out.println("Prepare " + name);
    11         System.out.println("Tossing dough...");
    12         System.out.println("Adding sauce...");
    13         System.out.println("Adding toppings: ");
    14         for (String topping : toppings) {
    15             System.out.println("   " + topping);
    16         }
    17     }
    18 
    19     void bake() {
    20         System.out.println("Bake for 25 minutes at 350");
    21     }
    22 
    23     void cut() {
    24         System.out.println("Cut the pizza into diagonal slices");
    25     }
    26 
    27     void box() {
    28         System.out.println("Place pizza in official PizzaStore box");
    29     }
    30 
    31     public String getName() {
    32         return name;
    33     }
    34 
    35     public String toString() {
    36         StringBuffer display = new StringBuffer();
    37         display.append("---- " + name + " ----
    ");
    38         display.append(dough + "
    ");
    39         display.append(sauce + "
    ");
    40         for (String topping : toppings) {
    41             display.append(topping + "
    ");
    42         }
    43         return display.toString();
    44     }
    45 }

    然后还剩下,一些具体的子类:定义两个不同的店的芝士披萨

    NYStyleCheesePizza.java:

    1 public class NYStyleCheesePizza extends Pizza {
    2     public NYStyleCheesePizza() {
    3         name = "NY Style Sauce and Cheese Pizza";
    4         dough = "Thin Crust Dough";
    5         sauce = "Marinara Sauce";
    6 
    7         toppings.add("Grated Reggiano Cheese");
    8     }
    9 }

    ChicagoStyleCheesePizza.java:

     1 public class ChicagoStyleCheesePizza extends Pizza {
     2     public ChicagoStyleCheesePizza() {
     3         name = "Chicago Style Deep Dish Cheese Pizza";
     4         dough = "Extra Thick Crust Dough";
     5         sauce = "Plum Tomato Sauce";
     6 
     7         toppings.add("Shredded Mozzarella Cheese");
     8     }
     9 
    10     void cut() {
    11         System.out.println("Cutting the pizza into square slices");
    12     }
    13 }

    最后来一组测试类(Main.java):

     1 public class Main {
     2 
     3     public static void main(String[] args) {
     4         PizzaStore nyStore = new NYPizzaStore();
     5         PizzaStore chicagoStore = new ChicagoPizzaStore();
     6 
     7         Pizza pizza = nyStore.orderPizza("cheese");
     8         System.out.println("Ethan ordered a " + pizza.getName() + "
    ");
     9 
    10         pizza = chicagoStore.orderPizza("cheese");
    11         System.out.println("Joel ordered a " + pizza.getName() + "
    ");
    12 
    13         pizza = nyStore.orderPizza("clam");
    14         System.out.println("Ethan ordered a " + pizza.getName() + "
    ");
    15 
    16         pizza = chicagoStore.orderPizza("clam");
    17         System.out.println("Joel ordered a " + pizza.getName() + "
    ");
    18 
    19         pizza = nyStore.orderPizza("pepperoni");
    20         System.out.println("Ethan ordered a " + pizza.getName() + "
    ");
    21 
    22         pizza = chicagoStore.orderPizza("pepperoni");
    23         System.out.println("Joel ordered a " + pizza.getName() + "
    ");
    24 
    25         pizza = nyStore.orderPizza("veggie");
    26         System.out.println("Ethan ordered a " + pizza.getName() + "
    ");
    27 
    28         pizza = chicagoStore.orderPizza("veggie");
    29         System.out.println("Joel ordered a " + pizza.getName() + "
    ");
    30     }
    31 }

    结果展示(部分结果)

    此段代码地址:

              https://github.com/Stray-Kite/Design-Pattern/tree/master/src/headfirst/designpatterns/factory/pizzafm

    好了,现在然我们看一下工厂模式的定义吧!

    工厂模式:定义一个创建对象的接口,但由子类决定要实例化的是哪一个。工厂方法让类把

    实例化推迟到了子类。

    重点:简单工厂和工厂方法的区别:

                     子类的确看起来很像简单工厂。简单工程把全部的事情,在一个地方都处理完了,然而工厂方

              法却是创建了一个框架,让子类决定要如何实现。比方说,在工厂方法中,orderPizza()方法提供了

              一个一般的框架,以便创建披萨,orderPizza()方法依赖工厂方法创建具体类,并制造出实际的披萨

              。可通过继承PizzaStore()类,决定实际制造出的披萨是什么。简单工厂的做法,可以将对象创建封

              装起来,但是简单工厂不具备工厂方法的弹性,因为简单工程不能变更正在创建的产品。

    未完待续......

  • 相关阅读:
    FreeMarker常用语法学习
    Oracle如何实现创建数据库、备份数据库及数据导出导入的一条龙操作-------sql方式
    Oracle Partition 分区详细总结
    oracle 当中,(+)是什么意思
    SQL中EXISTS的用法
    JS return false 与 return true
    Merge into语句用法及其效率问题
    几种设置表单元素中文本输入框不可编辑的方法
    Oracle存储过程基本语法
    UNIX网络编程——Socket粘包问题
  • 原文地址:https://www.cnblogs.com/Trojan00/p/11320794.html
Copyright © 2020-2023  润新知