设计模式(1): 工厂模式

  工厂模式属于创建型设计模式(Creational Patterns),实现了“工厂”概念的面向对象设计模式。就像其他创建型模式一样,它也是处理在不指定对象具体类型的情况下创建对象的问题。工厂方法模式的实质是“定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类。工厂方法让类的实例化推迟到子类中进行。”

  创建一个对象常常需要复杂的过程,所以不适合包含在一个复合对象中。创建对象可能会导致大量的重复代码,可能会需要复合对象访问不到的信息,也可能提供不了足够级别的抽象,还可能并不是复合对象概念的一部分。工厂方法模式通过定义一个单独的创建对象的方法来解决这些问题。由子类实现这个方法来创建具体类型的对象。

1) 简单工厂模式(Simple Factory Pattern)

  简单工厂模式(Simple Factory Pattern):又称为静态工厂方法(Static Factory Method)模式,工厂对象通常包含一个或多个方法,用来创建这个工厂所能创建的各种类型的对象。这些方法可能接收参数,用来指定对象创建的方式,最后返回创建的对象。

  比如,一个程序要读取图像文件。程序支持多种图像格式,每种格式都有一个对应的ImageReader类用来读取图像。程序每次读取图像时,需要基于文件信息创建合适类型的ImageReader。这个选择逻辑可以包装在一个简单工厂中:

public class ImageReaderFactory {
    public static ImageReader imageReaderFactoryMethod(InputStream is) {
        ImageReader product = null;

        int imageType = determineImageType(is);
        switch (imageType) {
            case ImageReaderFactory.GIF:
                product = new GifReader(is);
            case ImageReaderFactory.JPEG:
                product = new JpegReader(is);
            //...
        }
        return product;
    }
}
你还可以先进行对产品进行注册
class ProductFactory
{
    private HashMap m_RegisteredProducts = new HashMap();

    public void registerProduct (String productID, Class productClass)
    {
        m_RegisteredProducts.put(productID, productClass);
    }

    public Product createProduct(String productID)
    {
        Class productClass = (Class)m_RegisteredProducts.get(productID);
        Constructor productConstructor = cClass.getDeclaredConstructor(new Class[] { String.class });
        return (Product)productConstructor.newInstance(new Object[] { });
    }
}

总结:

  简单工厂模式主要包括三部分:

  1)Factory:学生会,负责实现创建所有实例。

  2)Product:部门,提供创建实例所共有的公共接口。

  3)ConcreteProduct:(组织部,宣传部,外联部)创建具体事例。

  简单工厂模式将对象的创建和对象本身业务处理分离可以降低系统的耦合度,使得两者修改起来都相对容易。

  简单工厂模式最大的问题在于工厂类的职责相对过重,增加新的产品需要修改工厂类的判断逻辑,这一点与开闭原则是相违背的。

工厂方法模式(Factory Method Pattern)

  上面提到简单工厂模式违背了开闭原则,那如何解决呢?

  工厂方法模式是简单工厂模式的衍生,完全实现‘开闭原则’,实现了可扩展,可以应用于产品结果复杂的场合。

  工厂方法模式对简单工厂模式进行了抽象。有一个抽象的Factory类(可以是抽象类和接口),这个抽象工厂类不再负责产品的创建,仅负责具体工厂子类必须实现的接口,具体的生产工作由其子类去完成。在这个模式中,工厂类和产品类往往可以依次对应。即一个抽象工厂对应一个抽象产品,一个具体工厂对应一个具体产品,这个具体的工厂就负责生产对应的产品。

public interface Product {  }

public abstract class Creator
{
    public void anOperation()
    {
        Product product = factoryMethod();
    }

    protected abstract Product factoryMethod();
}

public class ConcreteProduct implements Product {  }

public class ConcreteCreator extends Creator
{
    protected Product factoryMethod()
    {
        return new ConcreteProduct();
    }
}

