简介
- 创建型设计模式
-
用于构建一个复杂对象,同时隐藏对象的创建细节。它允许你逐步构建一个对象,将对象的构建和表示分离,从而可以使用相同的构建过程创建不同的对象表示。
主要组成部分:
- Director(指导者):Director负责控制构建过程,按照一定顺序调用建造者的方法来构建对象。Director通常不直接知道具体的产品类,而只与抽象建造者接口交互。
-
Builder(抽象建造者):Builder定义了创建产品对象各部分的接口。它通常包括一系列方法,如buildPartA()、buildPartB()等,用于构建不同部分的对象。
-
ConcreteBuilder(具体建造者):ConcreteBuilder是Builder接口的具体实现,负责实际构建产品对象的各个部分。它包含了产品的具体构建逻辑,并最终返回构建好的产品。
-
Product(产品):Product是最终构建的复杂对象。它包含了由ConcreteBuilder构建的各部分,通常具有一个接口供客户端使用。
工作流程
- 创建产品类:首先定义产品类,产品是要构建的复杂对象。产品类通常包含多个部分,这些部分可以通过建造者来逐步构建。
- 创建抽象建造者接口:定义一个抽象建造者接口,它包含了构建产品各部分的方法。这个接口通常是产品构建的蓝图。
- 创建具体建造者类:为产品的每个部分创建具体建造者类,实现抽象建造者接口。每个具体建造者类负责实际构建产品的某个部分,并提供一种方式来获取最终的产品。
- 创建指导者类:指导者类用于控制构建过程,它包含一个抽象建造者的引用。指导者的构建方法可以按照特定顺序或逻辑来调用具体建造者的方法,从而构建产品。
- 客户端使用指导者:客户端通过实例化一个具体建造者和一个指导者,然后使用指导者的构建方法来构建产品。客户端可以自由配置产品的部分,但不需要关心具体的构建细节。
- 获取最终产品:最终产品是通过具体建造者的 getResult 方法获得的。客户端可以使用产品对象来执行各种操作。
例子
结构
代码
Product(产品)
/**
* @author: lpy
* @Date: 2023/10/20
* @desc: product
*/
@Data
public class Computer {
private String processor;
private String memory;
private String hardDisk;
private String monitor;
}
Director(指导者)
/**
* @author: lpy
* @Date: 2023/10/20
*/
public class ComputerDirector {
public void constructComputerDirector(ComputerBuilder builder){
builder.buildHardDisk();
builder.buildMemory();
builder.buildMonitor();
builder.buildProcessor();
}
}
Builder(抽象建造者)
/**
* @author: lpy
* @Date: 2023/10/20
* @desc: 学的不要太死,可以用抽象类哦
*/
public interface ComputerBuilder {
void buildProcessor();
void buildMemory();
void buildHardDisk();
void buildMonitor();
Computer getResult();
}
ConcreteBuilder(具体建造者)
/**
* @author: lpy
* @Date: 2023/10/20
*/
public class HighConfigurationComputerBuilder implements ComputerBuilder{
private Computer computer = new Computer();
@Override
public void buildProcessor() {
computer.setProcessor("i9 1300k");
}
@Override
public void buildMemory() {
computer.setMemory("256G");
}
@Override
public void buildHardDisk() {
computer.setHardDisk("40T");
}
@Override
public void buildMonitor() {
computer.setMonitor("Apple 视网膜屏");
}
@Override
public Computer getResult() {
return this.computer;
}
}
/**
* @author: lpy
* @Date: 2023/10/20
*/
public class LowConfigurationComputerBuilder implements ComputerBuilder{
private Computer computer = new Computer();
@Override
public void buildProcessor() {
computer.setProcessor("i3 1200f");
}
@Override
public void buildMemory() {
computer.setMemory("16G");
}
@Override
public void buildHardDisk() {
computer.setHardDisk("1T");
}
@Override
public void buildMonitor() {
computer.setMonitor("熊猫牌小显示器");
}
@Override
public Computer getResult() {
return this.computer;
}
}
测试类
/**
* @author: lpy
* @Date: 2023/10/20
*/
public class BuilderModeTest {
public static void main(String[] args) {
// 高配电脑
ComputerBuilder hc = new HighConfigurationComputerBuilder();
// 低配
ComputerBuilder lc = new LowConfigurationComputerBuilder();
ComputerDirector computerDirector = new ComputerDirector();
computerDirector.constructComputerDirector(hc);
computerDirector.constructComputerDirector(lc);
System.out.println(hc.getResult());
System.out.println(lc.getResult());
}
}
应用
- 需要构建复杂对象:当需要构建包含多个部分或组件的复杂对象,并且这些部分可以按不同的方式组合时,建造者模式非常有用。这可以避免构造器方法参数列表的爆炸性增长,使构造器更容易理解和使用。
-
需要隔离产品的构建和表示:建造者模式允许将对象的构建和表示分离,使产品的表示独立于构建过程。这允许你通过相同的构建过程创建不同的表示。
-
需要更好的可读性和可维护性:使用建造者模式可以提高代码的可读性,因为客户端代码只需关注对象的构建过程,而不需要了解构建细节。这使得代码更易于理解和维护。
建造者模式优缺点
-
优点:
- 封装性好:创建和使用分离,使用者不用关心创建过程
-
扩展性好:建造者之间互相独立,在一定程度上解耦
-
缺点:
- 增加类的数量:产生多于的builder
-
内部修改困难:如果产品内部发生变化,建造者也要进行修改
建造者模式 与 工厂模式 :
注重点不同 : 建造者模式 更注重于 方法的调用顺序 ; 工厂模式 注重于 创建产品 , 不关心方法调用的顺序 ;
创建对象力度不同 : 创建对象的力度不同 , 建造者模式可以创建复杂的产品 , 由各种复杂的部件组成 , 工厂模式创建出来的都是相同的实例对象 ,
1. 目的和用途:
建造者模式:主要用于创建一个复杂对象,这个复杂对象可以由多个部分组成,并且构建过程中可以有不同的配置选项。建造者模式允许逐步构建对象,分离构建和表示,并提供更好的控制和定制性。
工厂模式:主要用于创建对象,但通常是创建单一类型的对象,而不是复杂对象。工厂模式通过一个工厂方法来实现对象的创建,根据输入参数或条件返回不同类型的对象。
2. 构建过程:
建造者模式:在建造者模式中,构建过程是逐步的,客户端可以配置对象的不同部分,而建造者负责将这些部分组装成最终的对象。建造者模式通常包括一个指导者类,用于控制构建的步骤。
工厂模式:工厂模式是直接创建对象,通常不涉及对象构建的多个步骤。工厂方法只关心返回适当类型的对象。
3. 类型和关系:
建造者模式:建造者模式通常包括产品类、抽象建造者、具体建造者和指导者。产品类表示要构建的对象,抽象建造者定义构建对象的接口,具体建造者实现接口来构建对象的各个部分,指导者控制构建的过程。
工厂模式:工厂模式包括工厂类和产品类,工厂类通过工厂方法来创建产品对象。
4. 灵活性和控制:
建造者模式:建造者模式提供更大的控制和定制性,客户端可以配置对象的不同部分和特性,以满足特定需求。这使得建造者模式适用于需要构建不同配置的复杂对象的情况。
工厂模式:工厂模式通常提供相对较少的控制,因为它的主要目标是创建对象实例。工厂模式适用于需要根据输入条件选择合适的对象类型的情况。
7 大设计原则
不能全部遵守 , 也不能不遵守 , 注意平衡 功能 和 系统复杂度 , 找到最合适的一个点 ;
- 单一职责原则(Single Responsibility Principle - SRP):
这个原则规定一个类应该只有一个改变的理由,也就是说,一个类应该只有一个单一的职责。这有助于保持类的简单性和可维护性,因为每个类只需关注一个特定的功能。
- 开放-封闭原则(Open-Closed Principle - OCP):
开放-封闭原则要求系统中的软件实体(类、模块、函数等)应该对扩展开放,对修改封闭。这意味着当需要添加新功能时,应该通过扩展现有代码来实现,而不是修改原有代码。
- 里氏替换原则(Liskov Substitution Principle - LSP):
里氏替换原则规定,子类应该能够替换其父类,而不会影响程序的正确性。也就是说,子类应该继承父类的行为,但可以扩展或修改该行为,但不应该改变父类的行为。
- 接口隔离原则(Interface Segregation Principle - ISP):
接口隔离原则要求一个类不应该强迫其客户端依赖于它们不需要的接口。应该根据客户端的需求定义小而精确的接口,而不是大而笨重的接口。
- 依赖倒置原则(Dependency Inversion Principle - DIP):
依赖倒置原则要求高级模块不应该依赖于低级模块,它们都应该依赖于抽象。具体来说,这意味着应该通过抽象接口或抽象类来定义模块之间的依赖关系,而不是直接依赖于具体实现。
- 迪米特法则(Law of Demeter - LoD):
如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果其中一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。
- 合成复用原则(Composite Reuse Principle - CRP):
合成复用原则鼓励通过组合(合成)已有的类来实现新功能,而不是通过继承现有的类。这样可以降低系统的耦合度,并且更加灵活。
源码位置
全部源码github.com/xs-alpha/designPattern
参考文献
如有内容侵权,麻烦联系博主删除