[Musings]
最近沉迷设计模式了,挺好玩的,今天是建造者模式,最常见的builder,通过链式调用来方便构造,这个是我日常使用中觉得最实用的
建造者模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| public class Order { private String mainFood; private int number; private String address;
Order(String address) { this.address = address; }
public void setMainFood(String mainFood) { this.mainFood = mainFood; }
public void setAddress(String address) { this.address = address; }
public void setNumber(int number) { this.number = number; } }
public interface OrderBuilder { OrderBuilder setMainFood(String mainFood);
OrderBuilder setNumber(int number);
Order build(); }
public class MeituanOrderBuilder implements OrderBuilder { private Order order;
public MeituanOrderBuilder(String address) { this.order = new Order(address); }
@Override public OrderBuilder setMainFood(String mainFood) { this.order.setMainFood(mainFood); return this; }
@Override public OrderBuilder setNumber(int number) { this.order.setNumber(number); return this; }
@Override public Order build() { return this.order; } }
public class Main { public static void main(String[] args) { MeituanOrderBuilder builder = new MeituanOrderBuilder("123"); Order abc = builder.setMainFood("abc") .setNumber(12) .build(); } }
|
这是第一个简单版本的,然后我就想,如果在调用的时候可以写成下面这个版本,就更舒服了
1 2 3 4 5 6 7 8 9
| public class Main { public static void main(String[] args) { Order abc = Order.withMeituanBuilder() .setMainFood("abc") .setNumber(12) .build(); } }
|
然后我就开始班门弄斧,其实就是抽象工厂+建造者模式,builder返回不同的抽象工厂,然后每个工厂去做建造
1 2 3 4 5 6 7 8
| package org.example.builder;
public class Order { public static MeituanOrderBuilder withMeiTuanBuilder(String address){ return new MeituanOrderBuilder(address); } }
|
主要这里考虑的几个点:
- 建造者通过对超多参数的情况进行优化,防止构造函数过于复杂
- 通过链式调用来清晰明了的书写代码
- 考虑是否使用final来修饰字段,这样可以确保建造者模式在set完以后是固定的
第三点其实根据场景和设计需求考虑,设计模式本身就是灵活的,一起都要基于业务场景的上下文来实现,而不是单纯的照抄,理解核心原理,就像打太极一样,学会了,又好像没学,什么都忘了,想用的时候,让灵感飘动起来
所以到此为止,记住特性的区别
🏭 工厂方法:一个产品,多种实现
🏭 抽象工厂:一套产品,整体替换
🔨 建造者:复杂对象,分步构建
📋 原型:已有对象,复制使用
👑 单例:全局唯一,严格控制
原型模式
原型模式的核心就是两个
- 实现cloneable接口,重写clone方法
- 注意深浅拷贝,对于引用对象实现深拷贝
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| public class Address implements Cloneable{ private String city; private List<String> tags = new ArrayList<>();
public List<String> getTags() { return tags; }
public void setTags(List<String> tags) { this.tags = tags; }
public String getCity() { return city; }
public void setCity(String city) { this.city = city; }
public Address(Address other){ this.city = other.city; this.tags = new ArrayList<>(other.tags); }
@Override protected Object clone() throws CloneNotSupportedException { Address clone = (Address) super.clone(); clone.tags = new ArrayList<>(this.tags); return clone; } }
public class Main { public static void main(String[] args) throws CloneNotSupportedException { Address address = new Address(); Address clone = (Address) address.clone(); address.getTags().add("1"); System.out.println(address); System.out.println(clone); } }
|
其实很简单,就这么个逻辑