⭐简单说两句⭐
作者:后端小知识
CSDN个人主页:后端小知识
GZH:
后端小知识
欢迎关注点赞收藏⭐️留言
当我们需要实列化一个复杂的类,以得到不同结构类型和不同的内部状态的对象时,我们可以用不同的类对它们的实列化操作逻辑分别进行封装,这些类我们就称之为建造者。
当我们需要来之同一个类,但是要就有不同结构对象时,就可以通过构造另一个建造者来进行实列化。
产品类:Product 我们具体需要生成的类对象
抽象建造者类:Builder 为我们需要生成的类对象,构建不同的模块属性,即:公开构建产品类的属性,隐藏产品类的其他功能
具体建造者类: ConcreteBuilder 实现我们要生成的类对象
导演类: Director 确定构建我们的类对象具体有哪些模块属性
简单举个荔枝哈
话说有一天,我们的懒羊羊
接到了慢羊羊
下发的一个Java开发任务:定义一个手机类,创建出对象,并实例化
懒羊羊:小小投个懒吧☺,说罢便分分钟写完代码
懒羊羊:哈哈,我先定义一个Phone类
,浅浅定义几个属性,然后再Client类
中set一下就好啦,分分钟搞定
Phone.java
@Data
@Getter
@Setter
public class Phone{
//运行内存 单位GB ps:为了简写就没有用doc注释
private Integer ram;
//机身内存 单位GB
private Integer rom;
//CPU型号
private String typeCPU;
}
Client.java
public class Client {
public static void main(String[] args) {
Phone phone = new Phone();
phone.setRam(6);
phone.setRom(64);
phone.setTypeCPU("骁龙888");
System.out.println("phone = " + phone);
}
}
懒羊羊:来我们运行看结果
懒羊羊:村长,我写好啦
慢羊羊:这么快就写好啦? 几秒钟后~ ,你这啥玩意啊? 你是想让我去买手机时,还要让我自己动手组装?万一我组装错了不就废了吗,而且你这很明显违反了羊村定的一个最少知道法则啊,重做
【Tips】
当一个对象的组成过程特别繁琐,特别麻烦的时候,就不应该让客户端自己来完成
这样客户端可能会不按正确步骤组装对象,或缺少了某一个组件。
违反了迪米特法则
懒羊羊:可是,可是~~,我不知道怎么做了吖,村长,给个提示呗
慢羊羊:你是真的懒,这样吧,我告诉你个方法,你浅学一下创建者模式,再写一写
【One Hour Later】
懒羊羊:哈哈,我学会了,我再写个PhoneBuilder类
就好了,在里面定义个build方法,然后在build方法里组装就好了,然后再简单改一下Client类
就好啦,真棒
PhoneBuilder.java
public class PhoneBulider {
//关联手机 ps:为了简单,直接这么写的
private Phone phone = new Phone();
public Phone build(){
phone.setRam(12);
phone.setRom(64);
phone.setTypeCPU("骁龙886");
return phone;
}
}
Client.java
public class Client {
public static void main(String[] args) {
PhoneBulider phoneBulider = new PhoneBulider();
Phone build = phoneBulider.build();
System.out.println("build = " + build);
}
}
懒羊羊:村长,村长,我又写完啦,快看看
慢羊羊:嗯,这下是写好了,但是吧 ,我想要高端一点的手机怎么办,或者我也要低端一点的
懒羊羊:这好办,稍等~
慢羊羊:你这合适吗,高端机和低端机一样的配置?
【Tips】
封装地太狠, 客户端没办法选择配置, 都是由服务器端写好的的配置
懒羊羊:那好吧,我定义个HightLevelPhoneBulider类
和MidLevelPhoneBulider类
分别处理就好啦
HightLevelPhoneBulider
public class HightLevelPhoneBulider {
//关联手机 ps:为了简单,直接这么写的
private Phone phone = new Phone();
public Phone build(){
phone.setRam(24);
phone.setRom(512);
phone.setTypeCPU("骁龙888");
return phone;
}
}
MidLevelPhoneBulider
/**
* @Author tiancx
* @create 2023/4/9 11:08
*/
public class MidLevelPhoneBulider {
//关联手机 ps:为了简单,直接这么写的
private Phone phone = new Phone();
public Phone build(){
phone.setRam(12);
phone.setRom(256);
phone.setTypeCPU("骁龙886");
return phone;
}
}
客户端代码如下
结果在这里~
懒羊羊:村长,我又又写好啦,快看
慢羊羊:嗯,这下感觉还不错,不够为啥我感觉你高端机和中端机的组装过程很像啊? 你重复操作的话,一不小心漏了某个步骤可咋办?
【Tips】
无论哪种配置的手机,配置过程都是一样的,只是细节不同,有重复
而且在重复的步骤中,某个建造者可能会漏了某个步骤,也不会报错,但是是不符合要求的
懒羊羊:我知道了,上次喜羊羊说过,这种可以抽象一下,稍等片刻
懒羊羊:我定义一个PhoneBuilder接口,抽象一下就好了,然后让具体的创建者重写一下就好了
PhoneBuilder
public interface PhoneBuilder {
void buildRam();
void buildRom();
void buildTypeCPU();
Phone build();
}
HightLevelPhoneBulider
public class HightLevelPhoneBulider implements PhoneBuilder{
//关联手机 ps:为了简单,直接这么写的
private Phone phone = new Phone();
@Override
public Phone build(){
return phone;
}
@Override
public void buildRam() {
phone.setRam(24);
}
@Override
public void buildRom() {
phone.setRom(512);
}
@Override
public void buildTypeCPU() {
phone.setTypeCPU("骁龙888");
}
}
MidLevelPhoneBulider
public class MidLevelPhoneBulider implements PhoneBuilder{
//关联手机 ps:为了简单,直接这么写的
private Phone phone = new Phone();
@Override
public Phone build(){
return phone;
}
@Override
public void buildRam() {
phone.setRam(12);
}
@Override
public void buildRom() {
phone.setRom(256);
}
@Override
public void buildTypeCPU() {
phone.setTypeCPU("骁龙886");
}
}
客户端代码
运行看下结果
懒羊羊:村长,看,我这次抽象了一下,怎么样啊
慢羊羊:可以,不过你这个,怎么感觉又要我自己组装了啊
懒羊羊:啊这,让我想想怎么办~
懒羊羊:咦,既然不能在客户端封装,那我创建个指挥者来弄吧,真聪明
Director
public class Director {
public Phone build(PhoneBuilder builder){
builder.buildRam();
builder.buildRom();
builder.buildTypeCPU();
return builder.build();
}
}
然后小改一下客户端代码
懒羊羊:村长,这下好了吧,嘻嘻
慢羊羊:阔以,差不多算可以了吧,但是还没有结束额
懒羊羊:什么?还没结束?
慢羊羊:行吧,行吧,今天辛苦你了,下次再来
懒羊羊:休息了一会,我来把刚刚的类图画一下吧
懒羊羊:我们在顺带说一下优缺点吧:
优点:
缺点:
【都看到这了,点点赞点点关注呗,爱你们】
结语
谢谢你的阅读
,由于作者水平有限,难免有不足之处,若读者发现问题,还请批评,在留言区留言或者私信告知,我一定会尽快修改的。若各位大佬有什么好的解法,或者有意义的解法都可以在评论区展示额,万分谢谢。
写作不易,望各位老板点点赞,加个关注!
作者:后端小知识
CSDN个人主页:后端小知识
GZH:后端小知识
欢迎关注点赞收藏⭐️留言