设计模式之工厂方法模式和开放-封闭原则
2017-03-23 12:19
316 查看
设计模式之工厂方法模式和开放-封闭原则
以下所有仅供记录和参考,如有问题,请留言提出,感谢!转载注明出处。
关于简单工厂模式参见之前写的设计模式之简单工厂模式。
在记录简单工厂模式的时候有提到这么一句话:简单工厂模式是工厂模式的特殊情况。其实话也不能这么说,研究了工厂方法模式之后,才发现,它是基于面向对象的“开放-封闭原则”而对简单工厂模式进行的改进。而且在记录简单工厂模式的那篇中,对于其缺点的描述说了一个“违反了‘高内聚责任分配原则’”,其实我也不懂这个原则。不过简单工厂模式确实违背了“开放-封闭原则”。
那么,就先记录一下面向对象的“开放-封闭原则”(The Open-Closeed Principle),简称OCP。
所谓的开放-封闭原则(以下用OC原则代替)说的是:对于软件设计来说,无论是类,模块,函数等,可以扩展,但是不可以修改。意思是:对于扩展是开放的,对于修改是封闭的。举个例子:假如你设计实现了一个PC端的枪战游戏叫做“穿越毛线”,那么为了玩家能够对游戏保持新鲜感,那么就得每隔一段时间对游戏进行一次更新。在更新的时候,就不能违背“OC原则”。意思就是,你可以对游戏的源码进行扩展,但是不能对原有的代码进行修改(不含修复bug的情况)。如果你对源码进行了修改,那么就说明这款游戏在设计的时候没有遵循OC原则,同时这个软件的维护性和扩展性就显得很糟糕。所以这就要求了在软件设计的时候,需要遵循OC原则,为以后的版本升级扩展,以及后期的维护提供方便。
针对于面向对象而言,OC原则提出:设计好一个类之后,就尽量不要再修改。但是 ,绝对的封闭是不可能做到的,不可能设计出来一个完美的永远不需要修改的类(假设设计的软件可以不断的更新)。那么,如何尽可能的设计出一个合理的封闭代码,我们可以在软件设计的时候,先假设变化不会发生,而当变化出现时,再使用继承和多态来对变化进行抽象隔离(创建父类,接口等,通过多态和继承对变化进行隔离)。当然,变化出现的越早越好,如果出现的晚了,用软件工程中的话来讲就是:问题出现的越晚,修复付出的代价越大。
总而言之,OC原则的精神在于:面对新的需求时,我们只需要对增加代码,而不需要修改已经存在的代码。这样,才能体现出面向对象设计中的提到的,可维护性,可扩展性,可复用性,灵活性好。
注:以上部分内容来自《大话设计模式》一书,感谢。
大概记录了一下OC原则。结合此原则和简单工厂模式来看,继续“农民伯伯买化肥”例子,在例子中,如果需要添加一种新的化肥,首先,得添加这个新化肥的类,并让此类继承化肥类,这块的代码就是对原有代码的扩展,而没有修改,遵循了开放-封闭原则。然后还得在化肥工厂类(Factory)的switch-case选择结构中添加一组新的选择,那么这就意味着,打开了Factory类,进行了代码的修改,而这就违反了开放-封闭原则。那么,按照上面所说的,在变化出现的时候,使用继承和多态来进行抽象隔离。所以,在化肥工厂Factory类这块,可以仿照化肥类Fertilizer那样,抽象出一个总的工厂接口或者父类,然后将每种化肥重新封装成一个单独的类去继承工厂类。在需要化肥对象的时候,通过多态的方式进行对象的创建。这样就使用了继承和多态的性质对原有的变化进行了抽象隔离。如果现在需要重新添加一种新的化肥,那么只需要封装新化肥的类,让它继承工厂类就可以了。这就是只对原有代码进行了扩展,而没有修改代码,从而遵循了开放-封闭原则。
下面用Java代码进行简单例子展示,依然使用在简单工厂模式中使用的例子:
化肥类,及其子类代码,这里添加了新的化肥有机肥(OrganicFertilizer):
工厂类,将原有的工厂改造成一个抽象类,而重新对每种化肥进行了封装,并继承工厂类:
再看看主类Farmer怎么写:
总结:从表面上来看,工厂方法模式似乎比简单工厂模式更加繁琐,因为没增加一种“化肥”,不仅要增加化肥类,还要添加一个对应化肥的工厂类。确实是更加麻烦了,但是工厂方法模式的优点在于,提高了代码的扩展性,灵活性,克服了简单工厂模式中需要修改代码的做法。这在面向对象编程中是特别重要的。
除此之外,会发现,简单工厂模式和工厂方法模式都有一个共同点,那就是:在农民伯伯需要发生变化的情况下,还是需要对Farmer类进行修改,进而获取需要的化肥,这个修改在这两种工厂模式中是没有办法避免的,但是利用反射机制可以解决这种情况
,以后再说。
以下所有仅供记录和参考,如有问题,请留言提出,感谢!转载注明出处。
关于简单工厂模式参见之前写的设计模式之简单工厂模式。
在记录简单工厂模式的时候有提到这么一句话:简单工厂模式是工厂模式的特殊情况。其实话也不能这么说,研究了工厂方法模式之后,才发现,它是基于面向对象的“开放-封闭原则”而对简单工厂模式进行的改进。而且在记录简单工厂模式的那篇中,对于其缺点的描述说了一个“违反了‘高内聚责任分配原则’”,其实我也不懂这个原则。不过简单工厂模式确实违背了“开放-封闭原则”。
那么,就先记录一下面向对象的“开放-封闭原则”(The Open-Closeed Principle),简称OCP。
所谓的开放-封闭原则(以下用OC原则代替)说的是:对于软件设计来说,无论是类,模块,函数等,可以扩展,但是不可以修改。意思是:对于扩展是开放的,对于修改是封闭的。举个例子:假如你设计实现了一个PC端的枪战游戏叫做“穿越毛线”,那么为了玩家能够对游戏保持新鲜感,那么就得每隔一段时间对游戏进行一次更新。在更新的时候,就不能违背“OC原则”。意思就是,你可以对游戏的源码进行扩展,但是不能对原有的代码进行修改(不含修复bug的情况)。如果你对源码进行了修改,那么就说明这款游戏在设计的时候没有遵循OC原则,同时这个软件的维护性和扩展性就显得很糟糕。所以这就要求了在软件设计的时候,需要遵循OC原则,为以后的版本升级扩展,以及后期的维护提供方便。
针对于面向对象而言,OC原则提出:设计好一个类之后,就尽量不要再修改。但是 ,绝对的封闭是不可能做到的,不可能设计出来一个完美的永远不需要修改的类(假设设计的软件可以不断的更新)。那么,如何尽可能的设计出一个合理的封闭代码,我们可以在软件设计的时候,先假设变化不会发生,而当变化出现时,再使用继承和多态来对变化进行抽象隔离(创建父类,接口等,通过多态和继承对变化进行隔离)。当然,变化出现的越早越好,如果出现的晚了,用软件工程中的话来讲就是:问题出现的越晚,修复付出的代价越大。
总而言之,OC原则的精神在于:面对新的需求时,我们只需要对增加代码,而不需要修改已经存在的代码。这样,才能体现出面向对象设计中的提到的,可维护性,可扩展性,可复用性,灵活性好。
注:以上部分内容来自《大话设计模式》一书,感谢。
大概记录了一下OC原则。结合此原则和简单工厂模式来看,继续“农民伯伯买化肥”例子,在例子中,如果需要添加一种新的化肥,首先,得添加这个新化肥的类,并让此类继承化肥类,这块的代码就是对原有代码的扩展,而没有修改,遵循了开放-封闭原则。然后还得在化肥工厂类(Factory)的switch-case选择结构中添加一组新的选择,那么这就意味着,打开了Factory类,进行了代码的修改,而这就违反了开放-封闭原则。那么,按照上面所说的,在变化出现的时候,使用继承和多态来进行抽象隔离。所以,在化肥工厂Factory类这块,可以仿照化肥类Fertilizer那样,抽象出一个总的工厂接口或者父类,然后将每种化肥重新封装成一个单独的类去继承工厂类。在需要化肥对象的时候,通过多态的方式进行对象的创建。这样就使用了继承和多态的性质对原有的变化进行了抽象隔离。如果现在需要重新添加一种新的化肥,那么只需要封装新化肥的类,让它继承工厂类就可以了。这就是只对原有代码进行了扩展,而没有修改代码,从而遵循了开放-封闭原则。
下面用Java代码进行简单例子展示,依然使用在简单工厂模式中使用的例子:
化肥类,及其子类代码,这里添加了新的化肥有机肥(OrganicFertilizer):
public abstract class Fertilizer { public abstract void getFertilizer(); } public class K extends Fertilizer{ public void getFertilizer() { System.out.println("got K"); } } public class N extends Fertilizer{ public void getFertilizer() { System.out.println("got N"); } } public class P extends Fertilizer{ public void getFertilizer() { System.out.println("got P"); } } public class OrganicFertilizer extends Fertilizer{ public void getFertilizer() { System.out.println("got OrganicFertilizer"); } }
工厂类,将原有的工厂改造成一个抽象类,而重新对每种化肥进行了封装,并继承工厂类:
public abstract class Factory { public abstract Fertilizer creatFertilizer(); } public class KFactory extends Factory{ public Fertilizer creatFertilizer() { return new K(); } } public class NFactory extends Factory{ public Fertilizer creatFertilizer() { return new N(); } } public class PFactoty extends Factory{ public Fertilizer creatFertilizer() { return new P(); } } public class OrganicFertilizerFactory extends Factory{ public Fertilizer creatFertilizer() { return new OrganicFertilizer(); } }
再看看主类Farmer怎么写:
public class Farmer { public static void main(String[] args) { //Factory factory = new KFactory(); //利用多态,先创建出来对应的K化肥工厂实例 //Fertilizer fertilizer = factory.creatFertilizer();//工厂生产对应的K化肥对象 //fertilizer.getFertilizer(); //获取K化肥 Factory factory = new OrganicFertilizerFactory(); //如果需要更换化肥,就只需要改变这块new的工厂对象 Fertilizer fertilizer = factory.creatFertilizer(); //这里的代码不用改变 fertilizer.getFertilizer(); //这的代码也不用改变 } }
总结:从表面上来看,工厂方法模式似乎比简单工厂模式更加繁琐,因为没增加一种“化肥”,不仅要增加化肥类,还要添加一个对应化肥的工厂类。确实是更加麻烦了,但是工厂方法模式的优点在于,提高了代码的扩展性,灵活性,克服了简单工厂模式中需要修改代码的做法。这在面向对象编程中是特别重要的。
除此之外,会发现,简单工厂模式和工厂方法模式都有一个共同点,那就是:在农民伯伯需要发生变化的情况下,还是需要对Farmer类进行修改,进而获取需要的化肥,这个修改在这两种工厂模式中是没有办法避免的,但是利用反射机制可以解决这种情况
,以后再说。
相关文章推荐
- 设计模式--工厂模式.策略模式.单一职责原则.开放封闭原则.依赖倒转原则
- 设计模式-开放封闭原则
- 设计模式之开放--封闭原则学习
- 设计模式原则(单一、开放封闭、里氏代换、依赖倒转、迪米特法则五大原则)
- 设计模式原则--开放-封闭原则
- 设计模式-开放封闭原则
- 致我们工作中的设计模式之设计原则---开放封闭原则
- 设计模式学习之开放封闭原则与依赖倒置原则
- 设计模式原则----开放封闭原则
- [设计模式原则]第六回:开放封闭原则
- Java设计模式(一)设计模式的原则、工厂方法和抽象工厂
- 设计模式(工厂方法)与软件开发原则
- 设计模式原则(单一、开放封闭、里氏代换、依赖倒转、迪米特法则五大原则)
- 设计模式-----开放--封闭原则
- 设计模式之开放--封闭原则学习
- 设计模式之开放封闭原则
- 五 单一职责、开放—封闭、依赖倒转原则——设计模式学习笔记
- 设计模式-开放封闭原则
- 设计模式六大原则--开放-封闭原则
- 设计模式学习--面向对象的5条设计原则之开放封闭原则--OCP