MyException - 我的异常网
当前位置:我的异常网» 设计模式 » 设计模式-抽像工场

设计模式-抽像工场

www.MyException.Cn  网友分享于:2013-09-28  浏览:0次
设计模式-抽像工厂

 一。概念

  提供一个创建一系列相关或相互依赖对像的接口,而无需指定它们具体的类。

二。模式动机

  这一系列对像之间是相互依赖的,相当于一个产品族

 三。模式的结构

  

  通过上图我们可以清楚的看到抽像工厂模式包括以下4个角色:

  1.抽像工厂角色(AbstractFactory):抽像工厂模式的核心,与具体的商业逻辑无关,通常是一个JAVA接口或者抽像类。

  2.具体工厂角色(Concrete Factory):该角色通常与具体的商业逻辑紧密相关,该角色里面的工厂方法依据具体的商业逻辑实例化具体的产品并返回,客户端通过该角色并调用该角色的工厂方法,获得具体产品对像,该角色通常都是一个具体JAVA类来承担。

  3.抽像产品角色:担任这个角色的类是工厂方法模式所创建的产品的父类,或者他们共同拥有的接口,通常是一个接口或者抽像类。

  4.具体产品角色:抽像工厂模式所创建的任何产品都是这个角色的实例,有一个具体JAVA类来承担。

  样例代码如下:

   

public class AbstractProductA 
{
   
   /**
    * @roseuid 59AC05990327
    */
   public AbstractProductA() 
   {
    
   }
}


public class ProductA1 extends AbstractProductA 
{
   
   /**
    * @roseuid 59AC05990359
    */
   public ProductA1() 
   {
    
   }
}


public class ProductA2 extends AbstractProductA 
{
   
   /**
    * @roseuid 59AC05990381
    */
   public ProductA2() 
   {
    
   }
}

public class AbstractProductB 
{
   
   /**
    * @roseuid 59AC059903BA
    */
   public AbstractProductB() 
   {
    
   }
}

public class ProductB1 extends AbstractProductB 
{
   
   /**
    * @roseuid 59AC059A001F
    */
   public ProductB1() 
   {
    
   }
}

public class ProductB2 extends AbstractProductB 
{
   
   /**
    * @roseuid 59AC059A0049
    */
   public ProductB2() 
   {
    
   }
}



public abstract class AbstractFactory 
{
   
   /**
    * @roseuid 59AC05690005
    */
   public AbstractFactory() 
   {
    
   }
   
   /**
    * @return AbstractProductA
    * @roseuid 59ABFB0103BE
    */
   public  Abstract  AbstractProductA createProductA() ;
   
   
   /**
    * @return AbstractProductB
    * @roseuid 59ABFB3B029D
    */
   public Abstract AbstractProductB createProductB() ;
}


public class ConcreteFactory1 extends AbstractFactory 
{
   
   /**
    * @roseuid 59AC057A02FC
    */
   public ConcreteFactory1() 
   {
    
   }
   
   /**
    * @return AbstractProductA
    * @roseuid 59ABFB9C00C9
    */
   public AbstractProductA createProductA() 
   {
        return new ProductA1();
   }
   
   /**
    * @return AbstractProductB
    * @roseuid 59ABFBA30011
    */
   public AbstractProductB createProductB() 
   {
        return new ProductB1();
   }
}




public class ConcreteFactory2 extends AbstractFactory 
{
   
   /**
    * @roseuid 59AC057A02C0
    */
   public ConcreteFactory2() 
   {
    
   }
   
   /**
    * @return AbstractProductA
    * @roseuid 59ABFCC701B9
    */
   public AbstractProductA createProductA() 
   {
        return new ProductA2();
   }
   
   /**
    * @return AbstractProductB
    * @roseuid 59ABFCC9001F
    */
   public AbstractProductB createProductB() 
   {
        return new ProductB2();
   }
}

 

public class Client 
{
   
   
   /**
    * @roseuid 59AC055700AB
    */
   public Client() 
   {
    
   }

   public static void main(String[] args){
           AbstractFactory theAbstractFactory;
        AbstractProductA theAbstractProductA;
        AbstractProductB theAbstractProductB;

        theAbstractFactory=new ConcreteFactory1();

        theAbstractProductA=theAbstractFactory.createProductA();
        theAbstractProductB=theAbstractFactory.createProductB();
  
   }
}

   跟据上面的模式结构图我们对“提供一个创建一系列相关或相互依赖对像的接口,而无需指定它们具体的类”  进行一个简要的分析:

       1.相关相互依赖对像,在这里面ProductA1的实例和ProductB1的实例就是一组相互关联(如内在的关联关系)或相互依赖(如整体和部分)关系,依据业务逻辑,ProductA1

 只能和同一产品等级结构AbstractProductB下的ProductB1相互关联而无法与ProductB2关联在一起。

  2.提供一个创建一系列相关或相互依赖对像的接口,而无需指定它们具体的类,这里面的接口,即为结构图中的AbstractProductA和AbstractProductB,客户端只依赖这些产品的接口进行编程,而不依赖于具体实现,即符合依赖倒转原则。“无需指定它们具体的类”  即客户端(client)跟本就不知道ProductA1、ProductA2、ProductB1和ProductB2的存在,客户端只需要调用具体工厂的工厂方法即可返回具体的产品实例。

 

四。模式样例

  我们接着工厂方法模式中的样例进行进一步分析,现在这个生产轮胎的工厂已经不满足只生产轿车轮胎了,他现已经引入了发动机的生产线(EngineLine)、车门(DoorLine)等整个车的各种零部件生产线,可以说他现在可以轻松制造一部Car,但是也并非所有的Car都能制造,比如他现只能生产benz和BMW两种类型的车(这样的工厂也够NX了),比如现在一部车只包含车轮胎、车门和发动机(当然肯定不止这么多),那么这个工厂就可以跟据客户的要求生产BMW和benz车了,如下图:

 

  代码如下:

  

public interface Door {
    public void open();
    public void close();
}
public class BenzDoor implements Door {

    @Override
    public void open() {
        System.out.println("奔驰车门开");
    }

    @Override
    public void close() {
        System.out.println("奔驰车门关");
    }
}
public class BmwDoor implements Door {

    @Override
    public void open() {
        System.out.println("宝马车门开");
    }

    @Override
    public void close() {
        System.out.println("宝马车门关");
    }

}
public interface Tire {
    public void getColor();
    public void getLife();
    public void getWidth();
}
public class BenzTire implements Tire {

    @Override
    public void getColor() {
        System.out.println("benz车color");
    }

    @Override
    public void getLife() {
        System.out.println("benz车life");
    }

    @Override
    public void getWidth() {
        System.out.println("benz车width");
    }
}
public class BmwTire implements Tire {

    @Override
    public void getColor() {
        System.out.println("bmw车color");
    }

    @Override
    public void getLife() {
        System.out.println("bmw车life");
    }

    @Override
    public void getWidth() {
        System.out.println("bmw车width");
    }

}
public interface Engine {
    public void start();

    public void stop();

}
public class BenzEngine implements Engine {

    @Override
    public void start() {
        System.out.println("benz车start");

    }

    @Override
    public void stop() {
        System.out.println("benz车stop");

    }

}
public class BmwEngine implements Engine {

    @Override
    public void start() {
        System.out.println("bmw车start");

    }

    @Override
    public void stop() {
        System.out.println("bmw车stop");

    }

}
public interface PartFactory {
    public Door createDoor();

    public Tire createTire();

    public Engine createEngine();

}
public class BenzPartFactory implements PartFactory {

    @Override
    public Door createDoor() {
        return new BenzDoor();
    }

    @Override
    public Tire createTire() {
        return new BenzTire();
    }

    @Override
    public Engine createEngine() {
        return new BenzEngine();
    }

}
public class BmwPartFactory implements PartFactory {

    @Override
    public Door createDoor() {
        return new BmwDoor();
    }

    @Override
    public Tire createTire() {
        return new BmwTire();
    }

    @Override
    public Engine createEngine() {
        return new BmwEngine();
    }

}
public class Car {
    private Door door;
    private Engine engine;
    private Tire tire;

    public Car(PartFactory factory) {
        this.door = factory.createDoor();
        this.engine = factory.createEngine();
        this.tire = factory.createTire();
    }

    public Door getDoor() {
        return door;
    }

    public Engine getEngine() {
        return engine;
    }

    public Tire getTire() {
        return tire;
    }    
}
public class Client {
    
    public static void main(String[] args) {
        PartFactory partFactory=new BenzPartFactory();
        Car benzCar=new Car(partFactory);
        
        benzCar.getDoor().open();
        benzCar.getEngine().start();
        benzCar.getTire().getColor();
        
    }

}

  运行结果如下:

  奔驰车门开
  benz车start
  benz车color

      跟据上面的类图及运行结果可以做如下分析:

           BenzDoor、BenzTire和BenzEngine有很强的关联关系,我们可以说一部benz车,不可能用Bmw的车门,即BmwDoor。这种很强的关联关系通过BenzPartFactory进行了很好的维护。对于客户端来说,如上面的client类,如果客户想要一部benz车,那么我只需要一个生产benz车的工厂即可,这个工厂所有的产品实例,都是benz车的部件。从运行结果我们也可以看出。

         试想一下,随着这个工厂的发展,他现在也要生产Audi的车,这时我们只要增加一个audi的车门的类AudiDoor、AudiTire 、AudiEngine和AudiPartFactory就可以了,其它的类不需要做任何的修改。但客户说,我要在车上装一对翅膀呢,堵车时可以飞,这时我们就要对每个工厂都要增加能返回翅膀的工厂方法,要对每个工厂进行修改,这是不符合开闭原则的。所以说抽象工厂对增加产品等级结构方面是不支持开闭原则的,对于产品族维度(如audi车)是支持开闭原则的。

 

 五。模式的约束

  对于产生一个相互关联或依赖的产品族适用,且支持在产品族方向的扩展,不适用于产品等级方向的扩展。

