通俗的讲,比如你想组装一个电脑,需要机箱、显示器、键盘、鼠标,但是它们选取的品牌各异,最终的电脑价格和性能又是天差地别。
而这样的根据相同的配件,不同的组装所产生出的具体的内容,就是建造者模式的具体实现,也就是将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的表示。
它声明为创建一个产品对象的各个部件指定的抽象接口,在该接口中一般声明两类方法,一类方法是buildPatX(),他们用于创建复杂对象的各个部件;另一类方法是getResult(),它们用于返回复杂对象。Builder既可以是抽象类,也可以是接口。
实现抽象建造者接口,构建和装配各个部件,定义并明确它所创建的复杂对象,也可以提供一个方法返回创建好的复杂产品对象。
它负责安排复杂对象的建造次序,指挥者与抽象建造者之间存在关联关系,可以在其construct()构造方法中调用建造者对象的部件构造与装配方法,完成复杂对象的建造。客户端一般只需要与指挥者进行交互,在客户端确定具体建造者的类型,并实例化具体建造者对象(也可以通过配置文件和反射机制),然后通过指挥者类的构造函数或者setter方法将该对象传入指挥者类中。它主要是用于创建一个复杂对象,它主要有两个作用①隔离了客户与对象的生成过程②负责控制产品对象的生产过程。
产品角色,一个具体的产品对象。
package com.guor.builder;
public interface Computer {
// 电脑配件(主机、显示器、键盘、鼠标)
String parts();
// 品牌
String brand();
// 型号
String model();
// 价格
Double price();
// 描述
String desc();
}
(1)ROG主机
package com.guor.builder;
public class RogHost implements Computer{
@Override
public String parts() {
return "主机";
}
@Override
public String brand() {
return "ROG";
}
@Override
public String model() {
return "光刃G15";
}
@Override
public Double price() {
return 13999.00;
}
@Override
public String desc() {
return "Intel i7-12700 16G 1TB+1TSSD RTX3070 8G独显";
}
}
(2)拯救者主机
package com.guor.builder;
public class LegionHost implements Computer {
@Override
public String parts() {
return "主机";
}
@Override
public String brand() {
return "Lenovo";
}
@Override
public String model() {
return "拯救者刃7000K";
}
@Override
public Double price() {
return 6999.00;
}
@Override
public String desc() {
return "Intel i5-12400F 16G 512G SSD RTX3060";
}
}
(1)ROG32寸显示器
package com.guor.builder;
public class Rog32Monitor implements Computer{
@Override
public String parts() {
return "显示器";
}
@Override
public String brand() {
return "ROG";
}
@Override
public String model() {
return "华硕PG32UG";
}
@Override
public Double price() {
return 7499.00;
}
@Override
public String desc() {
return "32寸 游戏显示器4K 144Hz HDR600";
}
}
(2)ROG27寸显示器
package com.guor.builder;
public class Rog27Monitor implements Computer {
@Override
public String parts() {
return "显示器";
}
@Override
public String brand() {
return "ROG";
}
@Override
public String model() {
return "华硕XG276Q";
}
@Override
public Double price() {
return 1899.00;
}
@Override
public String desc() {
return "27寸 电竞显示器 170Hz HDR400";
}
}
(3)三星显示器
package com.guor.builder;
public class SamsungMonitor implements Computer {
@Override
public String parts() {
return "显示器";
}
@Override
public String brand() {
return "三星";
}
@Override
public String model() {
return "三星S27R350FHC";
}
@Override
public Double price() {
return 999.00;
}
@Override
public String desc() {
return "27寸 IPS 便携显示器 75HZ";
}
}
(1)ROG机械键盘
package com.guor.builder;
public class RogKeyboard implements Computer {
@Override
public String parts() {
return "键盘";
}
@Override
public String brand() {
return "ROG";
}
@Override
public String model() {
return "龙骑士2";
}
@Override
public Double price() {
return 1899.00;
}
@Override
public String desc() {
return "机械键盘 双模 可分离式 104键 RGB背光 RX光轴";
}
}
(2)罗技机械键盘
package com.guor.builder;
public class LogitechKeyboard implements Computer {
@Override
public String parts() {
return "键盘";
}
@Override
public String brand() {
return "Logitech";
}
@Override
public String model() {
return "G610";
}
@Override
public Double price() {
return 479.00;
}
@Override
public String desc() {
return "cherry机械键盘 有线 104键 电竞游戏背光";
}
}
(1)ROG鼠标
package com.guor.builder;
public class RogMouse implements Computer {
@Override
public String parts() {
return "鼠标";
}
@Override
public String brand() {
return "ROG";
}
@Override
public String model() {
return "战刃3";
}
@Override
public Double price() {
return 599.00;
}
@Override
public String desc() {
return "无限版 三模鼠标 RGB灯效可换微动26000DPI";
}
}
(2)罗技鼠标
package com.guor.builder;
public class LogitechMouse implements Computer {
@Override
public String parts() {
return "鼠标";
}
@Override
public String brand() {
return "Logitech";
}
@Override
public String model() {
return "G402";
}
@Override
public Double price() {
return 199.00;
}
@Override
public String desc() {
return "有线鼠标 高速追踪FPS";
}
}
package com.guor.builder;
import java.util.ArrayList;
import java.util.List;
public class PackageComputer {
public static String getComputerList(String name, Integer grade) {
// 配件清单
List<Computer> list = new ArrayList<Computer>();
// 组装价格
Double price = 0.00;
// ROG套装
if(grade == 1){
RogHost host = new RogHost();
Rog32Monitor monitor = new Rog32Monitor();
RogKeyboard keyboard = new RogKeyboard();
RogMouse mouse = new RogMouse();
list.add(host);
list.add(monitor);
list.add(keyboard);
list.add(mouse);
price = host.price()+monitor.price()+keyboard.price()+mouse.price();
}else if(grade == 2){// ROG机箱 + 27寸显示器 + 罗技键鼠
RogHost host = new RogHost();
Rog27Monitor monitor = new Rog27Monitor();
LogitechKeyboard keyboard = new LogitechKeyboard();
LogitechMouse mouse = new LogitechMouse();
list.add(host);
list.add(monitor);
list.add(keyboard);
list.add(mouse);
price = host.price()+monitor.price()+keyboard.price()+mouse.price();
}else if(grade == 3){// Legion机箱 + 三星显示器 + 罗技键鼠
LegionHost host = new LegionHost();
SamsungMonitor monitor = new SamsungMonitor();
LogitechKeyboard keyboard = new LogitechKeyboard();
LogitechMouse mouse = new LogitechMouse();
list.add(host);
list.add(monitor);
list.add(keyboard);
list.add(mouse);
price = host.price()+monitor.price()+keyboard.price()+mouse.price();
}
StringBuilder builder = new StringBuilder();
builder.append(name+"组装电脑:\r\n");
builder.append("套餐:" + grade + "\r\n");
builder.append("套餐价格:" + price + " 元\r\n");
builder.append("配件清单:\r\n");
for (Computer computer : list) {
builder.append(computer.parts()+"、");
builder.append(computer.brand()+"、");
builder.append(computer.model()+"、");
builder.append(computer.price()+"、");
builder.append(computer.desc()+ "\r\n");
}
System.out.println("************************");
return builder.toString();
}
public static void main(String[] args) {
System.out.println(getComputerList("哪吒",1));
System.out.println(getComputerList("敖丙",2));
System.out.println(getComputerList("妲己",3));
}
}
哪吒哥,不差钱!
这代码写的没毛病,根据选择的套餐等级,组装不同配置的电脑,无脑ROG就是爽!
组装一个电脑,需要主机、显示器、键盘、鼠标。
package com.guor.builder;
public interface IComputer {
// 主机
IComputer appendHost(Computer computer);
// 显示器
IComputer appendMonitor(Computer computer);
// 键盘
IComputer appendKeyboard(Computer computer);
// 鼠标
IComputer appendMouse(Computer computer);
// 电脑清单
String getComputerDetail();
}
package com.guor.builder;
import java.util.ArrayList;
import java.util.List;
public class BuilderComputer implements IComputer {
// 配件清单
private List<Computer> list = new ArrayList<Computer>();
// 组装价格
private Double price = 0.00;
// 姓名
private String name;
// 套餐
private int grade;
public BuilderComputer(String name, int grade) {
this.name = name;
this.grade = grade;
}
@Override
public IComputer appendHost(Computer computer) {
list.add(computer);
price += computer.price();
return this;
}
@Override
public IComputer appendMonitor(Computer computer) {
list.add(computer);
price += computer.price();
return this;
}
@Override
public IComputer appendKeyboard(Computer computer) {
list.add(computer);
price += computer.price();
return this;
}
@Override
public IComputer appendMouse(Computer computer) {
list.add(computer);
price += computer.price();
return this;
}
@Override
public String getComputerDetail() {
StringBuilder builder = new StringBuilder();
builder.append(name+"组装电脑:\r\n");
builder.append("套餐:" + grade + "\r\n");
builder.append("套餐价格:" + price + " 元\r\n");
builder.append("配件清单:\r\n");
for (Computer computer : list) {
builder.append(computer.parts()+"、");
builder.append(computer.brand()+"、");
builder.append(computer.model()+"、");
builder.append(computer.price()+"、");
builder.append(computer.desc()+ "\r\n");
}
System.out.println("************************");
return builder.toString();
}
}
package com.guor.builder;
public class Builder {
public IComputer levelOne(){
return new BuilderComputer("哪吒",1)
.appendHost(new RogHost())
.appendMonitor(new Rog32Monitor())
.appendKeyboard(new RogKeyboard())
.appendMouse(new RogMouse());
}
public IComputer levelTwo(){
return new BuilderComputer("敖丙",2)
.appendHost(new RogHost())
.appendMonitor(new Rog27Monitor())
.appendKeyboard(new LogitechKeyboard())
.appendMouse(new LogitechMouse());
}
public IComputer levelThree(){
return new BuilderComputer("妲己",3)
.appendHost(new LegionHost())
.appendMonitor(new SamsungMonitor())
.appendKeyboard(new LogitechKeyboard())
.appendMouse(new LogitechMouse());
}
public static void main(String[] args) {
Builder builder = new Builder();
System.out.println(builder.levelOne().getComputerDetail());
System.out.println(builder.levelTwo().getComputerDetail());
System.out.println(builder.levelThree().getComputerDetail());
}
}
与上面结果一致。
去掉了繁琐的ifelse,符合单一职责原则、开闭原则,代码可读性、复用性、拓展性强。
很多人觉得设计模式很简单,但是,能够熟练的将设计模式应用在自己的项目中,将各模块、功能规划的井井有条,运用的炉火纯青、恰到好处,真的很难。反复阅读,仔细体会。
设计模式系列文章:
java设计模式1,单一职责原则
java设计模式2,开闭原则
java设计模式3,里氏替换原则
java设计模式4,不要和陌生人说话
java设计模式5,接口隔离原则
Java设计模式6,依赖倒置原则
java设计模式7,工厂方法模式
Java设计模式8,校验、审批流程改善神器,责任链模式
一篇打通架构设计,Java设计模式9,模板方法模式