前言
目前正在出一个设计模式专题
系列教程, 篇幅会较多, 喜欢的话,给个关注❤️ ~
本节给大家讲一下设计模式中的建造者模式
,并结合实际业务场景给大家讲解如何使用~
本专题的所有案例代码主要以Java
语言为主, 好了, 废话不多说直接开整吧~
建造者模式
建造者模式(Builder Pattern)
是一种创建型设计模式,它可以将一个复杂对象
的构建过程分解
为多个简单
的步骤,并将这些步骤分别实现,从而使得同样的构建过程可以创建不同的表示。建造者模式
常用于构建一些需要经过多个步骤才能完成的复杂对象,例如汽车、电脑等。
在建造者模式
中,通常有四个角色:抽象建造者(Builder)、具体建造者(ConcreteBuilder)、产品(Product)和指挥者(Director)
。其中,抽象建造者定义了创建产品的抽象方法和部件,具体建造者实现了这些抽象方法,并创建了一个具体产品,产品是由具体建造者构建的对象,指挥者则负责指导具体建造者进行构建,并且可以根据不同的需要指定不同的建造者进行构建。
假设我们要构建一个简单的人类,包括姓名、年龄、性别和职业等属性。我们可以先定义一个人类对象,它包含了所有的属性:
public class Person {
private String name;
private int age;
private String gender;
private String occupation;
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setGender(String gender) {
this.gender = gender;
}
public void setOccupation(String occupation) {
this.occupation = occupation;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", gender='" + gender + '\'' +
", occupation='" + occupation + '\'' +
'}';
}
}
接下来,我们定义一个抽象建造者接口,包含了创建人类对象的方法和设置属性的方法:
public interface PersonBuilder {
void createPerson();
void setName(String name);
void setAge(int age);
void setGender(String gender);
void setOccupation(String occupation);
Person getPerson();
}
然后,我们定义具体建造者类,实现了抽象建造者接口,具体实现了创建人类对象和设置属性的方法:
public class ConcretePersonBuilder implements PersonBuilder {
private Person person;
@Override
public void createPerson() {
person = new Person();
}
@Override
public void setName(String name) {
person.setName(name);
}
@Override
public void setAge(int age) {
person.setAge(age);
}
@Override
public void setGender(String gender) {
person.setGender(gender);
}
@Override
public void setOccupation(String occupation) {
person.setOccupation(occupation);
}
@Override
public Person getPerson() {
return person;
}
}
最后,我们定义一个指挥者类,负责指导具体建造者进行构建:
public class PersonDirector {
private PersonBuilder builder;
public PersonDirector(PersonBuilder builder) {
this.builder = builder;
}
public void constructPerson(String name, int age, String gender, String occupation) {
builder.createPerson();
builder.setName(name);
builder.setAge(age);
builder.setGender(gender);
builder.setOccupation(occupation);
}
}
接下来我们使用它:
public class BuilderTest {
public static void main(String[] args) throws Exception {
PersonBuilder builder = new ConcretePersonBuilder();
PersonDirector director = new PersonDirector(builder);
director.constructPerson("张三", 20, "男", "学生");
Person person = builder.getPerson();
System.out.println(person.toString());
}
}
看下输出:
Person{name='张三', age=20, gender='男', occupation='学生'}
从上面的例子可以看出,建造者模式
可以将一个复杂对象的构建过程分解为多个简单的步骤,并且可以根据不同的需要指定不同的具体建造者来构建不同的对象。同时,建造者模式还可以隐藏
对象的创建和实现细节,使得调用者只需要知道如何构建一个对象,而不需要知道对象的具体实现过程,从而提高了系统的灵活性和可维护性。
最佳实践
现在,我们就结合实际业务给大家展示一下如何使用建造者模式,跟上节一样,依然举电商平台的例子。
假设有一个电商平台,用户可以在平台上购买商品,商品有多种属性,包括名称、描述、价格、库存、品牌、分类等等。我们可以使用建造者模式
来实现商品对象的构建过程。
首先,定义一个商品类,包含多个属性:
@Data
public class Product {
private String name;
private String description;
private BigDecimal price;
private int stock;
private String brand;
private String category;
public Product(String name, String description, BigDecimal price, int stock, String brand, String category) {
this.name = name;
this.description = description;
this.price = price;
this.stock = stock;
this.brand = brand;
this.category = category;
}
}
然后,定义一个商品构造器接口,包含设置商品名称、描述、价格、库存、品牌、分类的方法:
public interface ProductBuilder {
Product build();
void setName(String name);
void setDescription(String description);
void setPrice(BigDecimal price);
void setStock(int stock);
void setBrand(String brand);
void setCategory(String category);
}
接下来,定义一个具体商品构造器,实现商品构造器接口,实现每个属性的设置方法:
public class ConcreteProductBuilder implements ProductBuilder {
private String name;
private String description;
private BigDecimal price;
private int stock;
private String brand;
private String category;
@Override
public void setName(String name) {
this.name = name;
}
@Override
public void setDescription(String description) {
this.description = description;
}
@Override
public void setPrice(BigDecimal price) {
this.price = price;
}
@Override
public void setStock(int stock) {
this.stock = stock;
}
@Override
public void setBrand(String brand) {
this.brand = brand;
}
@Override
public void setCategory(String category) {
this.category = category;
}
@Override
public Product build() {
return new Product(name, description, price, stock, brand, category);
}
}
最后,定义一个商品构造器指挥者,包含一个具体商品构造器对象,可以使用具体商品构造器对象来构建商品对象:
public class ProductDirector {
private ProductBuilder builder;
public ProductDirector(ProductBuilder builder) {
this.builder = builder;
}
public Product constructProduct(String name, String description, BigDecimal price, int stock, String brand, String category) {
builder.setName(name);
builder.setDescription(description);
builder.setPrice(price);
builder.setStock(stock);
builder.setBrand(brand);
builder.setCategory(category);
return builder.build();
}
}
现在,我们可以使用建造者模式来构建商品对象:
public class BuilderTest {
public static void main(String[] args) throws Exception {
ProductBuilder builder = new ConcreteProductBuilder();
ProductDirector director = new ProductDirector(builder);
Product product = director.constructProduct("iPhone 13", "Apple手机", new BigDecimal("7999.00"), 100, "Apple", "手机");
System.out.println(product);
// Product(name=iPhone 13, description=Apple手机, price=7999.00, stock=100, brand=Apple, category=手机)
}
}
结束语
设计模式其实并不难,大家在学习的时候一定要在理解的基础上去写代码,不要去背代码。下节给大家讲原型模式
~
本着把自己知道的都告诉大家,如果本文对您有所帮助,点赞+关注
鼓励一下呗~
相关文章
项目源码(源码已更新 欢迎star⭐️)
Kafka 专题学习
- 一起来学kafka之Kafka集群搭建
- 一起来学kafka之整合SpringBoot基本使用
- 一起来学kafka之整合SpringBoot深入使用(一)
- 一起来学kafka之整合SpringBoot深入使用(二)
- 一起来学kafka之整合SpringBoot深入使用(三)
项目源码(源码已更新 欢迎star⭐️)
ElasticSearch 专题学习
项目源码(源码已更新 欢迎star⭐️)
往期并发编程内容推荐
- Java多线程专题之线程与进程概述
- Java多线程专题之线程类和接口入门
- Java多线程专题之进阶学习Thread(含源码分析)
- Java多线程专题之Callable、Future与FutureTask(含源码分析)
- 面试官: 有了解过线程组和线程优先级吗
- 面试官: 说一下线程的生命周期过程
- 面试官: 说一下线程间的通信
- 面试官: 说一下Java的共享内存模型
- 面试官: 有了解过指令重排吗,什么是happens-before
- 面试官: 有了解过volatile关键字吗 说说看
- 面试官: 有了解过Synchronized吗 说说看
- Java多线程专题之Lock锁的使用
- 面试官: 有了解过ReentrantLock的底层实现吗?说说看
- 面试官: 有了解过CAS和原子操作吗?说说看
- Java多线程专题之线程池的基本使用
- 面试官: 有了解过线程池的工作原理吗?说说看
- 面试官: 线程池是如何做到线程复用的?有了解过吗,说说看
- 面试官: 阻塞队列有了解过吗?说说看
- 面试官: 阻塞队列的底层实现有了解过吗? 说说看
- 面试官: 同步容器和并发容器有用过吗? 说说看
- 面试官: CopyOnWrite容器有了解过吗? 说说看
- 面试官: Semaphore在项目中有使用过吗?说说看(源码剖析)
- 面试官: Exchanger在项目中有使用过吗?说说看(源码剖析)
- 面试官: CountDownLatch有了解过吗?说说看(源码剖析)
- 面试官: CyclicBarrier有了解过吗?说说看(源码剖析)
- 面试官: Phaser有了解过吗?说说看
- 面试官: Fork/Join 有了解过吗?说说看(含源码分析)
- 面试官: Stream并行流有了解过吗?说说看
推荐 SpringBoot & SpringCloud (源码已更新 欢迎star⭐️)
博客(阅读体验较佳)
本文正在参加「金石计划」