六。模式的变体与扩展

  1、抽像工厂提供静态工厂方法:抽像工厂可以提供一个静态的工厂方法,通过参数返回具体的工厂实例。

  2、抽像工厂与具体工厂合并:如果在产品族方向上确定只有一个产品族,那么抽像工厂就没有必要了,这时只需要一个具体工厂就可以了,我们可以进一步延深,为这个具体工厂提供一个静态方法,该方法返回自已的实例。

七。与其它模式的关系

  如果只有一个产品等级结构,那么就是工厂方法模式了,如下图:

  

 

  如果有多个产品等级结构,那么抽像工厂里面的每一个工厂方法都是"工厂方法"模式。

八。模式优缺点

   在产口族方向支持开闭原则,在产口等级结构方向不支持开闭原则。

文章评论

中美印日四国程序员比较
中美印日四国程序员比较
亲爱的项目经理,我恨你
亲爱的项目经理,我恨你
如何区分一个程序员是“老手“还是“新手“?
如何区分一个程序员是“老手“还是“新手“?
写给自己也写给你 自己到底该何去何从
写给自己也写给你 自己到底该何去何从
为什么程序员都是夜猫子
为什么程序员都是夜猫子
什么才是优秀的用户界面设计
什么才是优秀的用户界面设计
60个开发者不容错过的免费资源库
60个开发者不容错过的免费资源库
10个帮程序员减压放松的网站
10个帮程序员减压放松的网站
为啥Android手机总会越用越慢?
为啥Android手机总会越用越慢?
程序员和编码员之间的区别
程序员和编码员之间的区别
旅行,写作,编程
旅行,写作,编程
漫画:程序员的工作
漫画:程序员的工作
程序猿的崛起——Growth Hacker
程序猿的崛起——Growth Hacker
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
团队中“技术大拿”并非越多越好
团队中“技术大拿”并非越多越好
我是如何打败拖延症的
我是如何打败拖延症的
程序员必看的十大电影
程序员必看的十大电影
程序员的一天:一寸光阴一寸金
程序员的一天:一寸光阴一寸金
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
老美怎么看待阿里赴美上市
老美怎么看待阿里赴美上市
老程序员的下场
老程序员的下场
Google伦敦新总部 犹如星级庄园
Google伦敦新总部 犹如星级庄园
程序员应该关注的一些事儿
程序员应该关注的一些事儿
鲜为人知的编程真相
鲜为人知的编程真相
聊聊HTTPS和SSL/TLS协议
聊聊HTTPS和SSL/TLS协议
当下全球最炙手可热的八位少年创业者
当下全球最炙手可热的八位少年创业者
不懂技术不要对懂技术的人说这很容易实现
不懂技术不要对懂技术的人说这很容易实现
如何成为一名黑客
如何成为一名黑客
十大编程算法助程序员走上高手之路
十大编程算法助程序员走上高手之路
 程序员的样子
程序员的样子
Web开发者需具备的8个好习惯
Web开发者需具备的8个好习惯
Web开发人员为什么越来越懒了?
Web开发人员为什么越来越懒了?
那些性感的让人尖叫的程序员
那些性感的让人尖叫的程序员
编程语言是女人
编程语言是女人
Java程序员必看电影
Java程序员必看电影
总结2014中国互联网十大段子
总结2014中国互联网十大段子
2013年美国开发者薪资调查报告
2013年美国开发者薪资调查报告
每天工作4小时的程序员
每天工作4小时的程序员
那些争议最大的编程观点
那些争议最大的编程观点
2013年中国软件开发者薪资调查报告
2013年中国软件开发者薪资调查报告
程序员最害怕的5件事 你中招了吗?
程序员最害怕的5件事 你中招了吗?
看13位CEO、创始人和高管如何提高工作效率
看13位CEO、创始人和高管如何提高工作效率
我跳槽是因为他们的显示器更大
我跳槽是因为他们的显示器更大
科技史上最臭名昭著的13大罪犯
科技史上最臭名昭著的13大罪犯
一个程序员的时间管理
一个程序员的时间管理
5款最佳正则表达式编辑调试器
5款最佳正则表达式编辑调试器
程序员周末都喜欢做什么?
程序员周末都喜欢做什么?
程序员的鄙视链
程序员的鄙视链
代码女神横空出世
代码女神横空出世
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有