软件构造第11次课复习——工厂模式

临近考试,我温习了一下软件构造的第十一章,有了一些感悟,发一篇博客以抛砖引玉,如有错误请在评论区中指出,谢谢各位。

设计模式分为三种——创造型,结构型,行为类(Creational patterns,Structural patterns,Structural patterns)其中创造型“关注对象创建的过程”,典型代表是工厂方法模式。本文主要介绍工厂方法模式。

要用一句话来介绍工厂方法模式的话,就是“不用构造器产生新对象,而用‘工厂方法’产生新对象”。什么是工厂方法呢简单)工厂方法就是形如这样的方法

软件构造第11次课复习——工厂模式

他的使用是这样的 Trace log = new Factory().getTrace(“system”);

那这时候你可能有疑问:这和直接调用FileTrace有什么区别不就是脱裤子放屁——多此一举吗听我慢慢说来:

假设现在需要有一个打印错误消息的接口Trace,这个接口目前需要从文件中读取错误信息并打印,和从系统中读取信息并打印,但是这个接口以后需要从别的地方读取信息并打印(比如说,从内存中读取信息,只是举个例子),所以需要这个接口有很好的可拓展性,那么你作为程序设计者,要如何实现这个接口呢假定这个接口需要实现三个函数:

1. public void setDebug( boolean debug );

2. public void debug( String message );

3. public void error( String message );

每个类的这三个函数实现都不同

方案一:

public interface Trace {

 public void setDebug( boolean debug );

public void debug( String message );

public void error( String message );

 }

public class SystemTrace implements Trace

{ private boolean debug;

public void setDebug( boolean debug )

 { …}

public void debug( String message )

{ … }

public void error( String message )

{… }

}

public class FileTrace implements Trace

{ private boolean debug;

public void setDebug( boolean debug )

 { …}

public void debug( String message )

{ … }

public void error( String message )

{… }

}

用户想用什么就自己调用 比如FileTrace a=new FileTrace();

这样做有几个问题:1.把内部代码的类的名字泄露给用户了。

1.用户需要知道代码类名才能创建对象。这里你可能又有疑问:用户要调用代码不就是要知道类名才知道自己要调什么吗知道类名怎么知道要调什么况让他知道又有什么问题/p>

假如你雇用的3000一个月的程序员因为工资太少,女朋友和他分手了,喝了三两白的。

醉醺醺的他坐到工位下写下了以下的代码

public class MenoryTraces implements Trace

{

}

来实现在内存中读错误信息,乍一看好像没什么问题,静态检查也没有bug,但是用户调用以下函数的时候会出错:

MenoryTrace a=new MenoryTrace();

仔细一看才发现,源代码的MenoryTrace多了一个s,变成MenoryTraces!

倘若是一个大项目,这种复查是很花时间的,这就是不隐藏内部实现的恶果。

即使不考虑这种偶然情况,假若有一天因为需要打印多条错误信息,程序员把FileTrace,SystemTrace全在后面加s,那么以前的代码不就遭殃了吗以要尽量做到源代码和用户的“解耦”。

如果使用简单工厂方法

软件构造第11次课复习——工厂模式

用户在调用的时候只需要输入参数,就可以返回正确的类型,不用管trace后面加不加s的问题了。客户端也可以免去直接new的职责。

但是这样的话所有的new都在这个模式里完成了,一旦这个程序里有bug,所有的trace类都会遭殃,导致了添加代码的艰难和代码的不安全,那么就有了第二种模式

另外一种模式,工厂方法模式(注意,在老师的ppt中,把前面的简单工厂方法模式也化作工厂方法模式)

interface TraceFactory {

Trace getTrace();

void otherOperation();

}

public class SystemTraceFactory implements TraceFactory

 { public Trace getTrace()

{ … //other operations return new SystemTrace(); }

}

public class FileTraceFactory implements TraceFactory

 { public Trace getTrace()

 { return new FileTrace();

}

}

这样的

用户调用的时候是这样调用的

Trace log1 = new SystemTraceFactory().getTrace();

这种方法的好处是可以在工厂模式中实现别的方法,而且把FileTrace和SystemTrace隐藏起来了,假如新建类名特别长,像FindBugsInSystemAndGetTraceFromSystem用户不需要去记忆这么长且复杂的名字。但是用户仍需要判断自己调用的方法的工厂名字,所以说不同的工厂方法实现也有好有坏。

下面简要介绍一下静态工厂方法,静态工厂方法曾经在19年考题中出现过。它的实现类似于这种:

public class SystemTraceFactory

{ public static Trace getTrace()

 { return new SystemTrace(); }

 }

或是这种:  

public class TraceFactory

 { public static Trace getTrace(String type)

 { if(type.equals(“file”) return new FileTrace();

 else if (type.equals(“system”)

return new SystemTrace(); }

}

简单来说就是在方法的前面加上static,这样做有什么好处呢/p>

相比于通过构造器构造对象,其可以1.可具有指定的更有意义的名称,不必和类名一致

2. 不必在每次调用的时候都创建新的工厂对象

3. 可以返回原返回类型的任意子类型(SystemTrace或FileTrace)

来源:weixin_45714360

声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2021年6月5日
下一篇 2021年6月5日

相关推荐