• 2.工厂模式


    https://blog.csdn.net/likun_li/article/details/90021165

    【案例】 点单披萨项目(披萨种类,制作过程,订购),实现点单功能

    Pizza类

     1 //将Pizza 类做成抽象
     2 public abstract class Pizza {
     3     protected String name; //名字
     4     //准备原材料, 不同的披萨不一样,因此,我们做成抽象方法
     5     public abstract void prepare();
     6     public void bake() {
     7         System.out.println(name + " baking;");
     8     }
     9     public void cut() {
    10         System.out.println(name + " cutting;");
    11     }
    12     //打包
    13     public void box() {
    14         System.out.println(name + " boxing;");
    15     }
    16     public void setName(String name) {
    17         this.name = name;
    18     }
    19 }

    点单功能类

     1 public class OrderPizza {
     2      //构造器
     3     public OrderPizza() {
     4         Pizza pizza = null;
     5         String orderType; // 订购披萨的类型
     6         do {
     7             orderType = getType();
     8             if (orderType.equals("greek")) {
     9                 pizza = new GreekPizza();
    10                 pizza.setName(" 希腊披萨 ");
    11             } else if (orderType.equals("cheese")) {
    12                 pizza = new CheesePizza();
    13                 pizza.setName(" 奶酪披萨 ");
    14             } else if (orderType.equals("pepper")) {
    15                 pizza = new PepperPizza();
    16                 pizza.setName("胡椒披萨");
    17             } else {
    18                 break;
    19             }
    20             //输出pizza 制作过程
    21             pizza.prepare();
    22             pizza.bake();
    23             pizza.cut();
    24             pizza.box();
    25 
    26         } while (true);
    27     }
    28 }

       弊端:违反ocp原则,即对拓展开放,对修改关闭。当我们增加功能时,尽量不修改代码绘者少修改。而OrderPizza类中当增加一种Pizza字类时,则需要修改所有OrderPizza类(OrderPizza只是一个代称,可能有很多跟此功能一样的类)中对Pizza种类判断的代码。

    1.简单工厂模式

      简单工厂模式属于创建型模式,是工厂模式的一种。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式定义了一个创建对象的类,由这个类来封装实例化对象的行为。在软件开发中,当我们会用到大量的创建某种、某类对象时,就会使用到工厂模式。

      把创建Pizza对象封装到一个类中,这样我们有新的Pizza种类的时候,只需要修改此类即可,其他创建Pizza对象的代码就不需要修改了。

     1 //简单工厂类
     2 public class SimpleFactory {
     3 
     4     //更加orderType 返回对应的Pizza 对象
     5     public Pizza createPizza(String orderType) {
     6 
     7         Pizza pizza = null;
     8 
     9         System.out.println("使用简单工厂模式");
    10         if (orderType.equals("greek")) {
    11             pizza = new GreekPizza();
    12             pizza.setName(" 希腊披萨 ");
    13         } else if (orderType.equals("cheese")) {
    14             pizza = new CheesePizza();
    15             pizza.setName(" 奶酪披萨 ");
    16         } else if (orderType.equals("pepper")) {
    17             pizza = new PepperPizza();
    18             pizza.setName("胡椒披萨");
    19         }
    20         
    21         return pizza;
    22     }
    23 
    24 }
    SimpleFactory
     1 public class OrderPizza {
     2     //定义一个简单工厂对象
     3     SimpleFactory simpleFactory;
     4     Pizza pizza = null;
     5     
     6     //构造器
     7     public OrderPizza(SimpleFactory simpleFactory) {
     8         setFactory(simpleFactory);
     9     }
    10     
    11     public void setFactory(SimpleFactory simpleFactory) {
    12         String orderType = ""; //用户输入的
    13         
    14         this.simpleFactory = simpleFactory; //设置简单工厂对象
    15         
    16         do {
    17             orderType = getType(); 
    18             pizza = this.simpleFactory.createPizza(orderType);
    19             
    20             //输出pizza
    21             if(pizza != null) { //订购成功
    22                 pizza.prepare();
    23                 pizza.bake();
    24                 pizza.cut();
    25                 pizza.box();
    26             } else {
    27                 System.out.println(" 订购披萨失败 ");
    28                 break;
    29             }
    30         }while(true);
    31     }
    32     
    33     // 写一个方法,可以获取客户希望订购的披萨种类
    34     private String getType() {
    35         try {
    36             BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
    37             System.out.println("input pizza 种类:");
    38             String str = strin.readLine();
    39             return str;
    40         } catch (IOException e) {
    41             e.printStackTrace();
    42             return "";
    43         }
    44     }
    OrderPizza
    1 //相当于一个客户端,发出订购
    2 public class PizzaStore {
    3     public static void main(String[] args) {
    4         //使用简单工厂模式
    5         new OrderPizza(new SimpleFactory());
    6         System.out.println("~~退出程序~~");
    7     }
    8 
    9 }
    客户端

     2.工厂方法模式

    【新需求】每种Pizza有不同口味,客户可以点单可以选择不同的口味。这是可以使用创建不同的简单工厂类生产不同的口味,但是维护性和拓展性不好。此时可使用工厂方法模式。将披萨项目的实例化功能抽象成抽象方法,在不同口味点餐子类中具体实现。

      工厂方法模式:定义了一个创建对象的抽象方法,由子类决定要实例化的类。工厂方法模式将对象的实例化推迟到子类

     1 public abstract class OrderPizza {
     2 
     3     //定义一个抽象方法,createPizza , 让各个工厂子类自己实现
     4     abstract Pizza createPizza(String orderType);
     5     
     6     // 构造器
     7     public OrderPizza() {
     8         Pizza pizza = null;
     9         String orderType; // 订购披萨的类型
    10         do {
    11             orderType = getType();
    12             pizza = createPizza(orderType); //抽象方法,由工厂子类完成
    13             //输出pizza 制作过程
    14             pizza.prepare();
    15             pizza.bake();
    16             pizza.cut();
    17             pizza.box();
    18             
    19         } while (true);
    20     }
    21     
    22     // 写一个方法,可以获取客户希望订购的披萨种类
    23     private String getType() {
    24         try {
    25             BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
    26             System.out.println("input pizza 种类:");
    27             String str = strin.readLine();
    28             return str;
    29         } catch (IOException e) {
    30             e.printStackTrace();
    31             return "";
    32         }
    33     }
    34 }
    OrderPizza
     1 public class BJOrderPizza extends OrderPizza {
     2     
     3     @Override
     4     Pizza createPizza(String orderType) {
     5     
     6         Pizza pizza = null;
     7         if(orderType.equals("cheese")) {
     8             pizza = new BJCheesePizza();
     9         } else if (orderType.equals("pepper")) {
    10             pizza = new BJPepperPizza();
    11         }
    12         // TODO Auto-generated method stub
    13         return pizza;
    14     }
    15 }
    BJOrderPizza
     1 public class LDOrderPizza extends OrderPizza {
     2     @Override
     3     Pizza createPizza(String orderType) {
     4     
     5         Pizza pizza = null;
     6         if(orderType.equals("cheese")) {
     7             pizza = new LDCheesePizza();
     8         } else if (orderType.equals("pepper")) {
     9             pizza = new LDPepperPizza();
    10         }
    11         // TODO Auto-generated method stub
    12         return pizza;
    13     }
    14 }
    LDOrderPizza

    3.抽象工厂模式

      抽象工厂模式定义了一个interface用于创建相关或有依赖关系的对象簇,而无需指明具体的类。

      抽象工厂模式可以将简单工厂模式和工厂方法模式整合,从设计层面上看,抽象工厂模式就是简单工厂模式的进一步抽象。将工厂抽象成两层:AbsFactory抽象工厂和具体实现的工厂类。程序员可以根据创建对象类型使用对应的工厂子类。这样就将简单的工厂类变成了工厂簇,利于维护扩展。

    1 //一个抽象工厂模式的抽象层(接口)
    2 public interface AbsFactory {
    3     //让下面的工厂子类来 具体实现
    4     public Pizza createPizza(String orderType);
    5 }
    AbsFactory
     1 public class LDFactory implements AbsFactory {
     2     @Override
     3     public Pizza createPizza(String orderType) {
     4         System.out.println("~使用的是抽象工厂模式~");
     5         Pizza pizza = null;
     6         if (orderType.equals("cheese")) {
     7             pizza = new LDCheesePizza();
     8         } else if (orderType.equals("pepper")) {
     9             pizza = new LDPepperPizza();
    10         }
    11         return pizza;
    12     }
    13 }
    LDFactory
     1 //这是工厂子类
     2 public class BJFactory implements AbsFactory {
     3     @Override
     4     public Pizza createPizza(String orderType) {
     5         System.out.println("~使用的是抽象工厂模式~");
     6         // TODO Auto-generated method stub
     7         Pizza pizza = null;
     8         if(orderType.equals("cheese")) {
     9             pizza = new BJCheesePizza();
    10         } else if (orderType.equals("pepper")){
    11             pizza = new BJPepperPizza();
    12         }
    13         return pizza;
    14     }
    15 }
    BJFactory
     1 public class OrderPizza {
     2     AbsFactory factory;
     3     // 构造器
     4     public OrderPizza(AbsFactory factory) {
     5         setFactory(factory);
     6     }
     7 
     8     private void setFactory(AbsFactory factory) {
     9         Pizza pizza = null;
    10         String orderType = ""; // 用户输入
    11         this.factory = factory;
    12         do {
    13             orderType = getType();
    14             // factory 可能是北京的工厂子类,也可能是伦敦的工厂子类
    15             pizza = factory.createPizza(orderType);
    16             if (pizza != null) { // 订购ok
    17                 pizza.prepare();
    18                 pizza.bake();
    19                 pizza.cut();
    20                 pizza.box();
    21             } else {
    22                 System.out.println("订购失败");
    23                 break;
    24             }
    25         } while (true);
    26     }
    27 
    28     // 写一个方法,可以获取客户希望订购的披萨种类
    29     private String getType() {
    30         try {
    31             BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
    32             System.out.println("input pizza 种类:");
    33             String str = strin.readLine();
    34             return str;
    35         } catch (IOException e) {
    36             e.printStackTrace();
    37             return "";
    38         }
    39     }
    40 }
    OrderPizza
    1 public class PizzaStore {
    2     public static void main(String[] args) {
    3         // TODO Auto-generated method stub
    4         //new OrderPizza(new BJFactory());
    5         new OrderPizza(new LDFactory());
    6     }
    7 }
    客户端

    4.小结

    工厂模式意义:将实例化对象的代码提取出来,放到一个类中统一管理和维护,达到和主项目的依赖关系的解耦。从而提高项目的扩展性和维护性。

    Tips:创建对象实例不要直接new类,而是把这个new动作放入一个工厂的方法中,并返回,即变量不要持有具体类的引用。  

         不要让类直接继承具体类,而是继承抽象类或实现接口。

         不要覆盖类中已经实现的方法。

  • 相关阅读:
    表单验证
    obs 之 OBSObj
    rtmp流媒体协议分析(h264、aac)
    lintcode 508.Wiggle Sort
    SVN备份批处理文件
    防火墙没关导致 ORA-12541: TNS: 无监听程序
    [转]window10系统安装oracle11g时遇到INS-13001环境不满足最低要求
    关键驱动因素、约束和浮动因素
    C#之虚函数 非常清晰全面的讲解
    今天有个朋友问我抽象方法和接口的区别,为了解释清楚这个事情,我在网上看到一篇文章讲的非常好给大家分享一下,也感谢原作者的付出
  • 原文地址:https://www.cnblogs.com/qmillet/p/12112037.html
Copyright © 2020-2023  润新知