public class Client
{
    public static void main( String arg[] )
    {
        Creator creator = new ConcreteCreator();
        creator.anOperation();
    }
}

总结:

  工厂方法模式其实是对简单工厂模式中工厂进行了进一步抽象,已解决开闭问题。

  工厂方法模式分为以下四部分:

  抽象工厂(Creator)角色:是工厂方法模式的核心,与应用程序无关。任何在模式中创建的对象的工厂类必须实现这个接口。

  具体工厂(Concrete Creator)角色:这是实现抽象工厂接口的具体工厂类,包含与应用程序密切相关的逻辑,并且受到应用程序调用以创建产品对象。在上图中有两个这样的角色:BulbCreator与TubeCreator。

  抽象产品(Product)角色:工厂方法模式所创建的对象的超类型,也就是产品对象的共同父类或共同拥有的接口。在上图中,这个角色是Light。

  具体产品(Concrete Product)角色:这个角色实现了抽象产品角色所定义的接口。某具体产品有专门的具体工厂创建,它们之间往往一一对应。

  工厂方法的缺点也很明显,在添加新产品时,不仅需要编写新的具体产品类,而且还要提供与之对应的具体工厂类,系统中类的个数将成对增加,在一定程度上增加了系统的复杂度,有更多的类需要编译和运行,会给系统带来一些额外的开销。

抽象工厂模式

  抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。工厂方法模式针对的是一个产品等级结构;而抽象工厂模式针对的是多个产品等级结构。

  当每个抽象产品都有多于一个的具体子类的时候,工厂角色怎么知道实例化哪一个子类呢?比如每个抽象产品角色都有两个具体产品。抽象工厂模式提供两个具体工厂角色,分别对应于这两个具体产品角色,每一个具体工厂角色只负责某一个产品角色的实例化。每一个具体工厂类只负责创建抽象产品的某一个具体子类的实例。

  举个例子,商场里都有手机柜台和笔记本柜台,手机和笔记本都有苹果和联想品牌,如果你想要苹果的iPhone6,销售人员就会从手机柜台拿苹果的iPhone6,如果你想要联想的ThinkPad,销售人员就会从笔记本柜台拿联想的ThinkPad。这里的销售员就像是一个总的接口,一个抽象工厂,手机柜台和笔记本柜台就像两个具体工厂,苹果和联想就是抽象的产品,其各自生成的手机和笔记本就是具体的产品。

abstract class AbstractProductA{
    public abstract void operationA1();
    public abstract void operationA2();
}

class ProductA1 extends AbstractProductA{
    ProductA1(String arg){
        System.out.println("Hello "+arg);
    } // Implement the code here
    public void operationA1() { };
    public void operationA2() { };
}

class ProductA2 extends AbstractProductA{
    ProductA2(String arg){
        System.out.println("Hello "+arg);
    } // Implement the code here
    public void operationA1() { };
    public void operationA2() { };
}

abstract class AbstractProductB{
    //public abstract void operationB1();
    //public abstract void operationB2();
}

class ProductB1 extends AbstractProductB{
    ProductB1(String arg){
        System.out.println("Hello "+arg);
    } // Implement the code here
}

class ProductB2 extends AbstractProductB{
    ProductB2(String arg){
        System.out.println("Hello "+arg);
    } // Implement the code here
}

abstract class AbstractFactory{
    abstract AbstractProductA createProductA();
    abstract AbstractProductB createProductB();
}

class ConcreteFactory1 extends AbstractFactory{
    AbstractProductA createProductA(){
        return new ProductA1("ProductA1");
    }
    AbstractProductB createProductB(){
        return new ProductB1("ProductB1");
    }
}

class ConcreteFactory2 extends AbstractFactory{
    AbstractProductA createProductA(){
        return new ProductA2("ProductA2");
    }
    AbstractProductB createProductB(){
        return new ProductB2("ProductB2");
    }
}

