建造者模式(生成器模式)
功能:将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的表示。
优点:
客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象。
每一个具体建造者都独立,因此可以方便地替换具体建造者或增加新的具体建造者, 用户使用不同的具体建造者即可得到不同的产品对象 。
可以更加精细地控制产品的创建过程 。将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰,也更方便使用程序来控制创建过程。
增加新的具体建造者无须修改原有类库的代码,指挥者类针对抽象建造者类编程,系统扩展方便,符合“开闭”。
缺点:
建造者模式所创建的产品一般具有较多的共同点,其组成部分相似,若产品之间的差异性很大,则不适合使用
该模式,因此其使用范围受到一定限制。
若产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大。
模式应用:
很多游戏软件中,地图包括天空、地面、背景等组成部分,人物角色包括人体、服装、装备等组成部分,
可以使用建造者模式对其进行设计,通过不同的具体建造者创建不同类型的地图或人物
建造者模式,英文名builder_pattern,抛开所有文献对建造者模式的定义,我认为建造者模式是当我们
现有的资源无法满足我们的业务的时候,我们进行的一个统一的建造或者改造的一个过程,或者说是一个代码
的封装,我们可以叫它为建造者模式。
我曾经做过一个这样的模块,一个业务系统,数据产生在子系统A里面,同时子系统B需要A所产生的数据,但是需要经过"改造"和"加工",我们打个比方,假如A得到了一个关于交易的情况的一个Json类型的数据包,给B的时候也许有一些属性和字段不需要,或者A没有的而B却需要进行自主的构建,其实假如我们只有这一项的话,完全不需要使用到设计模式,但是假如A和B之间需要交换的数据种类非常的多,并且有可能C系统也会参与进来,甚至D系统也来了。。。这个时候我们不得不想一个统一的办法来管理它们,没错,就是建造者模式。
举例: KFC套餐
套餐是一个复杂对象,一般包含主食(如汉堡、鸡肉卷等)和饮料(如果汁、 可乐等)等部分,不同的套餐有不同的组成部分,而KFC的服务员可以根据顾客的要求,一步一步装配这些组成部分,构造一份完整的套餐,然后返回给顾客。
代码和使用案例:
package com.xxx.demo;
/**
* CLASSNAME:SmsSender
* AUTHOR:邓望保 lenovo
* 邮箱:411085214@qq.com
* 电话:18665996821
* DATE:2018/3/10 23:30
* 描述1: 创建型模式--建造者模式
* 描述2: 第一步兴建一个基本类
*/
public class SmsSender {
private String id;
private String name;
public SmsSender(String id, String name) {
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "SmsSender{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
'}';
}
}
package com.xxx.demo;
/**
* CLASSNAME:SendBuilder
* AUTHOR:邓望保 lenovo
* 邮箱:411085214@qq.com
* 电话:18665996821
* DATE:2018/3/10 23:38
* 描述1:建设者模式 --》第三步 穿件建设者
* 描述2:
*/
public interface SendBuilder {
public void buildSender(SmsSender sender);
public MailSender getMailSender();
}
2.新建MailSender 有上面两个属性外,还增加了其他属性
package com.xxx.demo;
/**
* CLASSNAME:MailSender
* AUTHOR:邓望保 lenovo
* 邮箱:411085214@qq.com
* 电话:18665996821
* DATE:2018/3/10 23:35
* 描述1: 建设者模式--模拟场景
* 描述2:第二步, 创建Mail发送者
*/
public class MailSender {
private String id;
private String name;
private String age;
private String address;
private String type;
public MailSender() {
}
public MailSender(String id) {
this.id = id;
}
public MailSender(String id, String name, String age, String address, String type) {
this.id = id;
this.name = name;
this.age = age;
this.address = address;
this.type = type;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
@Override
public String toString() {
return "MailSender{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", age='" + age + '\'' +
", address='" + address + '\'' +
", type='" + type + '\'' +
'}';
}
}
3.创建建设者
package com.xxx.demo;
/**
* CLASSNAME:SendBuilder
* AUTHOR:邓望保 lenovo
* 邮箱:411085214@qq.com
* 电话:18665996821
* DATE:2018/3/10 23:38
* 描述1:建设者模式 --》第三步 创建建设者
* 描述2:
*/
public interface SendBuilder {
public void buildSender(SmsSender sender);
public MailSender getMailSender();
}
第四步:创建具体建设者
package com.xxx.demo;
/**
* CLASSNAME:ConcreateBuilder
* AUTHOR:邓望保 lenovo
* 邮箱:411085214@qq.com
* 电话:18665996821
* DATE:2018/3/10 23:40
* 描述1:创建者设计模式 第四步,创建具体构建者
* 描述2:
*/
public class ConcreateBuilder implements SendBuilder {
private MailSender mMailSender;
public ConcreateBuilder() {
mMailSender = new MailSender();
}
@Override
public void buildSender(SmsSender smsSender) {
mMailSender.setId(smsSender.getId());
mMailSender.setName(smsSender.getName());
mMailSender.setAge("18");
mMailSender.setAddress("china");
}
@Override
public MailSender getMailSender() {
return mMailSender;
}
}
第五: 创建导演类
package com.xxx.demo;
/**
* CLASSNAME:Director
* AUTHOR:邓望保 lenovo
* 邮箱:411085214@qq.com
* 电话:18665996821
* DATE:2018/3/10 23:46
* 描述1:建设者设计模式 第五步
* 描述2:创建导演者类,用于构造的一个指挥,get和set具体的bean对象
*/
public class Director {
private SendBuilder mBuilder=new ConcreateBuilder();
public MailSender getMailSender(SmsSender smsSender){
mBuilder.buildSender(smsSender);//构建
return mBuilder.getMailSender();//获取
}
}
最后测试:
package com.xxx.demo;
/**
* CLASSNAME:Test
* AUTHOR:邓望保 lenovo
* 邮箱:411085214@qq.com
* 电话:18665996821
* DATE:2018/3/10 23:49
* 描述1: 建设者模式(创建型设计模式) 第五步
* 描述2: 测试验证结果
*/
public class Test {
public static void main(String[] args) {
SmsSender smsSender = new SmsSender("1", "kitty");
Director director = new Director();
MailSender mailSender = director.getMailSender(smsSender);
System.out.println(mailSender);
}
}
运行结果:
MailSender{id='1', name='kitty', age='18', address='china', type='null'}