淘宝客网站源码加各类插件,西安seo培训哪个好,天津市建设工程交易网,广告策划方案怎么做原型模式
原型模式#xff08;Prototype Pattern#xff09;是指原型实例指定创建对象的种类#xff0c;并且通过拷贝这些这些原型创建新的对象#xff0c;属于创建型模式。#xff08;对不通过new关键字#xff0c;而是通过对象拷贝来实现创建对象的模式称为原型模式Prototype Pattern是指原型实例指定创建对象的种类并且通过拷贝这些这些原型创建新的对象属于创建型模式。对不通过new关键字而是通过对象拷贝来实现创建对象的模式称为原型模式。
原型模式的核心在于拷贝原型对象。以系统中已经存在的一个对象为原型直接基于内存二进制流进行拷贝无需再经历耗时的对象初始化过程不调用构造函数。
原型模式适用以下场景
类初始化消耗资源比较多new产生的一个对象需要非常繁琐的过程构造函数比较复杂循环体中产生大量的对象 一个标准的原型模式代码
interface IPrototypeT{T clone();
}class ConcretePrototype implements IPrototype{private int age;private String name;public int getAge() {return age;}public void setAge(int age) {this.age age;}public String getName() {return name;}public void setName(String name) {this.name name;}Overridepublic ConcretePrototype clone() {ConcretePrototype concretePrototype new ConcretePrototype();concretePrototype.setAge(this.age);concretePrototype.setName(this.name);return concretePrototype;}Overridepublic String toString() {return ConcretePrototype{ age age , name name \ };}
}public class Test {public static void main(String[] args) {ConcretePrototype prototype new ConcretePrototype();prototype.setAge(18);prototype.setName(Tom);System.out.println(prototype);ConcretePrototype cloneType prototype.clone();System.out.println(cloneType);}
}上面的复制过程是我们自己完成的另外JDK已经帮我们实现了一个现成的API我们只需要实现Cloneable接口即可。
class ConcretePrototype implements Cloneable{private int age;private String name;public int getAge() {return age;}public void setAge(int age) {this.age age;}public String getName() {return name;}public void setName(String name) {this.name name;}Overridepublic ConcretePrototype clone() {try {return (ConcretePrototype) super.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();return null;}}Overridepublic String toString() {return ConcretePrototype{ age age , name name \ };}
}
然而复制后的克隆对象是的成员复制的不是值而是引用的地址。如果我们修改任意一个对象中的属性值prototype和cloneType的属性值都会改变。这就是我们常说的浅克隆。只是完整复制了值数据类型没有赋值引用对象所有的引用对象仍然指向原来的对象。
使用序列化实现深度克隆
class ConcretePrototype implements Cloneable, Serializable {private int age;private String name;private ListString hobbies;public int getAge() {return age;}public void setAge(int age) {this.age age;}public String getName() {return name;}public void setName(String name) {this.name name;}public ListString getHobbies() {return hobbies;}public void setHobbies(ListString hobbies) {this.hobbies hobbies;}Overridepublic ConcretePrototype clone() {try {return (ConcretePrototype) super.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();return null;}}public ConcretePrototype deepClone(){try{ByteArrayOutputStream bos new ByteArrayOutputStream();ObjectOutputStream oos new ObjectOutputStream(bos);oos.writeObject(this);ByteArrayInputStream bis new ByteArrayInputStream(bos.toByteArray());ObjectInputStream ois new ObjectInputStream(bis);return (ConcretePrototype) ois.readObject();}catch (Exception e){e.printStackTrace();return null;}}Overridepublic String toString() {return ConcretePrototype{ age age , name name \ , hobbies hobbies };}
}public class Test {public static void main(String[] args) {ConcretePrototype prototype new ConcretePrototype();prototype.setAge(18);prototype.setName(Tom);ListString hobbies new ArrayList();hobbies.add(Math);hobbies.add(baseball);prototype.setHobbies(hobbies);System.out.println(prototype);ConcretePrototype cloneType prototype.deepClone();System.out.println(cloneType);System.out.println(prototype.getHobbies());System.out.println(cloneType.getHobbies());System.out.println(prototype.getHobbies() cloneType.getHobbies());}
}克隆破坏单例模式
如果我们克隆的目标对象是单例对象那么深克隆就会破坏单例。为了防止克隆破坏单例只要禁止深克隆就行。
一种是不实现Cloneable接口重新clone方法在clone方法中返回单例对象即可。
原型模式的优缺点
优点
1、性能优良Java自带的原型模式是基于内存二进制流的拷贝比直接new一个对象性能提升许多。
2、可以使用深克隆方式保存对象的状态使用原型模式将对象复制一份并将其保存起来简化了创建对象的过程。
缺点
1、需要为每一个类配置一个克隆方法。
2、克隆方法位于类的内部当对已有的类进行改造的时候需要修改代码违反了开闭原则。
3、实现深度克隆需要编写较为复杂的代码。
建造者模式
建造者模式Builder Pattern是将一个复杂对象的构建过程与它的表示分离使得同样的构建过程可以创建不同的表示属于创建型模式。建造者模式适用于创建对象需要很多步骤但步骤的顺序不一定固定。如果一个对象有非常复杂的内部结构很多属性可以将复杂对象的创建和使用进行分离。
建造者模式的基本写法
import lombok.Data;Data
class Course{private String name;private String ppt;private String video;
} class CourseBuilder{private Course course new Course();public void addName(String name){course.setName(name);}public void addPpt(String ppt){course.setPpt(ppt);}public void addVideo(String video){course.setVideo(video);}public Course build(){return this.course;}
}public class Test {public static void main(String[] args) {CourseBuilder builder new CourseBuilder();builder.addName(设计模式);builder.addPpt(【ppt】);builder.addVideo(【视频】);Course course builder.build();System.out.println(course);}
}建造者模式的链式写法
import lombok.Data;class CourseBuilder{Datapublic class Course{private String name;private String ppt;private String video;}private Course course new Course();public CourseBuilder addName(String name){course.setName(name);return this;}public CourseBuilder addPpt(String ppt){course.setPpt(ppt);return this;}public CourseBuilder addVideo(String video){course.setVideo(video);return this;}public Course build(){return this.course;}
}public class Test {public static void main(String[] args) {CourseBuilder builder new CourseBuilder().addName(设计模式).addPpt(【ppt】).addVideo(【视频】);System.out.println(builder.build());}
}在JDK中StringBuilder它提供append()方法就是应用了建造者模式。
建造者模式的优缺点
优点
1、封装性好创建和使用分离
2、扩展性好建造类之间独立一定程度上解耦。
缺点
1、产生多余的Builder对象
2、产品内部发生变化建造者都要修改成本比较大。
建造者模式和工厂模式的区别
1、建造者模式更加注重方法的调用顺序工厂模式注重于创建对象。
2、创建对象的力度不同建造者模式创建复杂的对象由各种复杂的部件组成工厂模式创建出来的都一样。
3、关注点不一样工厂模式只需要把对象创建出来就可以了而建造者模式不仅要创建这个对象还要知道这个对象由哪些部件组成。
4、建造者模式根据建造过程中的顺序不一样最终的对象部件组成也不一样。