建造者模式:建造需要的产品,建造者模式侧重于一个对象构建很复杂,需要很多步骤,那么我们可以把对象的构建和最后的组装分离出来,就像汽车装修组件车厂,通过组合创建自己需要的完整的产品。
下面是在网上找到的一个示例,觉得还是蛮一目了然,更清晰的理解建造者模式。
假如我们有一款游戏哈,可能由于网络的原因导致画质加载不出来出现用户体验不好的情况,就比如打王者荣耀,他那个场景会有树,会有石头,天气,地面等等的可能。那遇到这种情况我怎么才能按照不同的画质加载不同的场景呢?
来,首先咱们要有地图抽象接口!用来加载天气,房子,树和路面
/**
* 抽象地图接口
* 1.加载天气
* 2.加载房子
* 3.加载树
* 4.加载路面
*
* @Author df
* @Date 2020/10/10 11:11
*/
public interface IMap {
void createWeather();
void createHouse();
void createTree();
void createWay();
}
咱们再来具体的地图实现,阴天房子,树,路面是什么场景逻辑呢?
/**
* 阴天实现服务类
* 1.加载天气阴天的逻辑
* 2.加载房子阴天的逻辑
* 3.加载树阴天的逻辑
* 4.加载路面阴天的逻辑
* @Author df
* @Date 2020/10/10 11:17
*/
public class MapCloudyServiceImpl implements IMap {
@Override
public void createWeather() {
System.out.println("阴天");
}
@Override
public void createHouse() {
System.out.println("房子的玻璃暗的");
}
@Override
public void createTree() {
System.out.println("树的颜色是深绿色");
}
@Override
public void createWay() {
System.out.println("路面有些潮湿");
}
}
咱们再来晴天的具体实现,看看晴天的场景!
/**
* 晴天实现服务类
* 1.加载天气晴天的逻辑
* 2.加载房子晴天的逻辑
* 3.加载树晴天的逻辑
* 4.加载路面晴天的逻辑
*
* @Author df
* @Date 2020/10/10 11:13
*/
public class MapSunServiceImpl implements IMap {
@Override
public void createWeather() {
System.out.println("晴天");
}
@Override
public void createHouse() {
System.out.println("房子被阳光照耀的很好看");
}
@Override
public void createTree() {
System.out.println("树叶闪闪发光");
}
@Override
public void createWay() {
System.out.println("路面发烫");
}
}
来咱们现在组合场景,实现不同画质下的场景!高画质建造者!
/**
* 高画质类
* 1.建造组合,高画质地图加载方法
*
* @Author df
* @Date 2020/10/10 11:20
*/
public class MapAdvBuilder {
private IMap iMap;
public MapAdvBuilder(IMap iMap) {
super();
this.iMap = iMap;
}
public void createMap() {
System.out.println("创建了一个高画质的地图");
iMap.createWeather();
iMap.createHouse();
iMap.createTree();
iMap.createWay();
}
}
低画质建造者,哈哈就是按照自己组合把最占网络宽带的加载场景去除已实现低画质情景。
/**
* 低画质类
* 1.建造组合,低画质地图加载方法
* @Author df
* @Date 2020/10/10 11:23
*/
public class MapLowBuilder {
private IMap iMap;
public MapLowBuilder(IMap iMap) {
super();
this.iMap = iMap;
}
public void createMap() {
System.out.println("创建了一个低画质的地图");
iMap.createWeather();
iMap.createHouse();
// iMap.createTree(); // 低画质就把创建树的过程去掉了
iMap.createWay();
}
}
测试实验一下
/**
* 测试案例使用
* @Author df
* @Date 2020/10/10 11:02
*/
public class Test {
public static void main(String[] args) {
// 阴天服务
IMap cloudyService = new MapCloudyServiceImpl();
MapAdvBuilder highMap = new MapAdvBuilder(cloudyService);
highMap.createMap();
// 晴天服务
IMap sunService = new MapSunServiceImpl();
// MapAdvBuild highMap1=new MapAdvBuild(sunService);
// highMap1.createMap();
System.out.println();
// 低画质
MapLowBuilder lowBuild = new MapLowBuilder(sunService);
lowBuild.createMap();
}
}
结果:
其实不难看出,建造者的核心就是把需要的产品组合起来,返回给我们一个组装好的完整产品,而工厂模式则是返回一系列相关的产品,这些产品位于不同的产品等级结构,构成了一个产品族,如果抽象工厂是汽车配件生产工厂,那么建造者就是汽车组装工厂,通过对部件的组装可以返回一辆完整的汽车。
建造者模式组成如下图:
建造者builder:声明要创建的工具
建造者实现类:具体的建造者来创建具体产品
产品(product):建造的产品对象
指挥者(Director):客户端通过和指挥者交互得到需要的产品。
虽然模式是这样的,但是只要中心思想符合此设计模式,其实可以不用非得按照设计模式上的要求分的那么清楚,比如必须有指挥者啥的,因为可能会变得很臃肿,按照自己业务来实现可扩展,可维护的设计模式,就是最好的设计模式!
比如:StringBuilder就是建造者模式,String是产品,StringBuilder的出现可以对String append,insert等操作,而没有Director,可能那个指挥者就是我们程序员的代码调用StringBuilder把!
还比如看到好多大牛的博客建造者模式也不是完全按照说必须有指挥者啊,必须有具体的builder啊什么的,都是按照自己的业务来确定最简单,最有效,可扩展,可维护的设计模式!
说了这么多,希望你能理解此设计模式,当然最终还是自己得多想,根据自己实际业务思考出来的设计模式会更加深刻哦!