目录
建造者模式
简介
使用场景
优缺点
模式结构
实现
原型模式
简介
应用场景
优缺点
模式结构
实现
建造者模式
简介
将复杂对象的构建与表示进行分离,使得同样的构建过程可以创建不同的表示。是一个将复杂的对象分解为多个简单的对象,然后一步一步构建而成。它将变与不变分离,即产品的组成部分是不变的,但是每一部分都可以灵活选择。
使用场景
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";}@Overridepublic void draw() {System.out.println("Inside Rectangle::draw() method.");}
}public class Square extends Shape {public Square(){type = "Square";}@Overridepublic void draw() {System.out.println("Inside Square::draw() method.");}
}public class Circle extends Shape {public Circle(){type = "Circle";}@Overridepublic 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 读取二进制流。