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

      为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。

    抽象工厂模式与工厂方法模式的区别

      抽象工厂模式是工厂方法模式的升级版本,他用来创建一组相关或者相互依赖的对象。他与工厂方法模式的区别就在于,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式则是针对的多个产品等级结构。在编程中,通常一个产品结构,表现为一个接口或者抽象类,也就是说,工厂方法模式提供的所有产品都是衍生自同一个接口或抽象类,而抽象工厂模式所提供的产品则是衍生自不同的接口或抽象类
      在抽象工厂模式中,有一个产品族的概念:所谓的产品族,是指位于不同产品等级结构中功能相关联的产品组成的家族。抽象工厂模式所提供的一系列产品就组成一个产品族;而工厂方法提供的一系列产品称为一个等级结构。我们依然拿生产汽车的例子来说明他们之间的区别。

    优点

      抽象工厂模式将具体产品的创建延迟到具体工厂的子类中,这样将对象的创建封装起来,可以减少客户端与具体产品类之间的依赖,从而使系统耦合度低,这样更有利于后期的维护和扩展,这真是抽象工厂模式的优点所在,然后抽象模式同时也存在不足的地方

    缺点

      抽象工厂模式很难支持新种类产品的变化。这是因为抽象工厂接口中已经确定了可以被创建的产品集合,如果需要添加新产品,此时就必须去修改抽象工厂的接口,这样就涉及到抽象工厂类的以及所有子类的改变,这样也就违背了“开发——封闭”原则

    实现

      借助女娲造人的过程添加新的物种等级水果,然后根据地域造不同的人。类图如下:

    人类接口:

    package com.lidaming.design03.abstractfactory;
    
    public interface IHuman {
        void color();
        
    }
    View Code

    人类的实现类:

    package com.lidaming.design03.abstractfactory;
    
    public class WhiteHuman implements IHuman {
    
        public void color() {
            System.out.println("this is white");
    
        }
    }
    View Code
    package com.lidaming.design03.abstractfactory;
    
    public class YellowHuman implements IHuman {
    
        public void color() {
            System.out.println("this is yellow");
    
        }
    
    }
    View Code

    水果接口:

    package com.lidaming.design03.abstractfactory;
    
    public interface IFruit {
        void locate();
    }
    View Code

    水果的实现类:

    package com.lidaming.design03.abstractfactory;
    
    public class Apple implements IFruit {
    
        public void locate() {
            System.out.println("grow on the tree");
        }
    
    }
    View Code
    package com.lidaming.design03.abstractfactory;
    
    public class Orange implements IFruit {
    
        public void locate() {
            // TODO Auto-generated method stub
            System.out.println("grow on the tree");
        }
    
    }
    View Code

    抽象工厂:

    package com.lidaming.design03.abstractfactory;
    
    public interface AbstractFactory {
        IHuman createHuman();
    
        IFruit createFruite();
    }
    View Code

    具体工厂的实现:

    package com.lidaming.design03.abstractfactory;
    
    public class AsiaFactory implements AbstractFactory {
    
        public IHuman createHuman() {
            
            try {
                return YellowHuman.class.newInstance();
            } catch (InstantiationException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return null;
        }
    
        public IFruit createFruite() {
            try {
                return Apple.class.newInstance();
            } catch (InstantiationException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return null;
        }
    
    }
    View Code
    package com.lidaming.design03.abstractfactory;
    
    public class Europe implements AbstractFactory {
    
        public IHuman createHuman() {
            try {
                return WhiteHuman.class.newInstance();
            } catch (InstantiationException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return null;
        }
    
        public IFruit createFruite() {
            try {
                return Orange.class.newInstance();
            } catch (InstantiationException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return null;
        }
    
    }
    View Code

    场景类:

    package com.lidaming.design03.abstractfactory;
    
    public class Client {
        public static void main(String[] args) {
            AbstractFactory factory = new AsiaFactory();
            IHuman human = factory.createHuman();
            human.color();
            IFruit fruit = factory.createFruite();
            fruit.locate();
    
            factory = new Europe();
            human = factory.createHuman();
            human.color();
            fruit = factory.createFruite();
            fruit.locate();
        }
    }
    View Code

    分析

    当抽象工厂面对扩展新的产品等级的时候,如:造动物的时候!

      需要修改抽象工厂,具体工厂(违反“开放封闭原则”),至于维护成本,更是无法评估

    总结

      无论是简单工厂模式,工厂方法模式,还是抽象工厂模式,他们都属于工厂模式,在形式和特点上也是极为相似的,他们的最终目的都是为了解耦。在使用时,我们不必去在意这个模式到底工厂方法模式还是抽象工厂模式,因为他们之间的演变常常是令人琢磨不透的。经常你会发现,明明使用的工厂方法模式,当新需求来临,稍加修改,加入了一个新方法后,由于类中的产品构成了不同等级结构中的产品族,它就变成抽象工厂模式了;而对于抽象工厂模式,当减少一个方法使的提供的产品不再构成产品族之后,它就演变成了工厂方法模式。
      所以,在使用工厂模式时,只需要关心降低耦合度的目的是否达到了。

    参考:

    http://blog.csdn.net/zhengzhb/article/details/7359385

    http://blog.jobbole.com/78067/

  • 相关阅读:
    javascript/jquery操作cookie
    更改IE/FireFox查看源代码的默认编辑器,比如notepad++
    javascript refresh page 几种页面刷新的方法
    C# Enum,Int,String的互相转换 枚举转换
    js中两个感叹号的作用
    JQuery操作iframe
    JQuery判断一个元素下面是否有内容或者有某个标签
    Meta标签详解
    五一放假回校,真爽
    ASP.NET错误处理(一)摘自MSDN
  • 原文地址:https://www.cnblogs.com/hpuCode/p/5382066.html
Copyright © 2011-2022 走看看