zoukankan      html  css  js  c++  java
  • 23种设计模式之工厂模式

    披萨项目为例,使用工厂模式设计

    需求:方便披萨品种扩展,便于维护,要能运行时扩展

    披萨族(组)设计类图

    假设只有原料不同,其他操作如烘焙、切割、打包相同,就把prepare方法设置为抽象方法

    一般设计如下

    //披萨族抽象类
    public abstract class Pizza {
    
        protected String name;
    
        public abstract void prepare();
    
        public void bake() {
            System.out.println(name + " baking;");
        }
    
        public void cut() {
            System.out.println(name + " cutting;");
        }
    
        public void box() {
            System.out.println(name + " boxing;");
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
    }
    Pizza族抽象类
    public class CheesePizza extends Pizza {
        public void prepare() {
            super.setName("CheesePizza");
            System.out.println(name + " preparing;");
        }
    }
    CheesePizza extends Pizza
    public class GreekPizza extends Pizza {
        public void prepare() {
            super.setName("GreekPizza");
            System.out.println(name + " preparing;");
        }
    }
    GreekPizza extends Pizza
    public class PepperPizza extends Pizza {
        public void prepare() {
            super.setName("PepperPizza");
            System.out.println(name + " preparing;");
        }
    }
    PepperPizza extends Pizza
    public class OrderPizza {
    
        public OrderPizza() {
            Pizza pizza = null;
            String orderType;
            do {
                orderType = getType();
                if (orderType.equals("cheese")) {
                    pizza = new CheesePizza();
                } else if (orderType.equals("greek")) {
                    pizza = new GreekPizza();
                } else if (orderType.equals("pepper")) {
                    pizza = new PepperPizza();
                } else {
                    break;
                }
                pizza.prepare();
                pizza.bake();
                pizza.cut();
                pizza.box();
            } while (true);
        }
    
        private String getType() {
            try {
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
                System.out.println("input pizza type:");
                String pizzaType = bufferedReader.readLine();
                return pizzaType;
            } catch (Exception ex) {
                ex.printStackTrace();
                return "";
            }
        }
    
    }
    OrderPizza 用户通过输入pizza类型来点pizza
    public class PizzaStore {
    
        public static void main(String[] args){
            OrderPizza orderPizza;
            orderPizza=new OrderPizza();
        }
    
    }
    pizza商店应用PizzaStore

    这种设计有个问题就是,如果有新品种,那就要在披萨族中添加(即实现Pizza抽象类),再在OrderPizza类中添加else if判断,同样如果删除披萨品种也要修改这两个地方

    简单工厂模式就可以把OrderPizza中创建Pizza部分(if else 变化 部分)抽出来

    1、简单工厂模式:定义了一个创建对象的类,由这个类来封装实例化对象的行为

    public class SimplePizzaFactory {
    
        public Pizza createPizza(String orderType){
            Pizza pizza=null;
            if (orderType.equals("cheese")) {
                pizza = new CheesePizza();
            } else if (orderType.equals("greek")) {
                pizza = new GreekPizza();
            } else if (orderType.equals("pepper")) {
                pizza = new PepperPizza();
            }
            return pizza;
        }
    
    }
    在OrderPizza中抽取出来的方法封装成简单工厂SimplePizzaFactory
    public class OrderPizza {
    
        SimplePizzaFactory simplePizzaFactory;
    
        public OrderPizza(SimplePizzaFactory simplePizzaFactory) {
            setFactory(simplePizzaFactory);
        }
    
        public void setFactory(SimplePizzaFactory simplePizzaFactory) {
            this.simplePizzaFactory = simplePizzaFactory;
            Pizza pizza = null;
            String orderType;
            do {
                orderType = getType();
                pizza = simplePizzaFactory.createPizza(orderType);
                pizza.prepare();
                pizza.bake();
                pizza.cut();
                pizza.box();
            } while (true);
        }
    
        private String getType() {
            try {
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
                System.out.println("input pizza type:");
                String pizzaType = bufferedReader.readLine();
                return pizzaType;
            } catch (Exception ex) {
                ex.printStackTrace();
                return "";
            }
        }
    }
    
    OrderPizza 改造后,就要使用简单工厂创建披萨实例
    OrderPizza 改造后,就要使用简单工厂创建披萨实例
    public class PizzaStore {
    
        public static void main(String[] args){
            OrderPizza orderPizza;
            orderPizza=new OrderPizza(new SimplePizzaFactory());
        }
    
    }
    PizzaStore 传入简单工厂实例对象

    这样的简单工厂设计,增删披萨品种时只需在披萨族中增删披萨种类,和修改披萨工厂中方法,不需要改OrderPizza类

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

    假如要在伦敦和纽约开披萨分店,地域特色不同,披萨工厂也就不同了,也就是工厂是可变的了,那么为了不让OrderPizza类依赖于工厂,就把制作pizza方法变为抽象方法,OrderPizza类也就是抽象类了,也就是把工厂的实现放到子类去实现,伦敦工厂实现伦敦工厂方法,纽约工厂实现纽约工厂方法

    开始有个Pizza族,现在又有个Pizza工厂族,即OrderPizza

    工厂方法模式设计方案:将披萨项目里的披萨对象实例化功能抽象成抽象方法,在不同加盟店具体实现功能

    public abstract class OrderPizza {
    
        public OrderPizza() {
            Pizza pizza = null;
            String orderType;
    
            do {
                orderType = getType();
                pizza=createPizza(orderType);
    
                pizza.prepare();
                pizza.bake();
                pizza.cut();
                pizza.box();
            } while (true);
        }
    
        public abstract Pizza createPizza(String orderType);
    
    
        private String getType() {
            try {
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
                System.out.println("input pizza type:");
                String orderType = bufferedReader.readLine();
                return orderType;
            } catch (Exception ex) {
                ex.printStackTrace();
                return "";
            }
        }
    }
    abstract class OrderPizza里面有abstract Pizza createPizza(String orderType)
    public class LDCheesePizza extends Pizza {
        public void prepare() {
            super.setName("LDCheesePizza");
            System.out.println(name+" preparing;");
        }
    }
    LDCheesePizza extends Pizza
    public class LDPepperPizza extends Pizza {
        public void prepare() {
            super.setName("LDPepperPizza");
            System.out.println(name+"preparing;");
        }
    }
    LDPepperPizza extends Pizza
    public class NYCheesePizza extends Pizza {
        public void prepare() {
            super.setName("NYCheesePizza");
            System.out.println(name+"preparing;");
        }
    }
    NYCheesePizza extends Pizza
    public class NYPepperPizza extends Pizza {
        public void prepare() {
            super.setName("NYPepperPizza");
            System.out.println(name+"preparing;");
        }
    }
    NYPepperPizza extends Pizza
    public class LDOrderPizza extends OrderPizza {
        public Pizza createPizza(String orderType) {
            Pizza pizza = null;
    
            if (orderType.equals("cheese")) {
                pizza = new LDCheesePizza();
            } else if (orderType.equals("pepper")) {
                pizza = new LDPepperPizza();
            }
            return pizza;
        }
    }
    LDOrderPizza extends OrderPizza
    public class NYOrderPizza extends OrderPizza {
        public Pizza createPizza(String orderType) {
            Pizza pizza=null;
    
            if(orderType.equals("cheese")){
                pizza=new NYCheesePizza();
            }else if(orderType.equals("pepper")){
                pizza=new NYPepperPizza();
            }
            return pizza;
        }
    }
    NYOrderPizza extends OrderPizza
    public class PizzaStore {
    
        public static void main(String[] args){
            OrderPizza orderPizza;
    //        orderPizza=new LDOrderPizza();
            orderPizza=new NYOrderPizza();
        }
    }
    PizzaStore

    简单工厂和工厂方法模式,看上去没有大的区别,但是在大型项目中,工厂方法模式就比较好,灵活性比较好点

    3、抽象工厂模式:定义了一个接口用于创建相关或有依赖关系的对象族,而无需明确指定具体类(简单工厂演化)

    public interface AbsFactory {
    
        Pizza createPizza(String orderType);
    
    }
    interface AbsFactory工厂接口
    public class LDFactory implements AbsFactory {
        public Pizza createPizza(String orderType) {
            Pizza pizza = null;
    
            if (orderType.equals("cheese")) {
                pizza = new LDCheesePizza();
            } else if (orderType.equals("pepper")) {
                pizza = new LDPepperPizza();
            }
            return pizza;
        }
    }
    LDFactory implements AbsFactory
    public class NYFactory implements AbsFactory {
        public Pizza createPizza(String orderType) {
            Pizza pizza=null;
    
            if(orderType.equals("cheese")){
                pizza=new NYCheesePizza();
            }else if(orderType.equals("pepper")){
                pizza=new NYPepperPizza();
            }
            return pizza;
        }
    }
    NYFactory implements AbsFactory
    public class OrderPizza {
    
        private AbsFactory absFactory;
    
        public OrderPizza(AbsFactory absFactory) {
            setFactory(absFactory);
        }
    
        public void setFactory(AbsFactory factory) {
            Pizza pizza = null;
            String orderType;
    
            this.absFactory = factory;
    
            do {
                orderType=getType();
                pizza=absFactory.createPizza(orderType);
    
                if(pizza!=null){
                    pizza.prepare();
                    pizza.bake();
                    pizza.cut();
                    pizza.box();
                }
            } while (true);
        }
    
        public String getType() {
            try {
                BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(System.in));
                System.out.println("input pizza type:");
                String orderType=bufferedReader.readLine();
                return orderType;
            }catch (Exception ex){
                ex.printStackTrace();
                return "";
            }
        }
    }
    OrderPizza
    public class PizzaStore {
    
        public static void main(String[] args){
            AbsFactory absFactory;
            OrderPizza orderPizza;
            absFactory=new LDFactory();
            orderPizza=new OrderPizza(absFactory);
        }
    
    }
    PizzaStore

     4、依赖抽象原则

    变量不要持有具体类的引用

    不要让类继承自具体类,要继承自抽象类或接口

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

  • 相关阅读:
    快速获取一个正数的掩码
    使用pdfbox删除pdf指定文字内容
    判断奇偶性
    RabbitMQ高级特性
    常见排序算法
    postman和postman interceptor的安装
    Linux命令
    Chrome 错误代码:ERR_UNSAFE_PORT
    IDEA运行tomcat控制台乱码
    Spring Boot 项目架构
  • 原文地址:https://www.cnblogs.com/hujiapeng/p/8075488.html
Copyright © 2011-2022 走看看