设计模式--------建造者设计模式
1.什么是建造者模式?
在开发中
将一个复杂的对象的构建和它的表示分离,使得一个同样的构建过程可以创建不同的表示
在日常生活中
当我们日常生活中需要盖房子的时候,一班分为好几个步骤,打地基,砌墙,粉刷,装修等等一系列步骤,没钱的话我们可以自己干这些全部步骤,如果有钱我们可以雇佣工人来帮我们做这些事情,如果更有钱我们可以请设计师,设计师指挥工人得到我们需要的房子,如果工人是盖平房的,我们可以得到一座平房,如果工人是盖别墅的,我们可以得到别墅,我们可以根据我们想要的房子得特性,让设计师雇佣不同的工人,我们不用关心房子创建的过程,却可以得到我们想要的产品。
2.建造者模式的特点
建造者模式是一种创建型模式,适用于流程固定(如果差异过大,则不适合使用建造者模式),但组合不同的事物,而且使用建造者模式可以使客户端不必知道产品内部组成的细节。
3.建造者模式的结构
角色 | 描述 |
---|---|
Builder 抽象建造者 | 抽象的建造者,一般为接口或抽象类 |
ConcreteBuilder具体建造者 | 实现抽象建造者的所有方法,并返回一个产品 |
Product 产品 | 具体产品(被建造的对象) |
Director 指挥者(不是必须存在的) | 指挥建造者建造产品,有时候建造者自己会做指挥者 |
4.代码展示
Product
package org.best.common;
/**
* 产品
*/
public class House {
//地基
private String foundation;
//围墙
private String wall;
//粉刷
private String paint;
//装修
private String remodel;
//省略GETTER,SETTER,toString
}
抽象建造者
/**
* 抽象建造者
*/
public interface Builder {
/**
* 打地基
*/
void doFoundation();
/**
* 砌墙
*/
void doWall();
/**
* 粉刷
*/
void doPaint();
/**
* 装修
*/
void doRemodel();
/**
* 得到产品
* @return
*/
House doHouse();
}
实际建造者
package org.best.common;
/**
* 实际建造者(平房)
*/
public class BungalowBuilder implements Builder{
private House house=new House();
@Override
public void doFoundation() {
house.setFoundation("平房地基");
}
@Override
public void doWall() {
house.setWall("平房围墙");
}
@Override
public void doPaint() {
house.setPaint("大白");
}
@Override
public void doRemodel() {
house.setRemodel("中式装修");
}
@Override
public House doHouse() {
return house;
}
}
/**
* 实际建造者(别墅)
*/
public class VillaBuilder implements Builder {
private House house=new House();
@Override
public void doFoundation() {
house.setFoundation("别墅地基");
}
@Override
public void doWall() {
house.setWall("别墅围栏");
}
@Override
public void doPaint() {
house.setPaint("壁纸");
}
@Override
public void doRemodel() {
house.setRemodel("欧式装修");
}
@Override
public House doHouse() {
return house;
}
}
指挥者
/**
* 指挥者
*/
public class Director {
public House createHouse(Builder builder) {
builder.doFoundation();
builder.doWall();
builder.doPaint();
builder.doRemodel();
return builder.doHouse();
}
}
测试类
public class Test {
public static void main(String[] args) {
Director director = new Director();
House house = director.createHouse(new VillaBuilder());
System.out.println(house);
House house1 = director.createHouse(new BungalowBuilder());
System.out.println(house1);
}
}
//输出结果
House{foundation='别墅地基', wall='别墅围栏', paint='壁纸', remodel='欧式装修'}
House{foundation='平房地基', wall='平房围墙', paint='大白', remodel='中式装修'}
在我们开发过程中,我们有时候的对象会有很多个参数,如果每次都一个一个都通过构造函数或者set方法,那也太累了,有的时候甚至参数个数不同还需要改构造函数,这时候,我们可以使用建造者模式来解决这个问题(以上面的房子为例)
1.使用静态内部类的方式
package org.best.common;
/**
* 产品
*/
public class House {
//地基
private String foundation;
//围墙
private String wall;
//粉刷
private String paint;
//装修
private String remodel;
public House() {
}
public House(HouseBuilder houseBuilder) {
this.foundation = houseBuilder.foundation;
this.wall = houseBuilder.wall;
this.paint = houseBuilder.paint;
this.remodel = houseBuilder.remodel;
}
public static class HouseBuilder{
//地基
private String foundation;
//围墙
private String wall;
//粉刷
private String paint;
//装修
private String remodel;
public HouseBuilder setFoundation(String foundation){
this.foundation=foundation;
return this;
}
public HouseBuilder setWall(String wall){
this.wall=wall;
return this;
}
public HouseBuilder setPaint(String paint){
this.paint=paint;
return this;
}
public HouseBuilder setRemodel(String remodel){
this.remodel=remodel;
return this;
}
public House build(){
return new House(this);
}
}
}
如果以上这种方式你觉得不好理解,你也可以采用下面这种方式,缺点就是会增加一些类
public class HouseBuilder {
private House house=new House();
public HouseBuilder setFoundation(String foundation){
house.setFoundation(foundation);
return this;
}
public HouseBuilder setWall(String wall){
house.setWall(wall);
return this;
}
public HouseBuilder setPaint(String paint){
house.setPaint(paint);
return this;
}
public HouseBuilder setRemodel(String remodel){
house.setRemodel(remodel);
return this;
}
public House build(){
return house;
}
}
测试
public class Test {
public static void main(String[] args) {
House house2 = new HouseBuilder().setFoundation("自建房").setWall("刮腻子").setPaint("大白").setRemodel("不装修").build();
System.out.println(house2);
House house3 = new House.HouseBuilder().setPaint("高层楼房").setWall("围栏").setPaint("壁纸").setRemodel("精装").build();
System.out.println(house3);
}
}
5.建造者模式的优缺点
优点
- 将创建产品的步骤和产品分离,使得使用相同的步骤可以得到不同的产品。
- 解耦合,每个建造者都是独立的互不影响。
缺点
- 适用于产品具有相同的特点,如果差别过大则不适用。
- 如果产品发生变化,则建造者都需要改变。