有一个建房子项目需求:
1)需要建一座房子:过程为打桩、砌墙、盖房顶
2)房子的种类有多种多样,但是建房子的过程是相同的
常见的思路是:创建一个房子抽象类,抽象类中有打桩、砌墙、盖房顶的抽象方法,然后房子的子类去实现这些方法,最后在客户端中使用即可。
抽象类
public abstract class AbstractHouse {
abstract void buildBasic();
abstract void buildWalls();
abstract void buildroof();
public void build(){
buildBasic();
buildWalls();
buildroof();
}
}
子类
public class CommonHouse extends AbstractHouse {
@Override
void buildBasic() {
System.out.println("普通房子打地基");
}
@Override
void buildWalls() {
System.out.println("普通房子建墙");
}
@Override
void buildroof() {
System.out.println("普通房子盖屋顶");
}
}
客户端
public class Client {
public static void main(String[] args) {
CommonHouse commonHouse=new CommonHouse();
commonHouse.build();
}
}
这种方式的缺点是把房子本身的属性和房子的创建过程耦合在一起了,程序的维护性和扩展性不好,解决这个问题我们需要使用建造者模式。
建造者模式
四种角色
1)product:一个具体的产品对象
2)Builder(抽象建造者):创建一个Product对象各个部件指定的接口
3)ConcreteBuilder:实现接口,构建和装配各个部件
4)Director(指挥者):构建一个使用Builder接口的对象
product
public class House {
private String basic;
private String wall;
private String roof;
public String getBasic() {
return basic;
}
public void setBasic(String basic) {
this.basic = basic;
}
public String getWall() {
return wall;
}
public void setWall(String wall) {
this.wall = wall;
}
public String getRoof() {
return roof;
}
public void setRoof(String roof) {
this.roof = roof;
}
}
抽象的建造者
public abstract class HouseBuilder {
public abstract void buildBasic();
public abstract void buildWall();
public abstract void buildroof();
public abstract House buildHouse();
}
具体的建造者
public class CommonHouse extends HouseBuilder {
protected House house=new House();
@Override
public void buildBasic() {
System.out.println("普通房子打地基");
}
@Override
public void buildWall() {
System.out.println("普通房子砌墙");
}
@Override
public void buildroof() {
System.out.println("普通房子建屋顶");
}
@Override
public House buildHouse() {
house.setBasic("地基深5米");
house.setWall("墙厚1米");
house.setRoof("屋顶厚1米");
return house;
}
}
指挥者
public class HouseDirector {
HouseBuilder houseBuilder=null;
public HouseDirector(HouseBuilder houseBuilder) {
this.houseBuilder = houseBuilder;
}
public House constructHouse(){
houseBuilder.buildBasic();
houseBuilder.buildWall();
houseBuilder.buildroof();
return houseBuilder.buildHouse();
}
}
客户端使用:
public class Client {
public static void main(String[] args) {
HouseDirector houseDirector=new HouseDirector(new CommonHouse());
House house=houseDirector.constructHouse();
System.out.println(house.getBasic());
}
}
建造者模式的优点:
1)客户端不需要知道产品内部组成的细节,使得产品本身和产品的 创建过程解耦,使得相同的创建过程可以创建不同的对象。
2)每一个具体的建造者都相对独立,便于替换或者扩展,用户使用不同的具体建造者即可得到不同的产品对象。增加新的具体建造者不需要修改原有类库的代码,符合开闭原则。
3)可以更加精细控制产品的创建过程,将复杂产品的创建步骤分解在不同的方法中,可以使创建过程更加清晰。