• 设计模式之工厂模式


      工厂(Factory)模式本质上就是封装对象的创建

      工厂模式大致分为:简单工厂静态工厂工厂方法抽象工厂模式

      严格意义上来说,简单工厂和静态工厂并不是一种设计模式,反而比较像一种编程习惯。但由于经常被使用,所以很多开发人员把这个编程习惯认为是“工厂模式”。

    1.简单工厂

      1.1 简单工厂角色

    public class PizzaFactory {
        
        public static final String CHEESE_PIZZA = "Cheese";
        public static final String GREEK_PIZZA = "Greek";
        
        public Pizza createPizza(String type){
            if(CHEESE_PIZZA.equals(type)){
                return new CheesePizza();
            }else if(GREEK_PIZZA.equals(type)){
                return new GreekPizza();
            }
            return null;
        }
    }

      1.2 Dome

    public class PizzaDemo {
    
        public static void main(String[] args) {
            PizzaFactory factory = new PizzaFactory();
            factory.createPizza(PizzaFactory.CHEESE_PIZZA);
        }
    }

    【每一次创建创建PizzaFactory对象都是为了调用createPizza(),因此可以采用静态方法的方式,减少对PizzaFactory对象的创建。此模式被称为静态工厂模式】

    2. 静态工厂模式

      2.1 静态工厂角色

    public class PizzaFactory {
        
        public static final String CHEESE_PIZZA = "Cheese";
        public static final String GREEK_PIZZA = "Greek";
        
        public static Pizza createPizza(String type){
            if(CHEESE_PIZZA.equals(type)){
                return new CheesePizza();
            }else if(GREEK_PIZZA.equals(type)){
                return new GreekPizza();
            }
            return null;
        }
    }

      2.2 Demo

    public class PizzaDemo {
    
        public static void main(String[] args) {
            PizzaFactory.createPizza(PizzaFactory.CHEESE_PIZZA);
        }
    }

    【每添加一种新的品种,都需要对工厂类进行修改,这违背了设计模式中的开放-封闭原则(对扩展开放,对修改封闭),因此有了工厂方法】

    3. 工厂方法

      针对一个产品,通过继承的方式,让子类创建对象。如果需要添加新的品种,只需要创建新的子类。

      3.1 超类

    public abstract class PizzaStore {
    
        public abstract Pizza createPizza();
        
        public Pizza orderPizza(){
            // let sub-class decide to which pizza will be created.
            Pizza pizza = createPizza();
            pizza.make();
            pizza.bake();
            pizza.cut();   
            pizza.box();
            return pizza;
        }
        
    }

      3.2 子类

    public class CheesePizzaStore extends PizzaStore {
        
        @Override
        public Pizza createPizza(){
            return new CheesePizza();
        }
    
    }

      3.3 Demo

    public class PizzaDemo {
    
        public static void main(String[] args) {
            PizzaStore store = new CheesePizzaStore();
            store.orderPizza();
        }
    }

    【当需要创建多个产品(即:产品族)的时候,工厂方法已经无法满足需求。针对这种情况,产生了抽象工厂模式】

    4. 抽象工厂模式

      抽象工厂针对的是一个产品族,通过组合的方式创建对象。

      4.1 抽象工厂角色【声明产品】

    //Two product: Apple & Banana

    public
    interface FruitFactory { public Fruit getApple(); public Fruit getBanana(); }

      4.2 具体的工厂角色【实例化某个产品族族中的所有产品】

    public class NorthFruitFactory implements FruitFactory {
    
        @Override
        public Fruit getApple() {
            return new NorthApple();
        }
    
        @Override
        public Fruit getBanana() {
            return new NorthBanana();
        }
    
    }
    public class SouthFruitFactory implements FruitFactory {
    
        @Override
        public Fruit getApple() {
            return new SouthApple();
        }
    
        @Override
        public Fruit getBanana() {
            return new SouthBanana();
        }
    
    }

      4.3 Dome

    public class Demo {
    
        public static void main(String[] args) {
            FruitFactory factory = new NorthFruitFactory();
            factory.getApple();
            factory.getBanana();
            
            System.out.println("---------------------------");
            
            factory = new SouthFruitFactory();
            factory.getApple();
            factory.getBanana();
        }
    }

       4.4 备注

            当需要添加一个新的产品,就必须修改接口,并且需要修改每个接口的实现

    5.参考资料

      5.1 O'Reilly《Head First设计模式》

      5.2 北风网在线培训《策略模式》

  • 相关阅读:
    .net 关于路径的总结
    asp.net Base64加解密
    asp.net中的<% %>,<%= %>,<%# %><%$ %>的使用
    asp.net Swiper 轮播动画
    ASP.NET中Literal控件的使用方法(用于向网页中动态添加内容)
    asp.net 获取表单中控件的值
    rgb值转换成16进制
    关于background全解
    移动端的性能陷阱
    原生JS实现雪花特效
  • 原文地址:https://www.cnblogs.com/BlueStarWei/p/10510214.html
Copyright © 2020-2023  润新知