锁定老帖子 主题:工厂方法模式应该是这样的
精华帖 (0) :: 良好帖 (0) :: 新手帖 (4) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2011-08-21
首先来讲简单工厂模式。如一个接口A, 实现类有A1,A2,A3. 在客户端上调用 A a=new A1(); 很多人觉得这样不好,因为这样就把接口跟具体的实现给耦合了。好吧,我也觉得不好,但是我先不会换成简单工厂,而是会这样: A a=null; if(type==1){ a=new A1(); }else if(type==2){ a=new A2(); }else if(type==3){ a=new A3(); } ; 但是上面的代码还是不好,因为可能调用这个if else判断的客户端不只有这里,其他的地方也要进行这样的判断,而且判断的逻辑是一样的。于是要考虑封装,自然而然的就要用简单工厂了。 其本质应该是 对A接口的实现类的选择的逻辑的封装 但是工厂方法模式:定义一个抽象的工厂方法,在子类中实现具体应该生成哪个A的接口。看上去确实生成A接口的选择被延时到子类。但是在客户端上调用还是有个很大的问题:谁来选择具体工厂方法模式中的工厂? 简单工厂模式是把这个逻辑封装了的,到了工厂方法模式这个选择是由客户端自己来选择的: AmethodFactory am=new A1methodFactory();//对应生成对象A1的工厂 下面我们来看看工厂方法模式是如何手jian的。 其实 A a=new A1(); 这段代码已经很面向接口编程了。因为后面的操作都是用接口A的引用a进行具体的操作的。 我就是不知道选择new 哪个A的具体实现才用工厂方法模式的。结果工厂方法模式让我这么办 AmethodFactory am=new A1methodFactory(); //我怎么知道选A1methodFactory 而不是选A2methodFactory的? A a=am.createA();//当然标准的做法这个方法是不要对外暴露的 这样的实现根本就没有起到把我将选择的逻辑封装起来,我还要多加个工厂AmethodFactory 还得在上面加实现 用来“开闭”我需求的增加。 我认为为了开闭的话,下面的代码就够了 A a=new A1();反正客户端已经知道怎么选了,换个实现就行了嘛 A a=new A2(); A a=new A3(); A a=new A3(); 要加需求就在加个类实现A接口,在这里在new之就行了,非常的开闭了。似乎是没有必要弄什么工厂方法模式的。 但是工厂模式存在也是有他的原因的,不过不能按简单工厂的思路想,不妨按外观模式的思路想想。 客户端需要一个A的实现完成一定的功能,如 A a=new A1(); a.test(1); a.test2("soft");但是客户端其实不是需要a, 他需要的是个整体,是 a.test(1); a.test2("soft"); 于是需要外观模式封装之。。。 class Facade{ public void face(int i,String soft){ a.test(i); a.test2(soft); } } face方法里面的逻辑一般上是固定的。 但是问题是 face方法依赖的a是个接口,不是实现类。自然而然的需要加入所谓的工厂方法, 于是有: class Facade{ public abstract create(); public void face(int i,String soft){//关键是这个方法的逻辑比较固定,这时候用继承的方式更好 //继承的目的其实主要是这个方法在子类里面不用写了 A a=create(); a.test(i); a.test2(soft); } } 这个Facade就变成了一个工厂方法了。 所以很多设计模式在讲到 工厂方法模式的时候会说 里面的create方法最好不给外面调用的。因为其实客户端不是需要对象 A,是需要完成特定的功能,这里是face方法(他才是客户端真正需要的),只是这些功能实现又依赖A罢了。 工厂模式跟简单工厂设计理念是不同的,他没有将选择的逻辑封装,而更像是个外观模式的变体。 其实像下面的这种需求,根本就不需要使用工厂方法模式的: A a=new A1(); a.test();// 客户端就只调这么一个方法,没有其他更复杂的逻辑了 //如果手不jian实在不需要在搞个工厂方法模式出来。 大家觉得如何? 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2011-08-21
我表示看不懂
|
|
返回顶楼 | |
发表时间:2011-08-21
//Context是Android里的,该方法用来创建view public static <T extends BaseUnit> T createUnit(Class<T> cls,Context context) { BaseUnit bu = null; try { bu = (BaseUnit)Class.forName(cls.getName()).getConstructor(Context.class).newInstance(context); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } return (T)bu; } 我很懒,一般都这么用 |
|
返回顶楼 | |
发表时间:2011-08-22
请教一下
public class buildhouse(){ //根据不同的参数类型 ... public gethouse(args){ switch(args.type){ case "red":new redhouse(args).getHouse(); break; case "blue":new bluehouse(args).getHouse();break; } } ... } public interface house(){ void setcolor(args); void setwin(args); void setdoor(args); String getHouse(); } public class redhouse implements house{ void setcolor(args){color = args.color;} void setwin(args){ winnumber = args.winnum; } void setdoor(args) { door = 1; door.setColor("black"); door.setclock(1); } String getHouse(args){ this.setcolor(args); this.setwin(args); this.setdoor(args); }; } public class bluehouse implements house{ void setcolor(args){color = args.color;} void setwin(args){ winnumber = args.winnum; } void setdoor(args) { door = 2; door.setColor("yellow"); door.setclock(1); } String getHouse(args){ this.setcolor(args); this.setwin(args); this.setdoor(args); }; } 如果需要增加新类型的房子,需要做的事情: 1,增加一个新的类 2,修buildhouse()的调用 如果buildhouse()需要增加新的方法,需要做的事情: 1,在buildhouse()中增加方法 2,修改所有的子类 问题: class redhouse与class bluehouse中的方法,setcolor,setwin内容都是一样的,这样算代码重复吗? 第二种方式 public class buildhouse(){ ... public gethouse(args){ color = args.color; winnumber = args.winnum; if(args.type=="red") { door = 1; door.setColor("black"); } if(args.type=="blue"){ door = 2; door.setColor("yellow"); } door.setclock(1); } ... } 如果需要增加新类型的房子,需要做的事情: 需要修改gethouse的方法gethouse 问题: 每次需要修改代码的时候,都要修改gethouse.如果某些参数类型是不同的处理,又需要重新修改buildhouse. 如: public class buildhouse(){ ... public gethouse(args){ color = args.color; winnumber = args.winnum; if(args.type=="red") { door = 1; door.setColor("black"); } if(args.type=="blue"){ door = 2; door.setColor("yellow"); } if(args.type=="green"){ //新增加的类型的处理与原来的不同 door.setclock(3); }else{ door.setclock(1); } } ... } 两种方式相比,哪种比较好?原理是什么 |
|
返回顶楼 | |
发表时间:2011-08-22
我觉得楼主钻研的太细了。
工厂方法,外观模式从目的上来说,是完全不同的,没有必要放在一起讨论。 设计模式中,功能相近或者结构相似的模式有很多,不用像答题一样,花费大量时间,把各个细微之处都抠得这么仔细。 |
|
返回顶楼 | |
发表时间:2011-08-22
看不懂……
|
|
返回顶楼 | |
发表时间:2011-08-22
工厂方法模式最简单的说法就是:用一维的工厂族对应二维的产品族
|
|
返回顶楼 | |
发表时间:2011-08-22
我也表示看不懂
|
|
返回顶楼 | |
发表时间:2011-08-22
我硬是没看懂!
|
|
返回顶楼 | |
发表时间:2011-08-22
最应该关心的应该是某个模式是用于在什么环境下解决什么问题、怎么解决问题,以及为什么要这样解决问题的。很多文章太表面化、形式化,看了都懂,就是跟实际应用联系不上,过后全忘。
|
|
返回顶楼 | |