学习设计模式也有一段时间了,两个多月了。在这段时间里面,我从设计模式里面感受到设计模式无穷的魅力,并且解决了我工作中自己所负责的一个令整个公司头痛的模块(这个模块在“观察者模式”会讲)。我从自己的亲身实践及感受中,发现当系统复杂到一定程度,已经不是技术能够解决的问题了,所以我们要学习设计模式。
我为了巩固《设计模式》的学习成果,从今天开始每天写一篇文章讲述一种设计模式,把自己的学习感受及心得全部写在上面,欢迎各位进行讨论,并指出,大家共同进步!
常用的Java设计模式有二十四种设计模式,我将在这连续的二十四天内,把这些设计模式都写在自己的博客中,以便自己以后查看和方便各位查看!
这二十四种设计模式,按设计模式的意图(即模式所想要解决的问题)可以分为三大类:1、创建类模式;2、结构类模式;3、行为类模式。我们首先来看下这三类设计模式分别包含了哪些设计模式:
1、创建类模式:生成器模式,单例模式,抽象工厂模式,简单工厂模式,原型模式;
2、结构类模式:适配器模式,桥接模式,组合模式,装饰器模式,外观模式,享元模式,代理模式;
3、行为类模式:责任链模式,命令模式,解释器模式,观察者模式,迭代器模式,协调者模式,状态模式,空对象模式,
备忘录模式,策略模式,模板方法模式,访问者模式。
接下来,开始我们的常用“设计模式之旅”。这篇文章,我们首先来讲“生成器模式”。
定义:将一个复杂对象的构建与它的表示分离,使得相同的构建可以创建出不同的表示。
意图:复杂对象中的一些子对象的创建过程经常发生剧烈的变化(比如创建算法里面有多个分支,根据不同的参数创建不同的子对象,而创建算法进行参数传递),而组合子对象为复杂对象的算法却相对的稳定。这时用“生成器”模式,我们就是用它来分离变化的部分和相对稳定的部分。其实我个人理解是它总的来说要保持客户端的一个稳定性!
类图:
涉及的角色:
1、Product :产品,其实就是复杂对象,是最终生产出来的对象
2、Builder :生成器接口或抽象类,里面主要是对复杂对象的子对象生成算法的描述;
3、ConcreteBuilderA :具体的一个生成器实现,里面实现了生成各子对象的各种算法;
4、Director :借助生成器做最后的复杂对象组合工作;
示例:我们以组装笔记本电脑为例进行举例,目前的笔记本电脑产商有:HP,DELL,Lenover,Accer等
package service; /* * @功能 这个接口的功能是说明各电脑生产商是怎么来取得各个部件(子对象) */ public interface Builder { //CPU public void buildCPU(); //内存 public void buildRAM(); //硬盘 public void buildHDD(); //鼠标 public void buildMouse(); }
package impl; import service.Builder; /* * 惠普公司的各电脑配件情况 */ public class HPCompany implements Builder { @Override public void buildCPU() { System.out.println("CPU来自Intel"); } @Override public void buildHDD() { System.out.println("硬盘来自希捷"); } @Override public void buildMouse() { System.out.println("鼠标来自双飞燕"); } @Override public void buildRAM() { System.out.println("内存来自金士顿"); } }
package impl;
import service.Builder; /* * 联想公司的电脑配件情况 */ public class LenoverCompany implements Builder { @Override public void buildCPU() { System.out.println("CPU来自AMD"); } @Override public void buildHDD() { System.out.println("硬盘来自西数"); } @Override public void buildMouse() { System.out.println("鼠标来自双飞燕"); } @Override public void buildRAM() { System.out.println("内存来自威刚"); } }
package impl;
import service.Builder; public class Director { private Builder company; public void getHoleComputer() { company.buildCPU(); company.buildHDD(); company.buildRAM(); company.buildMouse(); System.out.println("笔记本电脑组装完成"); } public void setBuilder(Builder company) { this.company = company; } }
package client;
import impl.Director; import impl.HPCompany; import impl.LenoverCompany; public class TestClient { /** * @param args */ public static void main(String[] args) { Director direc = new Director(); //先组装惠普的电脑 System.out.println("------先组装惠普的电脑"); direc.setBuilder(new HPCompany()); direc.getHoleComputer(); //再组装联想的电脑 System.out.println("\n------再组装联想的电脑"); direc.setBuilder(new LenoverCompany()); direc.getHoleComputer(); } }
最后的输出结果如下:
总结:
1、生成器模式中有三种可变化的维度:子对象的生成算法、子对象的组合算法、子对象的数量,不管这三者中的哪一个
发生变化,客户端代码都是不会变化,所以这种设计模式很好地保证了客户端代码的稳定性!
2、生成器模式很好地将经常变化的部分(子对象的创建算法)与相对稳定的部分(子对象的组合算法)分离开来,保证了相对稳定算法代码的重用!
3、生成器模式与工厂模式的区别:1)工厂模式返回的是一个单一对象,而生成器模式返回的是对象的组合;2)工厂模式创建出来的对象之间不一定存在关系,但生成器模式创建的那些子对象之间是聚合关系
JDK中哪些用到生成器模式:
1)java.lang.StringBuilder#append();
2)java.lang.StringBuffer#append();
3)java.sql.PreparedStatement;
4)javax.swing.GroupLayout.Group#addComponent()