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动作放入一个工厂的方法中,并返回,即变量不要持有具体类的引用。  

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

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

原文地址:https://www.cnblogs.com/qmillet/p/12112037.html