建造者模式
-
建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象,这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
-
一个Builder类会一步一步构造最终的对象,该Builder类是独立于其他对象的。
介绍
场景:建造一个复杂的产品或者开发过程中构建对象过于复杂,则需要进行分步处理。
意图:将一个复杂的构建与其装配相分离,使得同样的构建过程可以创建不同的表示。
本质:
- 分离了对子组件的单独构造(由Builder来负责)和装配(由Director负责),从而可以构件出复杂的对象。这个模式适用于:某个对象构造复杂的情况下使用。
- 由于实现了构件和装配的解耦,不同的构建器,相同的装配过程也可以做出不同的对象;相同的构建器,不同的装配过程也可以做出不同的对象。
- 因此,实现了构建算法、装配算法的解耦,实现了更好的复用。
何时使用:一些基本部件不会变,而其组合经常变化的时候。
如何解决:将变与不变分离开。
关键代码:建造者:创建和提供实例,导演:管理建造出来的实例的依赖关系。
使用场景:
- 需要生成的对象具有复杂的内部结构
- 需要生成的对象内部属性本身相互依赖。
应用实例:
- 去肯德基,汉堡、可乐、薯条、炸鸡翅等是不变的,而其组合是经常变化的,生成出所谓的"套餐"
- JAVA 中的 StringBuilder的append方法
- SQL中的PrepareStatement
- JDOM中DomBuilder,SAXBuilder
优点:
- 建造者独立,易扩展
- 便于控制细节风险
缺点:
- 产品必须有共同点,范围有限制
- 如内部变化复杂,会有很多的建造类
注意事项:与工厂模式的区别是:建造者模式更加关注与零件装配的顺序。
实现
步骤1:创建宇宙飞船框架和宇宙飞船组件
package com.ly.builder;
/**
* liyang 2020-07-12
* 创建宇宙飞船框架和宇宙飞船组件
*/
public class SpaceCraft {
private OrbitalModule orbitalModule; //轨道舱模块
private Engine engine; //发动机
private EscapeTower escapeTower; //逃逸仓
public OrbitalModule getOrbitalModule() {
return orbitalModule;
}
public void setOrbitalModule(OrbitalModule orbitalModule) {
this.orbitalModule = orbitalModule;
}
public Engine getEngine() {
return engine;
}
public void setEngine(Engine engine) {
this.engine = engine;
}
public EscapeTower getEscapeTower() {
return escapeTower;
}
public void setEscapeTower(EscapeTower escapeTower) {
this.escapeTower = escapeTower;
}
public void launch() {
System.out.println("发射宇宙飞船");
}
}
class OrbitalModule {
private String name;
public OrbitalModule(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class Engine {
private String name;
public Engine(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class EscapeTower {
private String name;
public EscapeTower(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
步骤2:创建建造者和装配者接口
package com.ly.builder;
public interface SpaceCraftBuilder {
OrbitalModule buildOrbitalModule();
Engine buildEngine();
EscapeTower buildEscapeTower();
}
package com.ly.builder;
public interface SpaceCraftDirector {
SpaceCraft directSpaceCraft();
}
步骤3:创建真实的建造者和装配者(装配建造者构建的零部件,返回装配好的SpaceCraft)
package com.ly.builder;
public class LySpaceCraftBuilder implements SpaceCraftBuilder{
@Override
public OrbitalModule buildOrbitalModule() {
System.out.println("ly-构建轨道舱");
return new OrbitalModule("ly-轨道舱");
}
@Override
public Engine buildEngine() {
System.out.println("ly-构建发动机");
return new Engine("ly-发动机");
}
@Override
public EscapeTower buildEscapeTower() {
System.out.println("ly-构建逃逸塔");
return new EscapeTower("ly-逃逸塔");
}
}
package com.ly.builder;
public class LySpaceCraftDirector implements SpaceCraftDirector {
//装配置自然需要调用构造者生产的组件
private SpaceCraftBuilder spaceCraftBuilder;
public LySpaceCraftDirector(SpaceCraftBuilder spaceCraftBuilder) {
super();
this.spaceCraftBuilder = spaceCraftBuilder;
}
@Override
public SpaceCraft directSpaceCraft() {
//使用建造者生产组件
OrbitalModule orbitalModule = spaceCraftBuilder.buildOrbitalModule();
Engine engine = spaceCraftBuilder.buildEngine();
EscapeTower escapeTower = spaceCraftBuilder.buildEscapeTower();
//使用生产的组件进行set组装
SpaceCraft spaceCraft = new SpaceCraft();
spaceCraft.setOrbitalModule(orbitalModule);
spaceCraft.setEngine(engine);
spaceCraft.setEscapeTower(escapeTower);
//组装完return出去
return spaceCraft;
}
}
步骤4:客户端测试
package com.ly.builder;
public class Client {
public static void main(String[] args) {
SpaceCraftDirector spaceCraftDirector = new LySpaceCraftDirector(new LySpaceCraftBuilder());
SpaceCraft spaceCraft = spaceCraftDirector.directSpaceCraft();
System.out.println(spaceCraft.getOrbitalModule().getName());
System.out.println(spaceCraft.getEngine().getName());
System.out.println(spaceCraft.getEscapeTower().getName());
spaceCraft.launch();
}
}
结果:
ly-构建轨道舱
ly-构建发动机
ly-构建逃逸塔
ly-轨道舱
ly-发动机
ly-逃逸塔
发射宇宙飞船
Process finished with exit code 0