//Factory creator - an indirect way of instantiating the factories
class FactoryMaker{
    private static AbstractFactory pf=null;
    static AbstractFactory getFactory(String choice){
        if(choice.equals("a")){
            pf=new ConcreteFactory1();
        }else if(choice.equals("b")){
                pf=new ConcreteFactory2();
            } return pf;
    }
}

// Client
public class Client{
    public static void main(String args[]){
        AbstractFactory pf=FactoryMaker.getFactory("a");
        AbstractProductA product=pf.createProductA();
        //more function calls on product
    }
}

总结:

  抽象工厂模式的实质是“提供接口,创建一系列相关或独立的对象,而不指定这些对象的具体类。”

  抽象工厂模式的目的,是将若干抽象产品的接口与不同主题产品的具体实现分离开。这样就能在增加新的具体工厂的时候,不用修改引用抽象工厂的客户端代码。

  抽象工厂模式主要分为四部分:

  AbstractFactory:工厂类的公共接口

  ConcreteFactory:具体工厂

  AbstractProduct:产品类的公共接口

  Product:具体工厂创建的产品实例

适用性:

  在以下情况可以考虑使用抽象工厂模式:

  一个系统要独立于它的产品的创建、组合和表示时。

  一个系统要由多个产品系列中的一个来配置时。

  需要强调一系列相关的产品对象的设计以便进行联合使用时。

  提供一个产品类库,而只想显示它们的接口而不是实现时。

优点:

  具体产品从客户代码中被分离出来

  容易改变产品的系列

  将一个系列的产品族统一到一起创建

缺点:

  在产品族中扩展新的产品是很困难的,要增加一个系列的某一产品,  既要在抽象的 Creator 里加代码,又要在具体的里面加代码。

使用场景:

  QQ 换皮肤,一整套一起换。

  生成不同操作系统的程序。

参考:

https://zh.wikipedia.org/wiki/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F_(%E8%AE%A1%E7%AE%97%E6%9C%BA)

https://zh.wikipedia.org/wiki/%E5%B7%A5%E5%8E%82%E6%96%B9%E6%B3%95

http://baike.baidu.com/view/1580263.htm

http://www.oodesign.com/

https://zh.wikipedia.org/wiki/%E6%8A%BD%E8%B1%A1%E5%B7%A5%E5%8E%82

http://baike.baidu.com/view/1580269.htm

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-12 05:45:19

设计模式(1): 工厂模式的相关文章

