一、原型模式
定义:用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象。
首先我们介绍下浅克隆和深克隆。
浅克隆: 如果原型对象的成员变量是基本类型,那么就直接复制,如果是引用类型,就只复制对应的内存地址(只复制引用)。(引用类型可的详细内容可参考我之前的文章:JVM系列)
深克隆: 深复制把要复制的对象所引用的对象都复制了一遍。
1、java实现浅克隆
Java 中的 Object 类提供了浅克隆的 clone() 方法,具体原型类只要实现 Cloneable 接口重写clone方法就可实现对象的浅克隆,这里的 Cloneable 接口就是抽象原型类。
代码如下:
public class HeapOOM implements Cloneable {
@Override
public Object clone() throws CloneNotSupportedException {
System.out.println("具体原型复制成功!");
return (HeapOOM) super.clone();
}
}
如果代码中不实现Cloneable接口,在调用clone方法时,会产生空指针异常。
super.clone()是使用父类 Object 类的clone()方法。
2、java实现深克隆
java可以通过序列化的方式实现深克隆。序列化参考:java中的序列化和transient关键字。
序列化就是指将对象转换为字节序列的过程,转换过程就等于复制了对象,但是原来的对象并没有动,只是复制将类型通过流的方式进行读取,然后写到另个内存地址中去。
3、作用
通过clone的方式在获取大量对象时性能影响较小,而new的方式随着实例的对象越来越多,性能会下降很多。
二、建造者模式
建造者模式将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成。它将变与不变相分离,即产品的组成部分是不变的,但每一部分是可以灵活选择的。
与工厂模式的区别是:建造者模式更加关注与零件装配的顺序,一般用来创建更为复杂的对象
一般有以下几个角色:
抽象建造者(builder):描述具体建造者的公共接口,一般用来定义建造细节的方法,并不涉及具体的对象部件的
创建。
具体建造者(ConcreteBuilder):描述具体建造者,并实现抽象建造者公共接口。
指挥者(Director):调用具体建造者来创建复杂对象(产品)的各个部分,并按照一定顺序(流程)来建造复杂
对象。
产品(Product):描述一个由一系列部件组成较为复杂的对象。
别的不说,我们上代码:
产品类:
@Date
public class Product {
//显示屏
private String xianshipin;
//主机
private String zhuji;
//键盘
private String jianpan;
//鼠标
private String shubiao;
//触屏
private String chupin;
}
建造者:
public abstract class Builder {
abstract void bulidXianshipin();
abstract void bulidZhuji();
abstract void bulidJianpan();
abstract void bulidShubiao();
abstract void bulidChupin();
abstract Product getProduct();
}
具体建造者:
public class ConcreteBuilder extends Builder {
private Product product;
public ConcreteBuilder() {
product = new Product();
}
@Override
void bulidXianshipin() {
System.out.println("显示屏");
}
@Override
void bulidZhuji() {
System.out.println("主机");
}
@Override
void bulidJianpan() {
System.out.println("键盘");
}
@Override
void bulidShubiao() {
System.out.println("鼠标");
}
@Override
void bulidChupin() {
System.out.println("触屏");
}
@Override
Product getProduct() {
return product;
}
}
重点来了,下面是指挥者或者叫项目经理:
指挥者:
public class Director {
public Product create(Builder builder) {
builder.bulidZhuji();
builder.bulidXianshipin();
builder.bulidChupin();
//此处有触屏就可以不用键盘和鼠标了,同样的可以选择键盘和鼠标
return builder.getProduct();
}
}
测试类:
public static void main(String[] args) {
Director director = new Director();
//此处用ConcreteBuilder子类
Product create = director.create(new ConcreteBuilder());
System.out.println(create.toString());
}
结果如下:
主机
显示屏
触屏
com.sheji.Product@5f4da5c3
建造者模式主要适用于以下应用场景:
相同的方法,不同的执行顺序,产生不同的结果。
多个部件或零件,都可以装配到一个对象中,但是产生的结果又不相同。
产品类非常复杂,或者产品类中不同的调用顺序产生不同的作用。
初始化一个对象特别复杂,参数多,而且很多参数都具有默认值。