首页 > 其他分享 >设计模式-建造者模式

设计模式-建造者模式

时间:2022-11-12 11:00:33浏览次数:34  
标签:mCombo void 建造 模式 private Combo 设计模式 public

在我们生活中的对象比如汽车,它是由车轮、车架、发动机等组合起来的对象,但是往往使用的人只想要一辆汽车并不想知道创建汽车的过程此时就可以使用建造者模式。

在软件开发中,也存在大量类似汽车一样的复杂对象,它们拥有一系列成员属性,这些成员属性中有些是引用类型的成员对象。而且在这些复杂对象中,还可能存在一些限制条件,如某些属性没有赋值则复杂对象不能作为一个完整的产品使用;有些属性的赋值必须按照某个顺序,一个属性没有赋值之前,另一个属性可能无法赋值等。

复杂对象相当于一辆有待建造的汽车,而对象的属性相当于汽车的部件,建造产品的过程就相当于组合部件的过程。由于组合部件的过程很复杂,因此,这些部件的组合过程往往被“外部化”到一个称作建造者的对象里,建造者返还给客户端的是一个已经建造完毕的完整产品对象,而用户无须关心该对象所包含的属性以及它们的组装方式,这就是建造者模式的模式动机。

建造者模式定义

建造者模式是一个将复杂对象的构建过程与它的表示分离,使得同样的构建过程可以创建不同的表示,属于创建型模式,使用建造者模式对于用户而言只需要指定需要建造的类型就可以获取对象,建造过程及细节不需要了解。

可以看一下传统建造者模式UML类图:

设计模式-建造者模式_建造者

设计模式-建造者模式_建造者模式_02

其中主要的角色有四个:

  1. 产品(Product):要创建的产品类对象
  2. 建造者抽象(Builder):建造者的抽象类,规范产品对象的各个部分组成的建造,一般由子类实现具体的建造过程
  3. 建造者(ConcreteBuilder):具体的Builder类,根据不同的业务逻辑,具体化对象的各个组成部分的创建
  4. 调用者(Director):调用具体的建造者来创建对象的各个部分,在指导者中不涉及具体产品的信息,只负责保证对象各部分完成创建或者按某种顺序创建

传统模式代码示例

举一个肯德基的套餐的例子。肯德基有很多套餐,肯德基的服务员需要根据用户的要求提供对应的的套餐。

@Data
@ToString
public class Combo {
private String title;
private String Hamburger;
private String chickenWings;
private String drumstick;
private String cola;

public Combo(String title){
this.title = title;
}
}
复制代码
public interface ComboBuilder {

Combo build();
void buildHamburger();
void buildChickenWings();
void buildDrumstick();
void buildCola();
}
复制代码
public class BComboBuilder implements ComboBuilder{
private final Combo mCombo = new Combo("B套餐");

@Override
public void buildHamburger() {
mCombo.setHamburger("两个套餐");
}

@Override
public void buildChickenWings() {
mCombo.setChickenWings("五个鸡翅");
}

@Override
public void buildDrumstick() {
mCombo.setDrumstick("三个鸡腿");
}

@Override
public void buildCola() {
mCombo.setCola("两个可乐");
}

public Combo build(){
return this.mCombo;
}
}
复制代码
public class AComboBuilder implements ComboBuilder {
private final Combo mCombo = new Combo("A套餐");

@Override
public void buildHamburger() {
mCombo.setHamburger("一个汉堡");
}

@Override
public void buildChickenWings() {
mCombo.setChickenWings("三个鸡翅");
}

@Override
public void buildDrumstick() {
mCombo.setDrumstick("三个鸡腿");
}

@Override
public void buildCola() {
mCombo.setCola("一个可乐");
}

public Combo build(){
return this.mCombo;
}
}
复制代码
public class Waiter {
private final ComboBuilder builder;

public Combo getCombo(){
return this.builder.build();
}
public Waiter(ComboBuilder builder){
this.builder = builder;
}
public void setBuilder() {
this.builder.buildChickenWings();
this.builder.buildCola();
this.builder.buildDrumstick();
this.builder.buildHamburger();
}

}
复制代码
public class Test {
public static void main(String[] args) {
AComboBuilder aComboBuilder = new AComboBuilder();
Waiter waiter = new Waiter(aComboBuilder);
waiter.setBuilder();
Combo combo = waiter.getCombo();
System.out.println(combo);
}
}
复制代码

传统模式优化-链式编程

public class AComboBuilder implements ComboBuilder {
private final Combo mCombo = new Combo("A套餐");

@Override
public ComboBuilder buildHamburger() {
mCombo.setHamburger("一个汉堡");
return this;
}

@Override
public ComboBuilder buildChickenWings() {
mCombo.setChickenWings("三个鸡翅");
return this;
}

@Override
public ComboBuilder buildDrumstick() {
mCombo.setDrumstick("三个鸡腿");
return this;
}

@Override
public ComboBuilder buildCola() {
mCombo.setCola("一个可乐");
return this;
}

public Combo build(){
return this.mCombo;
}
}
复制代码
public class Test {
public static void main(String[] args) {
AComboBuilder aComboBuilder = new AComboBuilder();

Combo combo = aComboBuilder.buildChickenWings()
.buildCola()
.buildDrumstick()
.buildHamburger()
.build();
System.out.println(combo);
}
}
复制代码

如上图所示不需要再一个一个写一个一个赋值了直接链式编程就好,还有一点上述的写法弃用了​​Director​​,个人感觉没必要硬着头皮要套传统模式的写法,也是可以有一些变通,主要是要适合自己的项目,如果就是一个对象的创建很复杂我们也可以将​​builder​​内嵌到类中如下:

