#软件构造实验 工厂方法模式 (Factory Method)

24 篇文章 1 订阅
8 篇文章 0 订阅

1.什么是工厂方法模式?

工厂方法模式(Factory Method) 又被称为 Virtual Constructor 虚拟构造器 :当客户端不知道要创建哪个具体类的实例,或者不想在client代码中指明要具体创建的实例时,用工厂方法。定义一个用于创建对象的接口,让其子类来决定实例化哪一个类,从而使一个类的实例化延迟到其子类。

2.什么时候需要我们用到工厂方法模式?

当一个类遇到以下几个情形的时候:
  • 无法预知要构造一个什么样的对象的类
  • 希望其子类指定其创建的对象
  • 将类的功能委托给多个其他的子类之一时,你需要确定到底哪个子类受到委派

常规情况下,client直接创建具体对象

Product p = new ProductTwo(); 

在工厂方法模式下:

Product p = new ConcreteTwo().makeObject();

其委派关系如图所示
在这里插入图片描述
举一个实例来讲,如对一个调试器的设计
其接口设计如下

public interface Trace {
    // turn on and off debugging
    public void setDebug( boolean debug );
    // write out a debug message
    public void debug( String message );
    // write out an error message
    public void error( String message );
}

分别实现其子类 FileTrace 与 SystemTrace

public class FileTrace implements Trace {
    private PrintWriter pw;
    private boolean debug;
    public FileTrace() throws IOException {
        pw = new PrintWriter( new FileWriter( "t.log" ) );
    }
    public void setDebug( boolean debug ) {
        this.debug = debug;
    }
    public void debug( String message ) {
        if( debug ) {
            pw.println( "DEBUG: " + message );
            pw.flush();
        }
    }
    public void error( String message ) {
        pw.println( "ERROR: " + message );
        pw.flush();
    }
}
public class SystemTrace implements Trace {
    private boolean debug;
    public void setDebug( boolean debug ) {
        this.debug = debug;
    }
    public void debug( String message ) {
        if( debug )
            System.out.println( "DEBUG: " + message );
    }
    public void error( String message ) {
        System.out.println( "ERROR: " + message );
    }
}

在上面那个例子中 接口Trace就是一个抽象产品, FileTrace 与 SystemTrace便是实现抽象产品的具体的产品

下面我们便套用工厂方法模式对其进行实现:

interface TraceFactory {
    public Trace getTrace();
    public Trace getTrace(String type);
    void otherOperation(){};
}

TraceFactory是一个生产各种Trace产品的抽象工厂,其不仅包含factory method,还可以实现 其他功能

public class Factory1 implements TraceFactory {
    public Trace getTrace() {
        return new SystemTrace();
    }
}

public class Factory2 implements TraceFactory {
    public Trace  getTrace(String type) {
        if(type.equals(“file”)
       		return new FileTrace();
        else if (type.equals(“system”)
        	return new SystemTrace();
    }

对抽象工厂进行实现:根据类型决定创建哪个具体产品, 当有新的具体产品加入时,可以在工厂类里修改或增加新的工厂函数(OCP),不会影响客户端代码

客户端对工厂方法的调用:

//客户端使用“工厂方法”来创建实例,得到实例的类型是抽象接口而非具体类
Trace log1 = new Factory1().getTrace();
log1.setDebug(true);
log1.debug( "entering log" );
Trace log2 = new Factory2().getTrace("system");
log2.setDebug(false);
log2.debug("...");

而为了方便的调用,我们可以设计静态工厂方法,既可以在ADT内部实现也可以构造单独的工厂类。

public class TraceFactory1 {
    public static Trace getTrace() {
        return new SystemTrace();
    }
}

public class TraceFactory2 {
    public static Trace getTrace(String type) {
        if (type.equals(“file”)
            return new FileTrace();
    else if (type.equals(“system”)
            return new SystemTrace();
    }
}

客户端对静态工厂方法的调用:

Trace log1 = TraceFactory1.getTrace();
log1.setDebug(true);
log1.debug( "entering log" );
Trace log2 = TraceFactory2.getTrace(“system”);
log1.setDebug(true);
log2.debug(...);

4. 工厂方法模式 Factory Method的优缺点:

优点:
  • 无需将各种根据需求选择不同的类的操作绑定到客户端代码。
  • 客户端代码仅需要处理工厂生成出来的产品的接口(Trace),因而可以调用用户定义的具体产品(FileTrace,SystemTrace),实现个性化的需求
潜在的缺点:
  • 客户端可能需要同时创建一个构造器 Creator的实例,那为什么不直接创建一个特定的具体产品呢?
  • 如果客户无论必须将创建者子类化,这是可以接受的,但是如果不是这样,那么客户就不得不处理另一个进化点。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值