设计模式-创建型模式:工厂模式

发布时间:2022年03月12日 阅读:693 次

1工厂模式

1.1.简单工厂模式

需求 要便于披萨种类的扩展,要便于维护

  1. 披萨的种类很多(比如 GreekPizz、CheessPizz等)

  2. 披萨的制作又prepare,bake,cut,box

  3. 完成披萨店订购功能。

传统模式

以点披萨代码为例

public OrderPizza() {
       Pizza pizza = null;
       String orderType;// 订购披萨的类型
       do {
           orderType = getType();
           if (orderType.equals("greek")) {
               pizza = new GreekPizza();
               pizza.setName("希腊披萨");
           }else if (orderType.equals("cheese")) {
               pizza = new CheesePizza();
               pizza.setName("奶酪披萨");
           }else if (orderType.equals("pepper")) {
               pizza = new PepperPizza();
               pizza.setName("胡椒披萨");
           }else {
               break;
           }
           // 输出pizza制作过程
           pizza.prepare();
           pizza.bake();
           pizza.cut();
           pizza.box();

       } while (true);
}

假如有新的Pizza种类就需要在上方加else if,此时是直接让调用者直接去创建披萨的对象。

传统方式的优缺点

1.优点是比较好理解,简单易操作

2.缺点是违反了设计模式的OCP原则,既对扩展开放,对修改关闭,既当我们给类增加新功能的时候,尽量不修改代码,或者尽可能少的修改代码

改进思路:把创建Pizza对象封装到一个类中,这样有新的Pizza种类时,只需要修改该类就可,其他有创建到Pizza对象的代码就不需要修改了。->简单工厂模式

上面的例子中运用上面的思想我们把原来的orderPizza放在工厂类来实现

public class SimpleFactory {

   // 根据OrderType返回对应的Pizza对象
   public Pizza createPizza(String orderType) {
       Pizza pizza = null;
       System.out.println("使用简单工厂模式 = " + orderType);
       if (orderType.equals("greek")) {
           pizza = new GreekPizza();
           pizza.setName("希腊披萨");
       }else if (orderType.equals("cheese")) {
           pizza = new CheesePizza();
           pizza.setName("奶酪披萨");
       }else if (orderType.equals("pepper")) {
           pizza = new PepperPizza();
           pizza.setName("胡椒披萨");
       }
       return pizza;
   }
}

对比传统模式和简单工厂模式的类图可以看出来,在OrderPizza和Pizza中间又加了一层,原来是OrderPizza依赖Pizza,后来让SampleFactory依赖Pizza。 通过封装SimpleFactory这个类,我们将OrderPizza和Pizza进行了解耦合。

不过除了对象创建在简单工厂里创建 其他工作还是在OrderPizza中进行

public class OrderPizza {
   // 定义一个简单工厂对象
   SimpleFactory simpleFactory;
   Pizza pizza = null;

   // 构造器
   public OrderPizza(SimpleFactory simpleFactory){
       setFactory(simpleFactory);
   }

   public void setFactory(SimpleFactory simpleFactory) {
       String orderType = "";// 用户输入的
       this.simpleFactory = simpleFactory;//设置简单工厂对象
       do {
           orderType = getType();
           pizza = this.simpleFactory.createPizza(orderType);
           // 输出Pizza
           if (pizza != null) {// 订购成功
               pizza.prepare();
               pizza.bake();
               pizza.cut();
               pizza.box();
           } else {
               System.out.println("订购披萨失败");
               break;
           }
       } while (true);
   }

   // 写一个方法,可以获取客户希望订购的披萨种类
   private String getType() {
       try {
           BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
           System.out.println("input pizza type:");
           return bufferedReader.readLine();
       } catch (Exception e) {
           e.printStackTrace();
           return "";
       }

   }

}

基本介绍

  1. 简单工厂模式时属于创建型模式,是工厂模式的一种。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式

  2. 简单工厂模式:定义了一个创建对象的类,由这个类来封装实例化对象的行为(代码)

  3. 在软件开发中,当我们会用到大量的创建某种,某类或者某批对象时,就会使用到工厂模式

简单工厂模式也叫静态工厂模式

1.2.工厂方法模式

需求 披萨项目新的需求:客户在北京点披萨时,可以点不同口味的披萨,比如北京的奶酪pizza、北京的胡椒pizza或者时伦敦的奶酪pizza、伦敦的胡椒pizza。

