设计模式-抽像工厂

 一。概念

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

二。模式动机

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

三。模式的结构

  

  通过上图我们可以清楚的看到抽像工厂模式包括以下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、抽像工厂与具体工厂合并:如果在产品族方向上确定只有一个产品族,那么抽像工厂就没有必要了,这时只需要一个具体工厂就可以了,我们可以进一步延深,为这个具体工厂提供一个静态方法,该方法返回自已的实例。

七。与其它模式的关系

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

  

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

八。模式优缺点

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

时间: 2024-11-18 21:15:06

设计模式-抽像工厂的相关文章

【设计模式】简单工厂模式

以面向对象的思想和简单工厂模式,写一个C++计算器程序,代码如下: #include <iostream> using namespace std; class Operation { public: Operation(double left, double right) { lhs = left; rhs = right; } const double GetLeft() const { return lhs; } const double GetRight() const { retur

设计模式之简单工厂模式

设计模式之简单工厂模式 动机:         不暴露实例化逻辑来创建对象.通过公共的接口创建新的对象.         这是一个简单的实现,客户端需要一个product,但是client不直接使用new对象,而是通过提供需要的对象信息来找factory得到新的product.         这个factory实例化一个具体的product并返回(转化成抽象的类),client段使用这个抽象的类而不用考虑它具体的实现. 应用举例:        也许工厂模式是使用最多的模式之一.举个例子,一个

设计模式之抽象工厂模式

抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 最大的好处便是易于交换产品系列,由于具体工厂类,在一个应用中只需在初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,它只需改变具体工厂即可使用不同的产品配置. 他使具体创建实例的过程与客户端分离,客户端是通过它们的抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离. 下面的代码还使用了反射与XML. 代码如下: using System; using System.Collections.Ge

初识设计模式之--简单工厂

作为一个刚刚入门的菜鸟.虽只学到了些许编程语言的皮毛(或者连皮毛都算不上),但是随着时间和学习的深入,"设计模式"这一专业术语便慢慢浮现在眼前. 到底何为设计模式呢?它的出现将会给我们带来哪些帮助?......等等一系列问题便会出现在我们脑海中.俗话说:问题才是探究知识的钥匙.就让我们带着 自己的疑问一同来学习设计模式. 首先,我们先来认识一下什么是设计模式,以及运用设计模式的优点. 设计模式的简单理解:模式是在某一背景下某个问题的一种解决方案.1.复用解决方案——通过复用已经公认的设

设计模式之抽象工厂模式20170803

创建型设计模式之抽象工厂模式: 一.含义 为创建一组相关或相互依赖的对象提供一个接口,而且无需指定它们的具体类. 具体来说, 为一组具有相同约束(属性)的对象,提供一个接口,这个接口下有不同的实现,每个实现类对应一种类型的约束(一种具体的属性),同时提供该类型的约束(属性)下所有对象的创建方法 二.代码说明 1.主要有两个角色 1)一组互相影响的产品线(对象),也叫做产品族 2)抽象工厂类及其实现类 抽象工厂类:在N个产品族中,在抽象工厂类中就应该有N个创建方法 实现类:具体实现类是产品族的具体

每天一个设计模式-1 简单工厂

每天一个设计模式-1  简单工厂 1.简单工厂的定义 提供一个创建对象实例的功能,而无须关心其具体实现(核心). 虽然不能让模块外部知道模块内部的具体实现,但模块内部是可以知道具体实现类的.干脆在模块内部建一个类,用这个类来创建接口,然后把创建号的接口返回给客户端:这样,外部应用就只需要根据这个类来获取相应的接口对象,通过这个接口对象就可以操作接口定义的方法了.显然,这个类就像一个工厂,专门用来生成(生产)需要的接口对象. 2.简单的例子 说明: 代码: Api:接口,wear是一个公有方法.

设计模式Java之工厂方法。

1,工厂方法: 使用一个工厂的方法来创建产品. 1 package WHP; 2 //产品依赖于抽象 3 public interface IRunable { 4 public void Run(); 5 } 1 package WHP; 2 //具体实现 3 public class Car implements IRunable { 4 public void Run(){ 5 System.out.println("Car running."); 6 } 7 } 1 packa

设计模式初探—简单工厂模式

为什么要学习设计模式? 可重用.可维护.可扩展.灵活性好 什么是简单工厂模式? 从设计模式的类型上来说,简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一.简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例.简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现. 简单工厂模式的好处? (1)将具体业务和实现进行分离 (2)将多个具体业务之间进行解耦 解决的问题? 单独的类来创造

设计模式 2/23 工厂模式(二)

先要给各位同学灌输一个思想,世间本无设计模式,用的人多了,自然就有了 没有太明显的优劣之分,只道是谁更适合 如果没法理解<<工厂>>,建议阅读上一篇 设计模式 2/23 工厂模式(一) ,毕竟是一个渐进明细的过程,急不来的 这一篇分享 工厂模式 回想一下简单工厂,我们把具体类的实例化工作放在一个工厂方法里面来执行. 同时故意在上一篇提到了开放-封闭原则. 仔细想象看看上一篇的代码,到底有没有遵守这个原则,或者说这个原则有没有被严格意义的遵守,或者说遵守的程度是多少. 如果我们要新增