可乐穿越记之工厂方法
引子:
(接着上次的话题)可乐刚说完自己想法,正想要接着说就被旁边的大臣打断了。大臣说:“大哥你也忒聪明了,这方法好,谢谢了。”连忙拜过陛下就一阵小跑出去了,可乐就只好无奈的笑笑,对陛下说:“这位大哥真积极啊,还没说完就跑了,我敢说没几天他还得来。”
这不没过几天,可乐正准备和皇帝吃早饭呢,这位大臣急急忙忙又跑来了,皇帝就说道:“你还真算好时间,要不加个坐?”,“行啊。。。”,看着皇帝脸色不善,“谢陛下了,我就想请教一下可乐同学工厂事情”。可乐嘿嘿一笑,说:“我早猜到你要来,说吧什么问题”。于是大臣一五二十的向可乐说明了。原来啊,刚开始几天,感觉挺美的,手下也都轻松了许多,没事还能打打牌。可是最近为了提高装备,就引进一个新作坊,可是问题是,标准还是按照以前产品标准,可是到了工厂又不认了,没办法就改吧,就把工厂里面规则改了(就是修改简单工厂里面代码)。想想能轻松了吧,但是军队里面发现这个作坊制作的不好,只好要撤掉,又要修改工厂。大臣就想想以后再来个七八个折腾,他就晚年不保了,这不就一大早跑来了。
可乐说:“上次我没说完你就跑了,算了,那就让咱们一起分析一下这个问题。”
问题:
1.没办法添加或者删除新的类(上节简单工厂的不足之处)
2.如何在不影响其他类情况下,随意添加或者删除(设计模式中的目的解耦)
思考:
回想一下我们上次的产品,然后我们就会发现一个很特别地方,就是无论你怎么添加删除一个具体产品类,都不会影响其他类使用。ok!我们发现了,这就是我们接口(抽象)作用,进一步讲,我们的工厂就不能用这个方法么?当然可以,这就是今天要说的工厂方法。
分析:
首先就是我们昨天的产品代码不变,这里还是给出来吧。
这是我们武器接口
public interface Arms { void use(); void GetNumber(); }
下面是实现这个武器接口的具体产品类(这里我就给两个容易说明)
public class Sword:Arms { public void use() { Console.WriteLine("hit people with Sword"); } public int length; public int weight; public void GetNumber() { Console.WriteLine("length:"+this.length); Console.WriteLine("weigth:"+this.weight); } public Sword(int length_,int weight_) { this.length = length_; this.weight = weight_; } }
public class Spear:Arms { public void use() { Console.WriteLine("hit people with Spear"); } public int length; public int weight; public void GetNumber() { Console.WriteLine("length:" + this.length); Console.WriteLine("weigth:" + this.weight); } public Spear(int length_,int weight_) { this.length = length_; this.weight = weight_; } }
以上没什么,关键是工厂怎么解决?用接口
定义一个接口,并且重要的是里面有个方法是返回产品接口的
public interface Factory { Arms getArms(int length,int weight); }
当然是实现工厂接口的,我们把它叫做具体工厂
一个具体工厂对应一个具体产品类,所以我们就有两个具体工厂了
public class SwordFactory:Factory { public Arms getArms(int length, int weight) { return new Sword(length,weight); } }
public class SpearFactory : Factory { public Arms getArms(int length, int weight) { return new Spear(length, weight); } }
很轻松是吧,呵呵你们可以试试。
深入思考:
1.那么如果再来一个新的产品类怎么办呢?无非就是它实现该这个产品接口,并且为它对应一个具体工厂,该工厂实现工厂接口。
2.那么如果再来一个新的产品类,并且不能实现这个产品接口怎么办?问的好,那么你就要建立一个新的产品接口,对应的建立一个新的工厂接口(有没有点发现呢?下面总结再说)。
总结:
1.从该事件我们就可以发现简单工厂的一点使用条件:那就是不经常进行扩展,并且有要经常的使用类(要不断实例化类)。所以就是常说的随机应变,不能照搬死套,事务是两面性的,自己考量一下是要自由呢?还是简单?
2.在工厂方法里面的角色:
抽象产品,具体产品。这两个上次说过就偷懒了。
抽象工厂:定义具体工厂返回接口的方法。
具体工厂:实现抽象工厂
3.就是在思考里面发现一点,那就是
一个抽象产品 对应 一个抽象工厂
一个具体产品 有 一个具体工厂
4.工厂方法的适应设计原则
倒置原则----具体工厂实现抽象工厂
依赖原则----具体工厂弱依赖具体产品
开闭原则----产品和工厂就有很好扩展性了,但是我说事物是具有两面性的,
所以工厂方法还是满足了部分。可以这么想,如果现在对两个具体产品都添加新的品种,直白说把刀分为大小刀,把剑分为长剑短剑,那么工厂方法还适用么?请听下回分解。