思路:使用简单工厂模式,创建不同的简单工厂类,比如BJPizzaSimpleFactory、LDPizzaSimpleFactory、等等。从当前这个案例来说,也是可以的,但是考虑到项目的规模以及软件的可维护性、可扩展性并不是特别好

思路2 使用工厂方法模式

基本介绍

工厂方法模式设计方案:将披萨项目的实例化功能抽象成抽象方法,在不同的口味点餐子类中具体实现。

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

定义抽象类

public abstract class OrderPizza {

   // 定义一个抽象方法,createPizza 让各个工厂子类自己实现
   abstract Pizza createPizza(String orderType);

   // 构造器
   public OrderPizza() {
       Pizza pizza;
       String orderType = "";// 用户输入的
       do {
           orderType = getType();
           pizza = createPizza(orderType);// 抽象方法,由工厂子类来完成
           // 输出Pizza
           if (pizza != null) {// 订购成功
               pizza.prepare();
               pizza.bake();
               pizza.cut();
               pizza.box();
           } else {
               System.out.println("订购披萨失败");
               break;
           }
       } while (true);
   }

   // 写一个方法,可以获取客户希望订购的披萨种类
   private String getType() {
       try {
           BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
           System.out.println("input pizza type:");
           return bufferedReader.readLine();
       } catch (Exception e) {
           e.printStackTrace();
           return "";
       }

   }
}

具体工厂

public class BJOrderPizza extends OrderPizza {
   @Override
   Pizza createPizza(String orderType) {
       Pizza pizza = null;
       if (orderType.equals("cheese")) {
           pizza = new BJCheesePizza();
       }else if (orderType.equals("pepper")) {
           pizza = new BJCheesePizza();
       }
       return pizza;
   }
}
public class LDOrderPizza extends OrderPizza {
   @Override
   Pizza createPizza(String orderType) {
       Pizza pizza = null;
       if (orderType.equals("cheese")) {
           pizza = new LDCheesePizza();
       }else if (orderType.equals("pepper")) {
           pizza = new LDCheesePizza();
       }
       return pizza;
   }
}

工厂方法将对象的实例化推迟到了子类,怎么理解呢? 之前的SimpleFactory在createPizza中直接就new出来了,但是在工厂方法中,我们将createPizza这个动作推迟到了OrderPizza的子类(XXOrderPizza)中才完成. 原来是由一个对象(SimpleFactory)负责所有具体类的实例化,现在实例化Pizza的责任被移到一个抽象类的子类中,此方法就如同一个工厂,所以我个人更喜欢称它为方法工厂。

1.3.抽象工厂模式

基本介绍

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

抽象工厂模式可以将简单工厂模式和工厂方法模式进行整合。

创建一个抽象工厂

// 一个抽象工厂模式的抽象层(接口)
public interface AbsFactory {
   // 让下面的工厂子类来具体实现
   Pizza createPizza(String orderType);
}

子工厂实现抽象工厂

// 这是一个工厂子类
public class BJFactory implements AbsFactory {
   @Override
   public Pizza createPizza(String orderType) {
       System.out.println("使用的是抽象工厂模式~~~~");
       Pizza pizza = null;
       if (orderType.equals("cheese")) {
           pizza = new BJCheesePizza();
       } else if (orderType.equals("pepper")) {
           pizza = new BJPepperPizza();
       }
       return pizza;
   }
}
public class LDFactory implements AbsFactory {
   @Override
   public Pizza createPizza(String orderType) {
       System.out.println("使用的是抽象工厂模式~~~~");
       Pizza pizza = null;
       if (orderType.equals("cheese")) {
           pizza = new LDCheesePizza();
       } else if (orderType.equals("pepper")) {
           pizza = new LDPepperPizza();
       }
       return pizza;
   }
}

可以创建更多的工厂子类

工厂模式 在JDK-Calendar 应用的源码分析 简单工厂模式

public static void main(String[] args) {
       Calendar cale = Calendar.getInstance();
       int year = cale.get(Calendar.YEAR);
       int month = cale.get(Calendar.MONTH) + 1;
       int day = cale.get(Calendar.DATE);
       int hour = cale.get(Calendar.HOUR_OF_DAY);
       int minute = cale.get(Calendar.MINUTE);
       int second = cale.get(Calendar.SECOND);
       System.out.println("Year: " + year);
       System.out.println("Month: " + month);
       System.out.println("Day: " + day);
       System.out.println("Hour: " + hour);
       System.out.println("Minute: " + minute);
       System.out.println("Second: " + second);
}

如图

image-20221209111532040.png

工厂模式小结


Tag:
相关文章

发表评论: