zoukankan      html  css  js  c++  java
  • [设计模式]工厂模式——抽象工厂

    简介

    根据《head first 设计模式》所述,工厂模式共有三种:静态工厂方法工厂方法、抽象工厂。本文介绍抽象工厂。

    1、定义:提供一个接口,用于创建相关或依赖对象的家族,而不需要指定具体类。

    2、满足的OO原则——依赖倒置原则:要依赖抽象,不要依赖具体类。

    3、模式结构:工厂类(抽象工厂和具体工厂)和产品类(抽象产品和具体产品)

    4、具体实现(完整代码):

    同样是做披萨系统,工厂方法是以披萨店为抽象进行设计,这样一个地区的披萨风味可以作为一个具体创建者类来实现,我们可以随意增加一个披萨风味,但是这样的话,可扩展性还是不够,因为如果新出现的一个披萨风味用了不同的原料的话,我们依然需要更改抽象产品类(Pizza)以及具体产品类进行扩充。而抽象工厂则是以原料抽象出来作为工厂进行设计,这样我们需要创建原料类(抽象工厂类),再选择不同的原料进行生产披萨即可,如果原料有所增加或者减少的话,我们只要更改原料类即可,同时这样的更改不会影响到其他的类。(而工厂方法中,如果减少原料的话,可能要更改一批涉及此原料的具体产品类,这是一个比较大的改动)

    • 抽象工厂类:定义了一个接口,所有的具体工厂都必须实现此接口,所有的具体工厂都必须实现此接口,这个接口包含一组方法用来生产产品。
    public interface PizzaIngredientFactory{
        public Dough createDough();
        public Sauce createSauce();
        public Cheese createCheese();
        public Veggies[] createVeggies();
        public Pepperoni createPepperoni();
        public Clams createClam();
    }
    • 具体工厂类:实现不同的产品家族,要创建一个产品,客户只要使用其中的一个工厂而完全不需实例化任何产品对象。
    //制作芝加哥披萨的原料工厂
    public class ChicagoPizzaIngredientFactory implements PizzaIngredientFactory{
        //面团
        public Dough createDough(){
            return new ThickCrustDough();
        }
        //酱料
        public Sauce createSauce(){
            return new PlumTomatoSauce();
        }
        //芝士
        public Cheese createCheese(){
            return new MozzarellaCheese();
        }
        //蔬菜
        public Veggies[] createVeggies(){
            Veggies veggies[] = {new Spinach(),new BlackOlives(),new EggPlant()};
            return veggies;
        }
        //意式腊肠
        public Pepperoni createPepperoni(){
            return new SlicedPepperoni();
        }
        //蛤蜊
        public Clams createClam(){
            return new FrozenClams();
        }
    }
    
    //制作纽约披萨的原料工厂
    public class NYPizzaIngredientFactory implements PizzaIngredientFactory{
        //面团
        public Dough createDough(){
            return new ThinCrustDough();
        }
        //酱料
        public Sauce createSauce(){
            return new MarinaraSauce();
        }
        //芝士
        public Cheese createCheese(){
            return new ReggianoCheese();
        }
        //蔬菜
        public Veggies[] createVeggies(){
            Veggies veggies[] = {new Garlic(),new Onion(),new Mushroom(),new RedPepper()};
            return veggies;
        }
        //意式腊肠
        public Pepperoni createPepperoni(){
            return new SlicedPepperoni();
        }
        //蛤蜊
        public Clams createClam(){
            return new FreshClams();
        }
    }
    • 抽象产品类:
    //原料:面团
    public interface Dough{
        public String toString();
    }
    
    //原料:意式腊肠
    public interface Pepperoni{
        public String toString();
    }
    • 具体产品类:
    //面团:厚面团
    public class ThickCrustDough implements Dough{
        public String toString(){
            return "Thick Crust Dough";
        }
    }
    
    //面团:薄面团
    public class ThinCrustDough implements Dough{
        public String toString(){
            return "Thin Crust Dough";
        }
    }
    
    //意式腊肠:腊肠片
    public class SlicedPepperoni implements Pepperoni{
        public String toString(){
            return "Sliced Pepperoni";
        }
    }
    • 客户端:客户的代码中只需设计抽象工厂,运行时将自动使用实际的工厂。
    //纽约风味的披萨饼
    public class NYPizzaStore extends PizzaStore{
        protected Pizza createPizza(String item){
            Pizza pizza = null;
            PizzaIngredientFactory ingredientFactory = new NYPizzaIngredientFactory();
    
            if(item.equals("cheese")){
                pizza = new CheesePizza(ingredientFactory);
                pizza.setName("New York Style Cheese Pizza");
            }else if(item.equals("veggie")){
                pizza = new VeggiePizza(ingredientFactory);
                pizza.setName("New York Style Veggie Pizza");
            }else if(item.equals("clam")){
                pizza = new ClamPizza(ingredientFactory);
                pizza.setName("New York Style Clam Pizza");
            }else if(item.equals("pepperoni")){
                pizza = new PepperoniPizza(ingredientFactory);
                pizza.setName("New York Style Pepperoni Pizza");
            }
            return pizza;
        }
    }
    
    //芝加哥风味的披萨饼
    public class ChicagoPizzaStore extends PizzaStore{
        protected Pizza createPizza(String item){
            Pizza pizza = null;
            PizzaIngredientFactory ingredientFactory = new ChicagoPizzaIngredientFactory();
    
            if(item.equals("cheese")){
                pizza = new CheesePizza(ingredientFactory);
                pizza.setName("Chicago Style Cheese Pizza");
            }else if(item.equals("veggie")){
                pizza = new VeggiePizza(ingredientFactory);
                pizza.setName("Chicago Style Veggie Pizza");
            }else if(item.equals("clam")){
                pizza = new ClamPizza(ingredientFactory);
                pizza.setName("Chicago Style Clam Pizza");
            }else if(item.equals("pepperoni")){
                pizza = new PepperoniPizza(ingredientFactory);
                pizza.setName("Chicago Style Pepperoni Pizza");
            }
            return pizza;
        }
    }

    5、抽象工厂优点:可以把一群相关的产品集合起来

    6、抽象工厂缺点:增加新种类的产品比较困难。

    7、工厂方法和抽象工厂的区别:

    • 工厂方法使用类,而抽象工厂使用对象
    • 工厂方法使用继承来创建对象,而抽象工厂通过对象的组合来创建对象。

        注:二者都负责将客户从具体类型中解耦,但方法不同:工厂方法创建对象,需要扩展一个类,并覆盖它的工厂方法;而抽象工厂提供一个用来创建一个产品家族的抽象类型,这个类型的子类定义了产品被产生的方法,要想使用这个工厂,必须先实例化它,然后将它传入一些针对抽象类型所写的代码中。

     

    参考资料

    [1] head first 设计模式

  • 相关阅读:
    通过修改manifest文件来解决Vista/Win7/Win8/win10下应用程序兼容性问题
    windows下django开发环境配置
    Django网站实例效果
    手动下载Linux安装包perf
    【Nginx】负载配置
    【VIM】常用命令
    【CentOS7】SCP服务器间传文件
    【CentOS7】目录统计du命令
    【CentOS7】安装GraphicsMagick
    【Nginx】限流配置
  • 原文地址:https://www.cnblogs.com/mj-selina/p/12488855.html
Copyright © 2011-2022 走看看