设计模式
设计模式的本质是面向对象设计原则的实际运用,是对类的==封装性==、==继承性==和==多态性==以及类的关联关系和组合关系的充分理解。
创建型模式-建造者模式
定义:指将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式。
它是将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成。它将变与不变相分离,即产品的组成部分是不变的,但每一部分是可以灵活选择的。
eg: 汽车中的方向盘、发动机、车架、轮胎等部件组装,计算机由 CPU、主板、内存、硬盘、显卡、机箱、显示器、键盘、鼠标等部件组装。
特点:
- 封装性好,构建和表示分离。
- 扩展性好,各个具体的建造者相互独立,有利于系统的解耦。
- 客户端不必知道产品内部组成的细节
缺点:
- 产品的组成部分必须相同,适用产品范围被限制
- 如果产品内部发生变化,则建造者也要同步修改,变化较为复杂,维护成本大
结构
建造者(==Builder==)模式由产品、抽象建造者、具体建造者、指挥者等 4 个要素构成
主要角色说明:
- 产品角色(==Product==):它是包含多个组成部件的复杂对象,由具体建造者来创建其各个零部件。
- 抽象建造者(==Builder==):它是一个包含创建产品各个子部件的抽象方法的接口,通常还包含一个返回复杂产品的方法 getResult()。
- 具体建造者(==Concrete Builder==):实现 ==Builder== 接口,完成复杂产品的各个部件的具体创建方法。
- 指挥者(==Director==):它调用建造者对象中的部件构造与装配方法完成复杂对象的创建,在指挥者中不涉及具体产品的信息。
UML 类图关系
建造者模式的实际体现
JDK
StringBuilder
:
public final class StringBuilder extends AbstractStringBuilder implements java.io.Serializable, CharSequence{
@Override
public StringBuilder append(Object obj) {
return append(String.valueOf(obj));
}
@Override
public StringBuilder append(String str) {
super.append(str);
return this;
}
@Override
public StringBuilder append(CharSequence s) {
super.append(s);
return this;
}
@Override
public StringBuilder append(char[] str) {
super.append(str);
return this;
}
...
}
AbstractStringBuilder
:
abstract class AbstractStringBuilder implements Appendable, CharSequence {
public AbstractStringBuilder append(String str) {
if (str == null)
return appendNull();
int len = str.length();
ensureCapacityInternal(count + len);
str.getChars(0, len, value, count);
count += len;
return this;
}
}
Appendable
:
public interface Appendable {
Appendable append(CharSequence csq) throws IOException;
Appendable append(CharSequence csq, int start, int end) throws IOException;
Appendable append(char c) throws IOException;
}
-
Appendable
定义多个append()
抽象方法,抽象建造者 -
AbstractStringBuilder
实现Appendable
接口,已经作为了建造者,只是抽象类不能直接实例化,通过StringBuilder
子类进行实例化。 -
StringBuilder
继承AbstractStringBuilder
,即作为具体建造者,也作为指挥者。
Spring
BeanDefinitionBuilder
:
public final class BeanDefinitionBuilder {
public AbstractBeanDefinition getRawBeanDefinition() {
return this.beanDefinition;
}
...
public BeanDefinitionBuilder setParentName(String parentName) {
this.beanDefinition.setParentName(parentName);
return this;
}
public BeanDefinitionBuilder setFactoryMethod(String factoryMethod) {
this.beanDefinition.setFactoryMethodName(factoryMethod);
return this;
}
public BeanDefinitionBuilder setScope(String scope) {
this.beanDefinition.setScope(scope);
return this;
}
...
public BeanDefinitionBuilder addPropertyValue(String name, Object value) {
this.beanDefinition.getPropertyValues().add(name, value);
return this;
}
...
}
AbstractBeanDefinition
:
public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor
implements BeanDefinition, Cloneable {
protected AbstractBeanDefinition(BeanDefinition original) {
setParentName(original.getParentName());
setBeanClassName(original.getBeanClassName());
setScope(original.getScope());
setAbstract(original.isAbstract());
setFactoryBeanName(original.getFactoryBeanName());
setFactoryMethodName(original.getFactoryMethodName());
setRole(original.getRole());
setSource(original.getSource());
copyAttributesFrom(original);
...
}
}
BeanDefinition
:
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
void setParentName(String parentName);
void setFactoryMethod(String factoryMethod);
void setFactoryMethodOnBean(String factoryMethod, String factoryBean);
void addConstructorArgValue(@Nullable Object value);
void addConstructorArgReference(String beanName);
void addPropertyValue(String name, @Nullable Object value);
}
-
BeanDefinition
扮演抽象 ==Builder== 的角色 -
BeanDefinitionBuilder
扮演具体 ==Builder== 角色 -
AbstractBeanDefinition
既扮演指挥者角色又为 ==Product==
简单使用示例
创建角色
-
Director
public class Director { private Builder builder; public Director(Builder builder) { this.builder = builder; } public Computer construct(String cpu, String motherboard, String graphic) { builder.cpu(cpu); builder.motherboard(motherboard); builder.graphic(graphic); builder.os(); return builder.build(); } }
-
Builder
public abstract class Builder { /** * setupCPU * @param cpu */ public abstract void cpu(String cpu); /** * setupMotherboard * @param motherboard */ public abstract void motherboard(String motherboard); /** * setupGraphic * @param graphic */ public abstract void graphic(String graphic); /** * setOS */ public abstract void os(); /** * build * @return */ public abstract Computer build(); }
-
LenovoLaptopBuilder
public class LenovoLaptopBuilder extends Builder { private Computer computer = new Computer(); @Override public void cpu(String cpu) { computer.setCpu(cpu); } @Override public void motherboard(String motherboard) { computer.setMotherboard(motherboard); } @Override public void graphic(String graphic) { computer.setGraphic(graphic); } @Override public void os() { computer.setOs("Windows 10"); } @Override public Computer build() { return computer; } }
-
MacLaptopBuilder
public class MacLaptopBuilder extends Builder{ private Computer computer = new Computer(); @Override public void cpu(String cpu) { computer.setCpu(cpu); } @Override public void motherboard(String motherboard) { computer.setMotherboard(motherboard); } @Override public void graphic(String graphic) { computer.setGraphic(graphic); } @Override public void os() { computer.setOs("MacOS"); } @Override public Computer build() { return computer; } }
-
Computer
public class Computer { private String cpu; private String motherboard; private String graphic; private String os; public void setCpu(String cpu) { this.cpu = cpu; } public void setMotherboard(String motherboard) { this.motherboard = motherboard; } public void setGraphic(String graphic) { this.graphic = graphic; } public void setOs(String os) { this.os = os; } }
简化模式
将角色==Director==与==Client==共用,以达到一种链式调用的编程
-
Laptop
public class Laptop { private String cpu; private String motherboard; private String graphic; private String os; public String getCpu() { return cpu; } public void setCpu(String cpu) { this.cpu = cpu; } public String getMotherboard() { return motherboard; } public void setMotherboard(String motherboard) { this.motherboard = motherboard; } public String getGraphic() { return graphic; } public void setGraphic(String graphic) { this.graphic = graphic; } public String getOs() { return os; } public void setOs(String os) { this.os = os; } public Laptop(String cpu, String motherboard, String graphic, String os) { this.cpu = cpu; this.motherboard = motherboard; this.graphic = graphic; this.os = os; } /** * 静态工厂方法构建 Builder * @return */ public static Laptop.Builder builder() { return new Laptop.Builder(); } /** * 静态内部类 */ public static class Builder { private String cpu; private String motherboard; private String graphic; private String os; public Laptop.Builder cpu(String cpu) { this.cpu = cpu; return this; } public Laptop.Builder motherboard(String motherboard) { this.motherboard = motherboard; return this; } public Laptop.Builder graphic(String graphic) { this.graphic = graphic; return this; } public Laptop.Builder os(String os) { this.os = os; return this; } public Laptop build() { return new Laptop(cpu, motherboard, graphic, os); } } public static void main(String[] args) { Laptop laptop = Laptop.builder() .cpu("intel") .motherboard("apple") .graphic("amd") .os("macOS") .build(); System.out.println(laptop); } }