目录
建造者模式
简介
使用场景
优缺点
模式结构
实现
原型模式
简介
应用场景
优缺点
模式结构
实现
建造者模式
简介
将复杂对象的构建与表示进行分离,使得同样的构建过程可以创建不同的表示。是一个将复杂的对象分解为多个简单的对象,然后一步一步构建而成。它将变与不变分离,即产品的组成部分是不变的,但是每一部分都可以灵活选择。
使用场景
1.当创建对象复杂时,可以将创建对象的步骤分离出去,使用建造者模式
2.对于一些复杂的对象,如果对象的属性是由许多不同部分组成的,而这些部分需要按照一定的步骤进行创建,那么就可以使用建造者模式
3.如果有许多相似的对象需要被创建,而且这些对象的创建过程相同,只是初始值不同,那么就可以使用建造者模式
4.如果想要创建一个对象,但是对象的创建过程需要使用一些敏感信息,比如密码等,那么就可以使用建造者模式来保证这些敏感信息的安全性
优缺点
优点:
1.封装性好,构建和表示分离
2.扩展性好,各个具体的建造者相互独立,有利于系统解耦
3.客户端不必知道产品内部的组成和细节,建造者可以对创建过程逐步细化,而不对其他模块产生任何影响,便于控制细节风险
缺点:
1.产品的组成部分必须相同,限制了其使用范围
2.产品内部发生变化,建造者也要修改,后期维护成本较大
模式结构
角色:
产品角色:包含多个组成部分的复杂对象,由具体建造者来创建其各个零部件
抽象建造者:包含创建产品各个子部件的抽象方法接口
具体建造者:实现 Builder 接口,完成复杂产品的各个部件的具体创建方法
指挥者:调用建造者对象中的部件构造与装配方法完成复杂对象的创建,在指挥者中不涉及具体产品的信息
结构图:
实现
//产品角色:包含多个组成部件的复杂对象
class Product {
private String partA;
private String partB;
private String partC;
public void setPartA(String partA) {
this.partA = partA;
}
public void setPartB(String partB) {
this.partB = partB;
}
public void setPartC(String partC) {
this.partC = partC;
}
public void show() {
//显示产品的特性
}
}
//抽象建造者:包含创建产品各个子部件的抽象方法
abstract class Builder {
//创建产品对象
protected Product product = new Product();
public abstract void buildPartA();
public abstract void buildPartB();
public abstract void buildPartC();
//返回产品对象
public Product getResult() {
return product;
}
}
//具体建造者:实现了抽象建造者接口。
public class ConcreteBuilder extends Builder {
public void buildPartA() {
product.setPartA("建造 PartA");
}
public void buildPartB() {
product.setPartB("建造 PartB");
}
public void buildPartC() {
product.setPartC("建造 PartC");
}
}
//指挥者:调用建造者中的方法完成复杂对象的创建
class Director {
private Builder builder;
public Director(Builder builder) {
this.builder = builder;
}
//产品构建与组装方法
public Product construct() {
builder.buildPartA();
builder.buildPartB();
builder.buildPartC();
return builder.getResult();
}
}
//调用
public class Client {
public static void main(String[] args) {
Builder builder = new ConcreteBuilder();
Director director = new Director(builder);
Product product = director.construct();
product.show();
}
}
原型模式
简介
允许通过复制或克隆一个已存在的对象来创建一个新对象,而无需从头开始创建。这种模式在需要生成大量复制相似对象时特别有用。
应用场景
1.创建新对象成本较大时
2.系统要保存对象的状态,而对象的状态变化很小
3.避免使用分层次的工厂类来创建分层次的对象
优缺点
优点:
1.通过复制已有对象,而不是从头创建,节约了时间和资源
2.如果对象包含多层嵌套,深复制会消耗太多资源;原型模式通过浅复制,可以避免
3.可以避免通过构造方法复制时可能出现的错误
不足:
1.增加了系统的复杂性,需要处理原始对象的复制和克隆操作
2.复制对象,增加了内存使用量
3.复制对象时,需确保所有的引用关系都正确的复制了
模式结构
角色:
抽象原型类:声明克隆方法的接口,是所有具体原型类的公共父类,可以是抽象类、接口和具体的实现类
具体原型类:实现抽象原型类中声明的克隆方法,在克隆方法中返回一个自己的克隆对象
客户类:让一个原型对象克隆自己而创建一个新的对象,在客户类中只需要直接实例化或通过工厂方法的创建一个原型对象,再通过该对象的克隆方法即可获得多个相同的对象
实现
1.创建接口抽象类
public abstract class Shape implements Cloneable {
private String id;
protected String type;
abstract void draw();
public String getType(){
return type;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Object clone() {
Object clone = null;
try {
clone = super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return clone;
}
}
2.拓展抽象类的实体类
public class Rectangle extends Shape {
public Rectangle(){
type = "Rectangle";
}
@Override
public void draw() {
System.out.println("Inside Rectangle::draw() method.");
}
}
public class Square extends Shape {
public Square(){
type = "Square";
}
@Override
public void draw() {
System.out.println("Inside Square::draw() method.");
}
}
public class Circle extends Shape {
public Circle(){
type = "Circle";
}
@Override
public void draw() {
System.out.println("Inside Circle::draw() method.");
}
}
3.创建一个类,从数据库获取实体类
import java.util.Hashtable;
public class ShapeCache {
private static Hashtable<String, Shape> shapeMap
= new Hashtable<String, Shape>();
public static Shape getShape(String shapeId) {
Shape cachedShape = shapeMap.get(shapeId);
return (Shape) cachedShape.clone();
}
// 对每种形状都运行数据库查询,并创建该形状
// shapeMap.put(shapeKey, shape);
// 例如,我们要添加三种形状
public static void loadCache() {
Circle circle = new Circle();
circle.setId("1");
shapeMap.put(circle.getId(),circle);
Square square = new Square();
square.setId("2");
shapeMap.put(square.getId(),square);
Rectangle rectangle = new Rectangle();
rectangle.setId("3");
shapeMap.put(rectangle.getId(),rectangle);
}
}
4.进行克隆
public class PrototypePatternDemo {
public static void main(String[] args) {
ShapeCache.loadCache();
Shape clonedShape = (Shape) ShapeCache.getShape("1");
System.out.println("Shape : " + clonedShape.getType());
Shape clonedShape2 = (Shape) ShapeCache.getShape("2");
System.out.println("Shape : " + clonedShape2.getType());
Shape clonedShape3 = (Shape) ShapeCache.getShape("3");
System.out.println("Shape : " + clonedShape3.getType());
}
}
与通过对一个类进行实例化来构造新对象不同的是,原型模式是通过拷贝一个现有对象生成新对象的。浅拷贝实现 Cloneable,重写,深拷贝是通过实现 Serializable 读取二进制流。