设计模式-工厂方法设计模式与接口的应用

来源:互联网 发布:js 界面跳转 编辑:程序博客网 时间:2024/05/20 18:19
前言
上一篇《设计模式-代理模式与适配器模式实现代码重用以及策略模式的使用》文章中已经提到了接口与策略模式的应用,这篇我继续根据接口与策略模式应用过程中出现的一些相冲突的需求来演示一种解决办法,这就是工厂方法设计模式与接口的应用

为什么要写这篇文章
写这篇文章之前我在think in java这本书上看到了介绍工厂方法设计模式与接口的应用《第9.9章接口与工厂》。看了里面的介绍我能理解里面所讲的规则,也让我知道了原来接口的应用这么多,看了一遍就过了,总感觉是在做无用功,所以我在这里记录一些接口的具体使用的案例以及其中涉及的一些模式,其中还有一些自己的疑惑,这篇文章除了介绍一种使用方法以外,更多的是自己的思考,如果想了解更多工厂方法设计模式,请阅读官方文档

正文
需求:现在client programmer需要我们类设计者提供一个方法能够从打印不同种cycle的信息,当然这个方法里面设计很复杂的算法,但是这些算法对不同种类型的cycle都适用。
分析:我先封装一个类,其它无相关的属性方法我都隐藏,然后对client programmer提供这个公共的接口方法。但是我这个公共的接口方法怎么才能实现复用呢? 利用策略设计模式可以实现。刚开始,我设计的代码如下
public class ClientNeedInterface {           private String introduction = "大家好,请允许我自我介绍一下" ;      private String end = "很高兴能让大家认识我" ;           public void methodToClient(Cycle cycle) {            //固定算法           System. out.println( introduction);            //自行车信息            cycle.printCycleInfo();            //固定算法           System. out.println( end);     }           public static void main(String[] args) {           ClientNeedInterface cnif = new ClientNeedInterface();            cnif.methodToClient( new Bicycle());            cnif.methodToClient( new Tricycle());            cnif.methodToClient( new Unicycle());     }}

提示:Cycle是一个接口,Bicycle、Tricycle、Unicycle是Cycle的实现类

描述:上面的代码很自然,一下子看不出些什么。但是代码必须在某处创建Cycle的确切类型,这个类型从上面提供给client programmer的公用接口看来,需要在客户端进行创建Bicycle这种确切的类型(上面演示是下main函数中),这样Bicycle就和客户端程序耦合在一起了,以后我想更改Bicycle这样的类,我都举步维艰,因为我不得不去考虑客户那边遗留代码是否会造成影响(类设计者不喜欢将这种不确定的东西给用户使用,需要实现隐藏)。不知道从哪里看到这样的结论,尽量少new具体类型,这样耦合比较大,如同spring那样注入就完美了。

给读者的话:呵呵,很遗憾的说一句:请原谅我的无知,上面是我结合think in java这本书前面几章,想到精神分裂才做的总结,不知道是否正确,因为think in java的作者,只给了我下面几句话




第一段讲的是策略这个设计模式的好处:工厂对象是一个接口,传递工厂接口实现类,我们这样可以做到给client programmer提供的公共接口与工厂实现类分离,随时可以替换成另外一个实现类。这里没有讲明我为什么不能使用上面的代码
第二段貌似指明了某处创建具体类会有耦合这样的问题,是不是我想多了? 这里他说想要创建框架(One common reason is to create a framework.),我从一些开源框架中看到确实很多不是直接在客户端程序进行new创建的,往往提供一个Factory类来进行创建

okey,已经跑题了,我们还是回来对代码做一下改进吧,一起来认识一下工厂方法设计模式与接口的应用
思考:我不打算提供客户端直接创建Cycle的实现类,那么我只能在向client programmer提供的共用方法中创建了,从上面提供的代码来看,我无法在methodToClient方法里面new 接口(当然不能直接在里面写具体类型,这样做代码无法复用),我们可以提供一个工厂接口,介绍工厂的实现,每个工厂的实现都有一个返回Cycle的具体实现类对象
如下代码
public class ClientNeedInterface {           private String introduction = "大家好,请允许我自我介绍一下" ;      private String end = "很高兴能让大家认识我" ;           public void methodToClient(CycleFactory factory) {            //固定算法           System. out.println( introduction);            //自行车信息           Cycle cycle = factory.goBackCycle();            cycle.printCycleInfo();            //固定算法           System. out.println( end);     }           public static void main(String[] args) {           ClientNeedInterface cnif = new ClientNeedInterface();            cnif.methodToClient( new TricycleFactoryImpl());            cnif.methodToClient( new UnicycleFactoryImpl());            cnif.methodToClient( new BicycleFactoryImpl());     }}

提示:TricycleFactoryImpl、UnicycleFactoryImpl、BicycleFactoryImpl是CycleFactory 的实现类,里面提供goBackCycle的一个接口方法返回各类cycle的对象

描述:上面我们可以得到几个知识点,1、使用策略设计模式的时候需要在方法里面得到具体的对象,我们可以间接设计一个工厂方法接口,通过传入不同的工厂实现类来得到不同的Cycle对象(工厂方法设计模式+策略模式),这样做代码不会破坏复用性。2、客户端程序员所能使用的是我提供的公共接口和类(以后维护是不会弃用这些接口和类,里面逻辑做修改到时有可能)。3:以后如果对Cycle做修改了,只要在Factory实现类做下调整就可以了(弃用替换都不会对客户端程序有任何影响)


参考资料
《think in java》中文版第四版



0 0