(三)原型模式(创建者模式)
原型模式定义
原型模式是通过复制一个原型对象来创建新的对象,不需要了解创建对象的细节,核心是在于拷贝原型对象。
原型模式优缺点
优点
- 可以提高性能;
- 无需考虑构造函数,直接创建一个对象;
缺点
- 配备克隆方法的对象需要通盘考虑,保证克隆对象的完整,不让容易出现部分引入对象浅拷贝问题;
原型模式类图
原型模式适用场景
- 资源优化场景,类初始化需要消耗资源,原型模式可以节省该资源;
- 一个对象多个修改者时,防止相互影响可以使用;
- 性能与安全要求场景时,new一个新的对象需要繁琐的数据准备和访问权限限制;
原型模式实现方式
原型模式可以通过浅拷贝或者深拷贝来实现;
浅拷贝
- 对于数据类型是基本数据类型的成员变量,浅拷贝会直接进行值传递,也就是将该属性值复制一份给新的对象;
- 对于引入数据类型的成员变量,浅拷贝仅仅将该成员变量引用值(内存地址)复制给新对象,新对象的引用数据类型变化会影响原对象;
代码
@Data
public class User implements Cloneable {
private String name;
private Integer age;
private List<Map<String,Object>> maps;
@Override
public User clone() throws CloneNotSupportedException{
return (User) super.clone();
}
}
public static void main(String[] args) throws CloneNotSupportedException {
User user = new User();
user.setName("li");
user.setAge(2);
List<Map<String,Object>> list = new ArrayList<>();
Map<String,Object> map = new HashMap<>();
map.put("a",4);
list.add(map);
user.setMaps(list);
User clone = user.clone();
System.out.println(clone);
System.out.println(user);
List<Map<String, Object>> maps = clone.getMaps();
maps.clear();
System.out.println(clone);
System.out.println(user);
}
深拷贝
- 复制对象的所有基本数据类型的成员变量值;
- 为所有引用数据类型的成员变量申请存储空间,并复制每个引用数据类型成员变量所引用的对象,直到该对象可达的所有对象。也就是说,对象进行深拷贝要对整个对象(包括对象的引用类型)进行拷贝;
代码
@Data
public class User implements Cloneable {
private String name;
private Integer age;
private List<Map<String,Object>> maps;
@Override
public User clone() throws CloneNotSupportedException{
User clone = (User) super.clone();
String jsonString = JSONObject.toJSONString(this.getMaps());
List<Map> maps1 = JSONObject.parseArray(jsonString, Map.class);
List<Map<String, Object>> collect = maps1.stream().map(x -> (Map<String, Object>) x).collect(Collectors.toList());
clone.setMaps(collect);
return clone;
}
}
public static void main(String[] args) throws CloneNotSupportedException {
User user = new User();
user.setName("li");
user.setAge(2);
List<Map<String,Object>> list = new ArrayList<>();
Map<String,Object> map = new HashMap<>();
map.put("a",4);
list.add(map);
user.setMaps(list);
User clone = user.clone();
System.out.println(clone);
System.out.println(user);
List<Map<String, Object>> maps = clone.getMaps();
maps.clear();
System.out.println(clone);
System.out.println(user);
}
(四)建造者模式(创建者模式)
创建者模式定义
创建者模式也叫生成器模式,将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
创建者模式优缺点
优点
- 使对象创建和使用分离,具有良好的封装性;
- 同一个对象可以根据建筑类的不同建造出不同属性对象,建造类之间互相独立,扩展性好,同时在一定程度上解耦。
缺点
- 产生了多余的建造对象,实体类数量增加;
- 当产品类出现改变时,会影响到建造类,导致修改困难;
创建者模式类图
创建者模式适用场景
- 相同的方法,不同执行顺序,产生不同结果时可以使用创建者模式;
- 多个部分装配到指定对象时可以使用创建者模式;
创建者模式实现方式
对象
@Data
@NoArgsConstructor
@AllArgsConstructor
public class CarProduct {
private String name;
private String wheels;
private String engine;
private String tail;
}
建造者和具体建造实现类
// 抽象的建造对象
public abstract class CarBuilder {
protected CarProduct car = new CarProduct();
abstract void builderName();
abstract void builderWheels();
abstract void builderEngine();
abstract void builderTail();
public CarProduct buildCar(){return car;}
}
// 具体的建造对象
public class XiaoMiCar extends CarBuilder {
@Override
void builderName() {super.car.setName("this is xiaomi car");}
@Override
void builderWheels() {super.car.setWheels("this is Non-slip tires");}
@Override
void builderEngine() {super.car.setEngine("V8 engines");}
@Override
void builderTail() {}
}
public class YeMaCar extends CarBuilder {
@Override
void builderName() {this.car.setName("this is YeMa car");}
@Override
void builderWheels() {this.car.setWheels("this is sports car tires");}
@Override
void builderEngine() {this.car.setEngine("this is v12 engines");}
@Override
void builderTail() {this.car.setTail("presence of a tail fin");}
}
指挥类和使用者
// 指挥类
public class CarDirector {
CarBuilder builder = null;
public CarDirector(CarBuilder builder) {this.builder = builder;}
public CarProduct builder(){
builder.builderName();
builder.builderWheels();
builder.builderEngine();
builder.builderTail();
return builder.buildCar();
}
}
// 使用者
public class Main {
public static void main(String[] args) {
CarProduct builder = new CarDirector(new XiaoMiCar()).builder();
System.out.println(builder.toString());
}
}