随笔分类
对象创建型模式
建造者模式
生成器模式
对象创建型模式之一
用来隐藏复合对象的创建过程,把复合对象的创建过程加以抽象,通过子类继承和重载的方式,动态地创建具有复合属性的对象
为什么会有这么模式呢?
当一个类的内部数据过于复杂的时候,要创建的话可能就需要了解这个类的内部数据,以及这些东西是怎样组织装配之类的,学习成本过高且较为混乱,这时候
就需要一个法子来管理下这个类中的数据,以至于不那么混乱,怎么让它在创建时不那么混乱且代码的可读性较好,不至于看花了眼,且自己想要的东西都能很好地进行创建设置呢?这便是建造者模式的应用场景了
先来看一段代码
public class House {
// 可以是其它类的对象,不一定是String -- 复合对象
private String floor;
private String wall;
private String roof;
public String getFloor() {
return floor;
}
public void setFloor(String floor) {
this.floor = floor;
}
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 class MainClass {
public static void main(String[] args) {
// 客户直接来创建房子 房子和客户之间高耦 high coupling //不可能什么都交给客户去实现
House house = new House();
house.setFloor("窗户");
house.setRoof("屋顶");
house.setWall("墙壁");
}
}
实际应用中也不可能让客户自己去修房子(学习成本太高),肯定是去找中介或代理商之类的,这样也解耦了客户和房子
以下实现客户与工程队的交互实现房子的创建
代码实现
/**
* 工程队
*/
public interface HouseBuilder {
void makeFloor();
void makeWall();
void makeRoof();
//交付产品
House makeHouse();
}
/**
* 平房的工程队
*/
public class PingFangBuilder implements HouseBuilder{
House house = new House();
@Override
public void makeFloor() {
house.setFloor("平房---->floor");
}
@Override
public void makeWall() {
house.setWall("平房---->wall");
}
@Override
public void makeRoof() {
house.setRoof("平房---->roof");
}
@Override
public House makeHouse() {
this.makeFloor();
this.makeRoof();
this.makeWall();
return house;
}
}
public class House {
// 可以是其它类的对象,不一定是String -- 复合对象
private String floor;
private String wall;
private String roof;
public String getFloor() {
return floor;
}
public void setFloor(String floor) {
this.floor = floor;
}
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 class MainClass {
public static void main(String[] args) {
// 客户直接来创建房子 房子和客户之间高耦 high coupling //不可能什么都交给客户去实现
// House house = new House();
// house.setFloor("窗户");
// house.setRoof("屋顶");
// house.setWall("墙壁");
HouseBuilder houseBuilder = new PingFangBuilder();
House house = houseBuilder.makeHouse();
System.out.println(house.getFloor()); //平房---->floor
System.out.println(house.getRoof()); //平房---->roof
System.out.println(house.getWall()); //平房---->wall
}
}
以上设计思想虽然能得到预期的房子,但是实际上客户是不可能直接去和工程队font>进行交互,得通过一个设计师 director来进行交互,设计师直接根据工程队类型再进行交互来创建房子,当然最终房子的获得仍然是从工程师那里获得,但是可以稍微进行封装表面上看是从设计师那里得到房子
代码实现
/**
* 工程队
*/
public interface HouseBuilder {
void makeFloor();
void makeWall();
void makeRoof();
//交付产品
House getHouse();
}
/**
* 房子的设计者来指挥工程队
*/
public class HouseDirector {
public House makeHouse(HouseBuilder houseBuilder){
houseBuilder.makeFloor();
houseBuilder.makeRoof();
houseBuilder.makeWall();
return houseBuilder.getHouse();
}
}
public class ApartmentBuilder implements HouseBuilder{
House house = new House();
@Override
public void makeFloor() {
house.setFloor("公寓---->floor");
}
@Override
public void makeWall() {
house.setWall("公寓---->wall");
}
@Override
public void makeRoof() {
house.setRoof("公寓---->roof");
}
@Override
public House getHouse() {
return house;
}
}
/**
* 平房的工程队
*/
public class PingFangBuilder implements HouseBuilder{
House house = new House();
@Override
public void makeFloor() {
house.setFloor("平房---->floor");
}
@Override
public void makeWall() {
house.setWall("平房---->wall");
}
@Override
public void makeRoof() {
house.setRoof("平房---->roof");
}
@Override
public House getHouse() {
// this.makeFloor();
// this.makeRoof();
// this.makeWall();
return house;
}
}
public class House {
// 可以是其它类的对象,不一定是String -- 复合对象
private String floor;
private String wall;
private String roof;
public String getFloor() {
return floor;
}
public void setFloor(String floor) {
this.floor = floor;
}
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 class MainClass {
public static void main(String[] args) {
// 客户直接来创建房子 房子和客户之间高耦 high coupling //不可能什么都交给客户去实现
// House house = new House();
// house.setFloor("窗户");
// house.setRoof("屋顶");
// house.setWall("墙壁");
// HouseBuilder houseBuilder = new PingFangBuilder();
// House house = houseBuilder.getHouse();
//改为设计者
//HouseBuilder houseBuilder = new PingFangBuilder();
HouseBuilder houseBuilder = new ApartmentBuilder();
HouseDirector houseDirector = new HouseDirector();
House house = houseDirector.makeHouse(houseBuilder);
System.out.println(house.getFloor()); //公寓---->floor
System.out.println(house.getRoof()); //公寓---->roof
System.out.println(house.getWall()); //公寓---->wall
}
}
由设计师根据具体类型的工程队去创建房子,设计思想理念也和现实生活中较为贴切
director在Builder模式中具有很重要的任务,它用于指导具体的构建者如何来构建产品,控制调用的先后顺序,并向调用者返回完整的产品类
优点
- 使用建造者模式可以让客户端不必知道产品的内部组成结构
- 具体的建造者之间是相互独立的,有利于系统的扩展,且可以在建造的过程中逐渐进行细化,而不会对其他模块产生任何影响
缺点
- 建造者模式所创建的产品一般具有较多的共同点,其组成部分相似;如果产品之间的差异性很大,则不适合使用建造者模式进行创建,因此其使用范围也受到一定的限制
- 如果产品的内部变化十分复杂,那么可能就需要较多具体的建造者来实现这种变化,导致系统变得十分膨胀
应用场景
- 对象的创建:Builder模式就是为对象的创建而设计的模式
- 创建的是一个复合对象:被创建的对象是一个具有复合属性的对象
- 关注对象创建的各部分的创建过程:不同的工厂(Builder生成器)对产品属性有着不同的创建方法
与抽象工厂进行比较
- 与抽象工厂相比,建造者模式是返回一个各部件组装好的完整产品,而抽象工厂模式是返回一系列相关的产品,这些产品位于不同的产品结构等级,构成了一个产品族
- 在抽象工厂中,客户端实例化具体工厂(多态),然后再调用具体的工厂方法来获取所需的产品对象;而建造者模式中,客户端不能直接去调用建造者相关方法,而是通过指挥者类 director来指导建造者如何来生成对象,包括这个对象的组装和建造步骤,它侧重于一步步构造一个复杂对象,返回一个完整的对象
- 如果将抽象工厂比作一个汽车配件生产工厂,生产一个产品族的产品,那么建造者模式就是一个汽车组装工厂,负责汽车部件的组装并且返回一个完整的汽车,这不就是客户所需求的吗?
<p>学到了学到了~</p>