西乡建网站公司,咋样建设网站,泰安房产网签,官方微信开发文章目录 七、原型模式八、建造者模式 七、原型模式
原型模式#xff08;Prototype Pattern#xff09;是用于创建重复的对象#xff0c;同时又能保证性能。它提供了一种创建对象的最佳方式。 这种模式是实现了一个原型接口#xff0c;该接口用于创建当前对象的克隆。当直… 文章目录 七、原型模式八、建造者模式 七、原型模式
原型模式Prototype Pattern是用于创建重复的对象同时又能保证性能。它提供了一种创建对象的最佳方式。 这种模式是实现了一个原型接口该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时则采用这种模式。 例如一个对象需要在一个高代价的数据库操作之后被创建。我们可以缓存该对象在下一个请求时返回它的克隆在需要的时候更新数据库以此来减少数据库调用。
例如
创建一个可复制的支付类
public class WxPay implements Cloneable{public WxPay(){System.out.println(创建支付对象);}public WxPay clone() throws CloneNotSupportedException {System.out.println(复制对象);return (WxPay) super.clone();}
}使用
public class demo {public static void main(String[] args) throws CloneNotSupportedException {WxPay pay new WxPay();WxPay pay1 pay.clone();System.out.println(pay);System.out.println(pay1);}
}可以看到创建了两个不同的对象只进行了一次构件函数的执行当直接创建对象的代价比较大时就可以采用这种模式。
另外原型的拷贝又有浅拷贝和深拷贝两个层次上面的方式就是浅拷贝只把当前对象做了拷贝如果对象中有其他对象的引用就不会进行拷贝修改任意一个对象中的引用对其他都会有影响。
比如上面的WxPay类做如下修改
先定义其他操作类
public class OtherOperation {private String name;public String getName() {return name;}public void setName(String name) {this.name name;}
}再修改WxPay类
public class WxPay implements Cloneable {private OtherOperation otherOperation new OtherOperation();public WxPay() {System.out.println(创建支付对象);}public WxPay clone() throws CloneNotSupportedException {System.out.println(复制对象);return (WxPay) super.clone();}public OtherOperation getOperation() {return otherOperation;}public String getName() {return otherOperation.getName();}}演示
public class demo {public static void main(String[] args) throws CloneNotSupportedException {WxPay pay new WxPay();WxPay pay1 pay.clone();System.out.println(pay);System.out.println(pay1);System.out.println(pay.getOperation());System.out.println(pay1.getOperation());pay.getOperation().setName(abc);System.out.println(pay1.getOperation().getName());}
}上面可以看出WxPay确实是复制出了一个实例但是WxPay里面的OtherOperation实例没有复制还只向同一个地址导致只要修改任意一个对象中的OtherOperation对其他实例都会有影响。
上面已经看出默认是浅拷贝但有的时候我们又需要其中引用的对象也要为新实例那怎么做呢下面就来看下深拷贝的实现方式
深拷贝实现方式 1重写 clone 方法来实现深拷贝 深拷贝实现方式 2通过对象序列化实现深拷贝(推荐)
实现方式 1重写 clone 方法来实现深拷贝
修改 OtherOperation类
public class OtherOperation implements Cloneable{private String name;public OtherOperation clone() throws CloneNotSupportedException {System.out.println(复制OtherOperation对象);return (OtherOperation) super.clone();}public String getName() {return name;}public void setName(String name) {this.name name;}
}
修改WxPay在clone中再复制OtherOperation 以达到深拷贝的效果
public class WxPay implements Cloneable {private OtherOperation otherOperation new OtherOperation();public WxPay() {System.out.println(创建支付对象);}public WxPay clone() throws CloneNotSupportedException {System.out.println(复制对象);WxPay wxPay (WxPay) super.clone();wxPay.otherOperation otherOperation.clone();return wxPay;}public OtherOperation getOperation() {return otherOperation;}public String getName() {return otherOperation.getName();}}演示
public class demo {public static void main(String[] args) throws CloneNotSupportedException {WxPay pay new WxPay();WxPay pay1 pay.clone();System.out.println(pay);System.out.println(pay1);System.out.println(pay.getOperation());System.out.println(pay1.getOperation());pay.getOperation().setName(abc);System.out.println(pay1.getOperation().getName());}
}可以看到WxPay 和 OtherOperation 都是新实例。
深拷贝实现方式 2通过对象序列化实现深拷贝
OtherOperation 实现 Serializable
public class OtherOperation implements Serializable {private String name;public String getName() {return name;}public void setName(String name) {this.name name;}
}WxPay 实现Serializable并提供方法对当前对象进行序列化操作
public class WxPay implements Serializable {private OtherOperation otherOperation new OtherOperation();public WxPay() {System.out.println(创建支付对象);}public OtherOperation getOperation() {return otherOperation;}public String getName() {return otherOperation.getName();}public WxPay deepClone() {//创建流对象ByteArrayOutputStream bos null;ObjectOutputStream oos null;ByteArrayInputStream bis null;ObjectInputStream ois null;try {//序列化bos new ByteArrayOutputStream();oos new ObjectOutputStream(bos);oos.writeObject(this); //当前这个对象以对象流的方式输出//反序列化bis new ByteArrayInputStream(bos.toByteArray());ois new ObjectInputStream(bis);return (WxPay) ois.readObject();}catch (Exception e) {return null;}finally {//关闭流try {bos.close();oos.close();bis.close();ois.close();}catch (Exception e2) {System.out.println(e2.getMessage());}}}
}效果
public class demo {public static void main(String[] args) throws CloneNotSupportedException {WxPay pay new WxPay();WxPay pay1 pay.deepClone();System.out.println(pay);System.out.println(pay1);System.out.println(pay.getOperation());System.out.println(pay1.getOperation());pay.getOperation().setName(abc);System.out.println(pay1.getOperation().getName());}
}和上面我们手动的方式是一样的效果。
八、建造者模式
建造者模式Builder Pattern使用多个简单的对象一步一步构建成一个复杂的对象。将一个复杂的构建与其表示相分离使得同样的构建过程可以创建不同的表示。主要解决在软件系统中有时候面临着一个复杂对象的创建工作其通常由各个部分的子对象用一定的算法构成由于需求的变化这个复杂对象的各个部分经常面临着剧烈的变化但是将它们组合在一起的算法却相对稳定。
例如在游戏场景中需要构建人物模型可能要先构建头部、再构建身体、然后四肢部分最后才是一个完整的人物如果都写在一起肯定会导致代码复杂不易其他开发人员理解对后期维护扩展难度都大如果使用构建者模式便可以将头部、身体、四肢写在不同的人物实现里面最后由一个构建类去按照一定的顺序加载它们然后组成了一个更大的复杂的对象这样便有利于维护扩展。
下面我们借助上面的例子简单用构建者模式实现下
定义人物对象这里直接将头、身体、四肢简化为属性的形式表达。
Data
public class Person {private String head;private String body;private String foot;
}定义人物构建接口并定义具体的抽象方法。
public interface PersonBuilder {//构建入口Person Builder();//构建头部void builderHead();//构建身体void builderBody();//构建四肢void builderFoot();
}定义一个男孩人物的具体构建实现
public class BoyBuilder implements PersonBuilder {private Person person;public BoyBuilder() {person new Person();}Overridepublic Person Builder() {builderHead();builderBody();builderFoot();System.out.println(构建完成);return person;}Overridepublic void builderHead() {System.out.println(开始构建男孩头部...);person.setHead(男孩头部信息);}Overridepublic void builderBody() {System.out.println(开始构建男孩身体...);person.setBody(男孩身体信息);}Overridepublic void builderFoot() {System.out.println(开始构建男孩四肢...);person.setFoot(男孩四肢部分信息);}}演示
public class demo {public static void main(String[] args) {PersonBuilder personBuilder new BoyBuilder();Person person personBuilder.Builder();System.out.println(StringFormatter.concat(构建对象, person.toString()).getValue());}}上面就是将一个人物的不同部分分别构建实际中每个小的构建都应该在具体的实现中去表达这里简化为了一个属性一个复杂的对象的构建与它的表示分离使得同样的构建过程可以创建不同的表示。