如果想成为一名更优秀的软件设计师,了解优秀软件的演变过程比学习优秀设计本省=身更有价值,因为设计的演变过程中蕴藏着大智慧。 ——《重构与模式》
最近在看《大话设计模式》这本书,以前只是大概的学习了一下设计模式,这次希望打算系统的学习一下软件开发中的设计模式,并且产出一些自己的理解,实践出真理,单纯的看书可能只是纸上谈兵,但是系统的学习一下还是很有必要的,就像很多成熟的数据结构都是通过前人编程经验总结的,这本《大话设计模式》不想一些计算机编程类的书集中在讲授一个优秀的软件设计样例或解决方案,而是重在讲诉软件一步步的演变过程,深入浅出,贴近生活,比较容易进入学习状态。
一.面向对象编程
编程初学者碰到问题总是直觉地用计算机的方式去思考怎么解决这本身没有错误,但是这种程序只为了满足当前需求,不容易实现后续的扩展,维护,复用,不足以称为高质量的代码。
三国时期,曹操大胜,宴请文武,诗性大发,不觉吟道:“喝酒唱歌,人生真爽!”众文武齐呼:“丞相好诗啊!”于是一臣子速命印刷工匠刻版印刷一样,以便流传千古。样板拿出来曹操一看,太粗俗了,不妥不妥,应改为“对酒当歌,人生真爽!”工匠只能连夜重刻,心中叫苦不迭。第二天样板再经丞相过目,心觉还是不妥,再改:“对酒当歌,人生几何!”。工匠当即晕倒在地。。。可是,如果有活字印刷的话,只需要改四个字就行了,岂不妙哉。
更改只需改字,谓之可维护;字可以重复使用,谓之可复用;添加在造字即可,谓之可扩展;移动字块就可以实现竖版,谓之灵活性高。古代四大发明中火药,造纸术,指南针都是从无到有的科技创新,而活字印刷是思维的进步。打比喻容易让人丧失对细节的理解和大脑真正的思考,但确实是新手入门的一个好的手段。
面向对象的思维就是通过封装,继承,多态,抽象把程序的耦合降低,易于维护,复用,扩展等。面向对象的设计模式就是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结。
二.简单工厂模式
简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(产品类继承自一个父类或接口)的实例。
该模式中包含的角色及其职责:
工厂:简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类的创建产品类的方法可以被外界直接调用,创建所需的产品对象。
抽象产品:简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。
具体产品:是简单工厂模式的创建目标,所有创建的对象都是充当这个角色的某个具体类的实例。
例子:本次我用水果作为抽象产品,苹果和橘子作为具体产品,并且通过普通的传值方法判断和反射实现简单工厂。
抽象产品(水果):
package simplefactory;
/**
* 定义产品的抽象接口 水果
* @author liucong
*/
public interface Fruit {
/**
* 定义吃水果的感觉
*/
public void eatFeel();
}
具体产品(苹果,橘子):
package simplefactory;
/**
* 苹果
* @author liucong
*/
public class Apple implements Fruit {
@Override
public void eatFeel() {
System.out.println("苹果味道很甜,但我不喜欢吃。");
}
}
package simplefactory;
/**
* 橘子
* @author liucong
*/
public class Orange implements Fruit {
@Override
public void eatFeel() {
System.out.println("橘子很酸,但我很喜欢吃。");
}
}
普通简单工厂:
package simplefactory;
/**
* 生产水果的简单工厂
* @author liucong
*/
public class SampleFruitFactory {
/**
* 生产水果的静态方法
* @param fruitType 水果类型
* @return
*/
public static Fruit productFruit(String fruitType){
if ("apple".equals(fruitType)) {
Fruit apple = new Apple();
System.out.println("生产了一个苹果");
return apple;
} else if("orange".equals(fruitType)) {
Fruit orange = new Orange();
System.out.println("生产了一个橘子");
return orange;
} else {
System.out.println("目前不能生产此水果");
return null;
}
}
}
通过反射实现的简单工厂:
package simplefactory;
/**
* 通过反射实现简单工厂
* @author liucong
*/
public class SampleFruitFactoryByReflection {
/**
* @param c xx.class
* @return 水果
* @throws ClassNotFoundException 异常
* @throws IllegalAccessException 异常
* @throws InstantiationException 异常。。。
*/
public static Fruit productFruit(Class c) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
Fruit fruit = (Fruit) Class.forName(c.getName()).newInstance();
return fruit;
}
}
测试类:
package simplefactory;
/**
* 测试类
* @author liucong
*/
public class SampleFactoryTest {
public static void main(String[] args) throws IllegalAccessException, InstantiationException, ClassNotFoundException {
// 给了个苹果,应该生产出苹果
Fruit fruit = SampleFruitFactoryByReflection.productFruit(Apple.class);
fruit.eatFeel();
}
}
测试结果: