`
Dapple
  • 浏览: 101070 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

工厂方法模式(Factory method)以及与抽象工厂(abstract factory)的区别

阅读更多
先看经典说法,

Define an interface for creating an object, but let subclasses
decidewhich class to instantiate. Factory Method lets a class defer
instantiation to subclasses. ----Gang of Four (定义一个创建对象的接口,
让子类决定用哪个类来实例化对象。工厂方法把类的实现放在子类中完成。)

Gang of Four把这一段看作是这个模式的目的(intent),但我看更像该模式的方
法(apporach)。因为连形式都说的很清楚了。

1. 一个接口。
2. 接口中有一个创建方法。

对这个接口的使用必然涉及工厂模式。它的使用方式是多种多样的。

我们来看一个例子,

1.
public interface ImageReader {
    public DecodedImage getDecodedImage();
}

2.
public class GifReader implements ImageReader {
    public DecodedImage getDecodedImage() {
        return decodedImage;
    }
}

3.
public class JpegReader implements ImageReader { // ....
}

4.
public class ImageReaderFactory {
    public static ImageReader getImageReader(InputStream is) {
        int imageType = determineImageType(is);
        switch(imageType) {
        case ImageReaderFactory.GIF:
        return new GifReader(is);
        case ImageReaderFactory.JPEG:
        return new JpegReader(is);
       // etc.
        }
  }
}

5.
public class client{
    public void useImageReader(){
        ImageReader ir = ImageReaderFactory.getImageReader(is);
        Decodedimage di = ir.getDecodedImage();
        di.doSth();
    }
}

使用工厂方法模式,必须要有1,2或3,5这三个环节。1是包含有创建方法的接口,
2或3是对接口的实现,5是客户端对接口的使用。变化比较多的就是第四个环节,
也就是new子类的环节。这个例子是在static方法中调用new来用子类来实例化接
口.

我们再看一个例子

public abstract class TemplateClient {
    public Map queryDatabase(String queryString) {
        RdfDatabase db = databaseFactory();

        checkQueryIsValid(queryString);

        return db.find(queryString);
    }
    public abstract RdfDatabase databaseFactory(); 

}

public class JenaClient extends TemplateClient {
    public RdfDatabase databaseFactory() { return new JenaDatabase(); }

上面的例子中是在static方法中调用的new,而你完全可以根据具体情况在你想要
的任何地方做实例化工作,比如在另一个类中这样写:
TemplateClient t = new
JenaClient(); RdfDatabase rdf = t.databaseFactory();
rdf.queryDatabase("select * from table");

你也可以在TemplateClient的子类JenaClient中这样使用,

public class JenaClient extends TemplateClient {
    public RdfDatabase databaseFactory() {
        return new JenaDatabase();
    }
//这样使用
    public void use(){
        queryDatabase("select * from table");
    }
}


在这个例子中,TemplateClient既扮演了客户端(客户端在这里是指是使用创建方
法的对象)的角色,又扮演了工厂模式中的接口的角色。这个例子中,工厂方法
模式配合了模板模式(模板模式参见..)

工厂模式极为常见,它变化万千,但不变的是,实际上可以归为一点,存在一个
创建接口。只要你实现这个接口、使用这个接口,不可避免的就会使用工厂方法
模式,即使你没有意识到这一点。

比如有个抽象接口A, 如下

interface A{
    ProductB b = createB();
}


你如果使用这样的创建接口A,就不可避免的要涉及对接口A的引用,以及对接口
A的实例化以及对ProdctB的引用。你只要使用了接口A,你的一系列做法就会符合
是工厂方法模式。

抽象工厂模式所不同的是,接口A所创建的对象不是产品,而是用来创建产品的工
厂。如下:

interface A{
    Factory f = createFactory();
}


抽象工厂模式就是用工厂方法模式来实现的。所以它们二者很像。其实工厂方法
模式更准确的写法应该是这样:

interface A{
   抽象对象B b = create具体对象B();
}


工厂方法模式不管抽象对象B是谁,这个对象是product也好,是工厂对象也好,
这都是工厂方法模式的应用,只是如果这个对象是工厂对象,则它会又延伸一套
抽象工厂模式。

抽象工厂也可以不用工厂方法模式配合,看这个例子,

public class client{
    public void doSomething(){
        MyAbstractFactory f = new MyConcreteFactory();
        Product1 p1 = f.getProduct1();
        Product2 p2 = f.getProduct2();
        p1.doSomethingWith(p2);
    }
}


这里用到了抽象工厂,MyAbstractFactory就是个抽象工厂。但抽象工厂的创建是
直接new出来来,如果你想换一个具体的工厂,你只能修改代码,该成这样,

MyAbstractFactory f = new MyAnotherConcreateFactory();

但如果配合上工厂方法模式,就可以变成这样,

public class client{
    public void doSomething(){
        MyAbstractFactory f = new MyConcreteFactory();
        Product1 p1 = f.getProduct1();
        Product2 p2 = f.getProduct2();
        p1.doSomethingWith(p2);
    }

public abstract MyAbstractFactory createFactory();
}

public class ASubClass extends client{
public MyAbstractFactory createFactory(){
return new MyConcreteFactory();
}
}


这是工厂方法模式,就像前面说的那样,它有一个创建接口(abstract
createFactory()可以看做接口),有对这个接口的实现。它也是抽象工厂模式。
或者说,这种抽象工厂的创建,使用了工厂方法模式。

希望这篇文章能帮你从形式上理解工厂方法模式以及它和抽象工厂模式的区别。
关于抽象工厂的详细讲解,请参考http://hi.baidu.com/dapplehou/blog/item /f4645edf52a4c21f4954038a.html
0
0
分享到:
评论

相关推荐

    抽象工厂模式(Abstract Factory Pattern)

    理解头绪,然后接合简单工厂模式、工厂方法模式对工厂家族的了解,再加上抽象工厂模式的意图,头脑中差不多有一个雏型了吧。好了,咱们一起来分析一下。。 先把各个角色揪出来。 抽象工厂:虚拟的衣柜,它只是个概念...

    JAVA工厂模式

    GOF在《设计模式》一书中将工厂模式分为两类:工厂方法模式(Factory Method)与抽象工厂模式(Abstract Factory)。将简单工厂模式(Simple Factory)看为工厂方法模式的一种特例,两者归为一类。 两者皆可,在...

    工厂方法和抽象工厂——Factory Method & Abstract Factory

    NULL 博文链接:https://chuanwang66.iteye.com/blog/1335230

    Java设计模式之工厂模式(Factory)

    2. 工厂方法模式(Factory Method) 3. 抽象工厂模式(Abstract Factory) 这三种模式从上到下逐步抽象,并且更具一般性。还有一种分类法,就是将简单工厂模式看为工厂方法模式的一种特例,两个归为一类。下面是使用...

    24种设计模式与6大设计原则

    工厂方法模式[FACTORY METHOD PATTERN] 抽象工厂模式[ABSTRACT FACTORY PATTERN] 门面模式[FACADE PATTERN] 适配器模式[ADAPTER PATTERN] 模板方法模式[TEMPLATE METHOD PATTERN] 建造者模式[BUILDER PATTERN] 策略...

    Java24种设计模式,Java24种设计模式,24种设计模式,学会了这24种设计模式,可以打遍天下无敌手,设计模式非常重要

    5、工厂方法模式FACTORY METHOD PATTERN 6、抽象工厂模式ABSTRACT FACTORY PATTERN 7、门面模式FACADE PATTERN 8、适配器模式ADAPTER PATTERN 9、模板方法模式TEMPLATE METHOD PATTERN 10、建造者模式BUILDER ...

    01-制造工具的工厂模式(1).html

    工厂方法模式( Factory Method ) 抽象工厂模式( Abstract Factory ) 单例模式( Singleton ) 建造者模式( Builder ) 原型模式( Prototype ) 结构型模式包含了: 适配器模式( Adapter ) 装饰器模式( ...

    浅析Python 简单工厂模式和工厂方法模式的优缺点

    工厂方法模式(Factory Method) 抽象工厂模式 (Abstract Factory) 但是在实际过程中还有一种工厂模式经常被使用,那就是 简单工厂模式(Simple Factory)。有一种常见的分类的方法:根据产品是由具体产品还是...

    java版本二十三种设计模式.zip

    - 工厂方法模式(Factory Method) - 抽象工厂模式(Abstract Factory) - 单例模式(Singleton) - 建造者模式(Builder) - 原型模式(Prototype) - 代理模式(Proxy) - 适配器模式(Adapter) - 装饰器模式(Decorator...

    09-通过容器实现的外观模式(2).html

    工厂方法模式( Factory Method ) 抽象工厂模式( Abstract Factory ) 单例模式( Singleton ) 建造者模式( Builder ) 原型模式( Prototype ) 结构型模式包含了: 适配器模式( Adapter ) 装饰器模式( ...

    00-初探 Laravel 和其中的设计模式(3).html

    工厂方法模式( Factory Method ) 抽象工厂模式( Abstract Factory ) 单例模式( Singleton ) 建造者模式( Builder ) 原型模式( Prototype ) 结构型模式包含了: 适配器模式( Adapter ) 装饰器模式( ...

    12-附录 1 设计模式的七大原则(1).html

    工厂方法模式( Factory Method ) 抽象工厂模式( Abstract Factory ) 单例模式( Singleton ) 建造者模式( Builder ) 原型模式( Prototype ) 结构型模式包含了: 适配器模式( Adapter ) 装饰器模式( ...

    C#版 24种设计模式

    工厂方法模式(Factory Method Pattern) 观察者模式(Observer Pattern) 建造者模式(Builder Pattern) 解释器模式(Interpreter Pattern) 命令模式(Command Pattern) 模板方法模式(Template Method Pattern) 桥接模式...

    10-基于装饰器的日志写入器(1).html

    工厂方法模式( Factory Method ) 抽象工厂模式( Abstract Factory ) 单例模式( Singleton ) 建造者模式( Builder ) 原型模式( Prototype ) 结构型模式包含了: 适配器模式( Adapter ) 装饰器模式( ...

    08-责任链和管道的协作(1).html

    工厂方法模式( Factory Method ) 抽象工厂模式( Abstract Factory ) 单例模式( Singleton ) 建造者模式( Builder ) 原型模式( Prototype ) 结构型模式包含了: 适配器模式( Adapter ) 装饰器模式( ...

    11-回顾和总结(1).html

    工厂方法模式( Factory Method ) 抽象工厂模式( Abstract Factory ) 单例模式( Singleton ) 建造者模式( Builder ) 原型模式( Prototype ) 结构型模式包含了: 适配器模式( Adapter ) 装饰器模式( ...

    03-查询语句建造器(1).html

    工厂方法模式( Factory Method ) 抽象工厂模式( Abstract Factory ) 单例模式( Singleton ) 建造者模式( Builder ) 原型模式( Prototype ) 结构型模式包含了: 适配器模式( Adapter ) 装饰器模式( ...

    04-通过策略选择驱动(1).html

    工厂方法模式( Factory Method ) 抽象工厂模式( Abstract Factory ) 单例模式( Singleton ) 建造者模式( Builder ) 原型模式( Prototype ) 结构型模式包含了: 适配器模式( Adapter ) 装饰器模式( ...

    02-控制反转和服务容器(1).html

    工厂方法模式( Factory Method ) 抽象工厂模式( Abstract Factory ) 单例模式( Singleton ) 建造者模式( Builder ) 原型模式( Prototype ) 结构型模式包含了: 适配器模式( Adapter ) 装饰器模式( ...

    05-容易被忽略的迭代器(1).html

    工厂方法模式( Factory Method ) 抽象工厂模式( Abstract Factory ) 单例模式( Singleton ) 建造者模式( Builder ) 原型模式( Prototype ) 结构型模式包含了: 适配器模式( Adapter ) 装饰器模式( ...

Global site tag (gtag.js) - Google Analytics