参考:https://blog.csdn.net/weixin_48052161/article/details/119083633
GOF 给建造模式的定义为:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示.
这句话说得很抽象,不好理解,其实它的意思可以理解为:将构造复杂对象的过程和组成对象的部件解耦
建造者模式和工厂模式区别:
建造者模式优点类似于工厂模式,都是用来创建一个对象,但是他们还是有很大的区别,主要区别如下:
建造者模式更加注重方法的调用顺序,工厂模式注重于创建完整对象
建造者模式根据不同的产品零件和顺序可以创造出不同的产品,而工厂模式创建出来的产品都是一样的
造者模式使用者需要知道这个产品有哪些零件组成,而工厂模式的使用者不需要知道,直接创建就行
创建模式着重于逐步将组件装配成一个成品并向外提供成品,
而抽象工厂模式着重于得到产品族中相关的多个产品对象
适用场景:
建造者模式适用于一个具有较多的零件的复杂产品创建过程,而且产品的各个组成零件还会经常发生变化或者说需要支持动态变化,但是零件的种类却总体稳定的场景:
相同的方法,不同的执行顺序需要产生不同的执行结果
产品类非常复杂,调用不同的零件或者按照不同的顺序来组装产品后需要得到不同的产品
当初始化一个对象非常复杂,而且很多参数都具有默认值
优点:
封装性好,创建和使用分离
扩展性好,建造类之间独立,一定程度上实现了解耦:
缺点:
产生多余的Builder对象
产品内部发生变化时,建造者都需要修改,成本较大
还是代码演示吧!
建造地形模型对象 Terrain,
其中地形由城墙Wall, 堡垒Fort, 地雷Mine组成
每一个构建对象,又有x, y, w, h四个方向指标属性
门面类:Terrain 依赖Wall、Mine、Fort
package com.example.dtest.design23.builder;
public class Terrain {
Wall w; //城墙
Fort f; //堡垒
Mine m; //地雷
@Override
public String toString() {
return "Terrain{" +
"w=" + w +
", f=" + f +
", m=" + m +
'}';
}
}
Wall类:
package com.example.dtest.design23.builder;
//城墙
public class Wall {
int x,y,w,h;
public Wall(int x,int y,int w,int h){
this.x = x;
this.y = y;
this.w = w;
this.h = h;
}
@Override
public String toString() {
return "Wall{" +
"x=" + x +
", y=" + y +
", w=" + w +
", h=" + h +
'}';
}
}
Fort类:
package com.example.dtest.design23.builder;
//堡垒
public class Fort {
int x, y, w, h;
public Fort(int x, int y, int w, int h) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
}
@Override
public String toString() {
return "Fort{" +
"x=" + x +
", y=" + y +
", w=" + w +
", h=" + h +
'}';
}
}
Mine类:
package com.example.dtest.design23.builder;
//地雷
public class Mine {
int x, y, w, h;
public Mine(int x, int y, int w, int h) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
}
@Override
public String toString() {
return "Mine{" +
"x=" + x +
", y=" + y +
", w=" + w +
", h=" + h +
'}';
}
}
建造抽象类:
package com.example.dtest.design23.builder;
public interface TerrainBuilder {
TerrainBuilder buildWall();
TerrainBuilder buildFort();
TerrainBuilder buildMine();
Terrain build();
}
建造实现类:
package com.example.dtest.design23.builder;
public class ComplexTerrainBuilder implements TerrainBuilder{
Terrain terrain = new Terrain();
@Override
public TerrainBuilder buildWall() {
terrain.w = new Wall(10, 10, 10, 10);
return this;
}
@Override
public TerrainBuilder buildFort() {
terrain.f = new Fort(20, 20, 20, 20);
return this;
}
@Override
public TerrainBuilder buildMine() {
terrain.m = new Mine(50, 50, 50, 50);
return this;
}
@Override
public Terrain build() {
return terrain;
}
}
测试类:
package com.example.dtest.design23.builder;
public class builderTest {
public static void main(String[] args) {
TerrainBuilder builder = new ComplexTerrainBuilder();
Terrain terrain = builder.buildFort().buildMine().buildWall().build();
System.out.println(terrain);
}
}
链式写法
注意:每个创建部分产品最后的返回值返回的都是this,这样就可以实现链式写法.
不用和之前一样一行行去调用,直接通过链式写法一直往下build,最终调用build()方法返回完整的产品对象。
Netty中怎么使用Builder设计模式:
如下图所示,大家还记得,在服务端启动的时候有个启动辅助类ServerBootStrap,我们调用group方法、channel方法设置参数。这里面也使用了链式编程来设置相关参数。