@Data
@ToString
public class Combo {
private String title;
private String Hamburger;
private String chickenWings;
private String drumstick;
private String cola;

public Combo(String title){
this.title = title;
}

public static class Builder {
private final Combo mCombo = new Combo("A套餐");

public Builder buildHamburger() {
mCombo.setHamburger("一个汉堡");
return this;
}

public Builder buildChickenWings() {
mCombo.setChickenWings("三个鸡翅");
return this;
}

public Builder buildDrumstick() {
mCombo.setDrumstick("三个鸡腿");
return this;
}

public Builder buildCola() {
mCombo.setCola("一个可乐");
return this;
}

public Combo build(){
return this.mCombo;
}
}
}
复制代码
Combo combo = new Combo.Builder()
.buildChickenWings()
.buildCola()
.buildDrumstick()
.buildHamburger()
.build();
System.out.println(combo);
复制代码

根据自己的项目需求随机变通

建造者模式在源码中的使用

这里就举 ​​StringBuilder​​的例子吧

设计模式-建造者模式_建造者模式_03

设计模式-建造者模式_建造者_04

设计模式-建造者模式_建造者模式_05

设计模式-建造者模式_ide_06

这种情况就很适用建造者模式应为在拼接字符串中为了提高性能需要做很多处理,如果放在外面每次使用都要调用那么多代码很不方便

建造者模式的应用场景

  1. 需要生成的产品对象有复杂的内部结构,这些产品对象通常包含多个成员属性。
  2. 当你的对象的构造方法有三四个甚至更多的时候可以使用建造者模式替代
  3. 当初始化一个对象特别复杂,参数多,而且很多参数都有默认值的时候

建造者模式优缺点:

优点:

  1. 在建造者模式中,客户不必知道产品内部的组成细节
  2. 封装性好,创建和使用隔离
  3. 扩展性好,建造类直接独立,一定程度上解耦

缺点:

  1. 产生多余的建造类
  2. 产品内部发生变化,建造者都要修改,违反开闭原则同时修改成本也比较大

建造者模式和工厂模式的区别

  1. 建造者模式更加注重方法的调用顺序,工厂模式注重创建对象
  2. 创建对象的力度不同,建造者模式创建复杂的对象,由各种复杂的部件组成,工程模式创建出来的都一样(这里可能有人疑问为啥一样,应为建造者模式对象的一些属性我们都是可以赋值的,可以有的有有的没有自然对象也就不一样了。工厂模式不一样只有一种创建方式要么属性全都有要么全没有所以一样)
  3. 关注维度不一样,工厂只关注对象的创建,建造者不仅要创建,还要知道这个对象是由那些部件组成的
  4. 建造者模式根据建造过程中的顺序不一样,最终的对象部件组成也有可能是不一样的(那些不关系调用顺序的类可就是一样的)

标签:mCombo,void,建造,模式,private,Combo,设计模式,public
From: https://blog.51cto.com/u_15773567/5846569

相关文章

  • 设计模式学习(十四):模板方法
    设计模式学习(十四):模板方法作者:Grey原文地址:博客园:设计模式学习(十四):模板方法CSDN:设计模式学习(十四):模板方法模板方法模板方法是一种行为型模式。假设我们要实现一个游......
  • 访问者模式
    访问者模式有点小复杂,而且需要在实际的时候提前留好后门,下面通过简单的例子来介绍一下。场景就是邮件发送,通知客户怎么了怎么了,后面可能需要短信或者app也推。推之前或推送......
  • 给网站添加一个夜间模式
    最近发现了一个可以很简单给网站添加夜间模式的js库项目地址:https://darkmodejs.learn.uno/将下面的代码放到网站的头部或尾部,就会在网页的右下角出现一个按钮,点击即可......
  • Redis 集群模式的安装与配置【源码安装redis-7.0.5】
    Redis最新版下载地址:http://download.redis.io/releases/redis-7.0.5.tar.gz步骤如下:1)wget http://download.redis.io/releases/redis-7.0.5.tar.gz2)tar-zxf redis-7......
  • Java静态代理设计模式模式(多线程Runnable)
    静态代理设计模式,就是代理对象来帮你忙前忙后,你负责出席一下就好了。需要:1.实现相同的接口2.真实角色3.代理角色,里面有一个成员是接口对象(实际上是真实角色----接口实......
  • 设计模式学习(十三):观察者模式
    设计模式学习(十三):观察者模式作者:Grey原文地址:博客园:设计模式学习(十三):观察者模式CSDN:设计模式学习(十三):观察者模式观察者模式观察者模式是一种行为型模式。在对象之间......
  • 【JS】891- 高级 Promise 模式 - Promise缓存
    https://www.jonmellman.com/posts/promise-memoization 译者:ConardLi在本文中,我们将介绍常见的缓存实现在并发条件下存在的问题。然后我们将介绍如何修复它,并且在此过程......
  • 命令模式
    命令模式使用场景我反复强调,设个非常重要!因为纵使你有十八般武器,不知道什么时候用也是白搭。从定义上我们就可以看出其可以解决的问题。当需要将各种执行的动作抽象出来......
  • C#设计模式之建造者模式
      原文网址:https://www.jb51.net/article/254976.htm场景:我们的冒险家,现在需要去武器商店买一把兵器,有刀和剑两种武器,冒险者可以告诉武器商人需要哪一种武器,然后武器商......
  • 工厂模式
    工厂模式定义工厂类,及工厂方法,获取工厂里面的数据@Service@OrderpublicclassRuleFactory{privatestaticfinalLoggerlogger=LoggerFactory.getLogger(R......