设计模式-抽象工厂模式(C#)

设计模式--抽象工厂模式(JAVA) 在抽象工厂模式中,一个具体工厂可以生产一组相关的具体产品,这样的一组产品成为产品族,产品族中的每一个产品都属于某一个产品继承等等级结构.当系统所提供的工厂生产的具体产品并不是一个简单的对象,而是多个位于不同产品等级结构.属于不同类型的具体产品时就可以使用抽象工厂模式. 抽象工厂模式与工厂方法模式最大的区别在于,工厂方法模式针对的是一个产品等级结构,而抽象工厂模式需要面对多个产品等级结构,一个工厂等级结构可以负责多个不同产品等级结构中的产品对象的创建,当一个工

JS 设计模式(工厂模式环境搭建)

<!--引入的核心JS文件--> <script type="text/javascript" src="CommonUtil.js"></script> <script type=text/javascript charset=utf-8> <!--JS设计模式(工厂模式)--> //搭建一个工厂环境 //卖车店 function CarShop(){}; CarShop.prototype={ cons

设计模式 5 —— 工厂模式

设计模式目录: 设计模式 1 ——观察者模式 设计模式 2 —— 装饰者模式 设计模式 3 —— 迭代器和组合模式(迭代器) 设计模式 4 —— 迭代器和组合模式(组合) 设计模式 5 —— 工厂模式 设计模式 5 -- 工厂模式,布布扣,bubuko.com

php设计模式:工厂模式

意图: 定义一个用于创建对象的接口,让子类决定实例化哪一个类. 工厂模式实现: 工厂模式中任何创建对象的工厂类都要实现这个接口,实现接口的方法体中都要实现接口中的方法,它声明了工厂方法,该方法返回一个Product类型的对象. 工厂模式适用场景:1.当一个类不知道它所必须创建的对象的类的时候2.当一个类希望由它的子类来指定它所创建的对象的时候3.当类将创建对象的职责委托给多个帮助子类的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候 实例: <?php /** * 抽象工厂角色 *

浅析JAVA设计模式之工厂模式(一)

1 工厂模式简介 工厂模式的定义:简单地说,用来实例化对象,代替new操作. 工厂模式专门负责将大量有共同接口的类实例化.工作模式可以动态决定将哪一个类实例化,不用先知道每次要实例化哪一个类. 工厂模式可以分一下三种形态: 简单工厂 (Simple Factory)模式:又称静态工厂模式(StaticFactory). 工厂方法 (Factroy Method)模式:又称多态性工厂模式(Polymorphic Factory). 抽象工厂 (Abstract Factroy)模式:又称工具箱模式

浅析JAVA设计模式之工厂模式(二)

1 工厂方法模式简介 工厂方法 (Factroy Method) 模式:又称多态性工厂模式(Polymorphic Factory),在这种模式中,核心工厂不再是一个具体的类,而是一个抽象工厂,提供具体工厂实现的接口,具体创建产品交由子工厂去做,抽象工厂不涉及任何产品被实例化的细节.而不同等级的产品,就对应一个不同等级的工厂,如下图. 图1 1.1工厂方法模式(多态性工厂模式): 工厂方法模式有三个角色: 1. 抽象产品接口 2. 具体产品类 3. 抽象工厂接口 4.具体工厂类. 1.2工厂方法

设计模式之工厂模式 (二)

工厂模式分为三大类 简单工厂(SimpleFactory) 工厂方法模式(Factory Method) 抽象工厂模式(Abstract Factory) 动态工厂(Dynamic Factory,属于优化版简单工厂) 一.简单工厂 组成如下: (1) 工厂类角色:这是本模式的核心,含有一定的商业逻辑和判断逻辑.在java中它往往由一个具体类实现. (2) 抽象产品角色:它一般是具体产品继承的父类或者实现的接口.在java中由接口或者抽象类来实现. (3) 具体产品角色:工厂类所创建的对象就是此

浅谈php设计模式(1)---工厂模式

一.接口继承直接调用 先看看这样一段代码: 1 <?php 2 3 interface db{ 4 function conn(); 5 } 6 7 class dbmysql implements db { 8 public function conn(){ 9 echo "连接到了mysql"; 10 } 11 } 12 13 class dbsqlite implements db{ 14 public function conn(){ 15 echo "连接到了

5分钟理解设计模式之工厂模式

工厂模式是Java中最常用的设计模式.工厂模式提供很好的创建对象的方式,属于创建型模式. 使用工厂模式创建对象是不向使用者暴露创建细节,并且可以通过统一的接口引用对象. 实现 我们将创建Shape接口和实现Shape接口的具体类.下一步再声明工厂类ShapeFactory. 示例类FactoryPatternDemo使用ShapeFactory获取Shape对象.通过给ShapeFactory传递图形参数(CIRCLE / RECTANGLE / SQUARE)来获取需要的对象. 第1步 创建一

浅析JAVA设计模式之工厂模式(三)

在阅读本文之前,请先阅读(一)和(二)中的简单工厂模式和工厂方法模式. 1抽象工厂模式简介 抽象工厂 (Abstract Factroy) 模式:工具箱模式(kit).抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态,如下图. 图1.1 上图左边有一个工厂类的等级结构,右边有两个不同的产品等级结构,分别是产品A的等级结构和产品B的等级结构,工厂1和工厂2分别负责不同一个产品等级,同一个产品族的产品的生产.又例如下图: 图1.2 上图表示的是Button和Text两个不同产品的等级