(五岁以下儿童)原型模型 Prototype
样机模型旨在复制一个现有对象来创建新对象。而不是通过的方式的实例。原型模式须要实现 Cloneable 接口。覆写clone方法,复制分为浅复制、深复制。
浅复制:将一个对象复制后。基本数据类型的变量都又一次创建,引用类型。指向的还是原对象所指向的。
深复制:讲一个对象复制后。不论基本数据类型和引用类型,都是又一次创建。是全然的彻底的复制。
public class ProtoType { public static void main(String[] args) throws Exception { Father f=new Father(); User u1=new User("123456",f); User u2=(User)u1.clone(); User u3=(User) u1.shallowClone(); System.out.println(u1==u2); //false System.out.println(u1.f==u2.f); //false System.out.println(u1.password == u2.password); //false System.out.println(u1.f==u3.f); //true System.out.println(u1.password == u3.password); //true } } class User implements Cloneable,Serializable{ String password; Father f; public User(String password,Father f){ this.password=password; this.f=f; } //浅复制 public Object shallowClone() throws CloneNotSupportedException{ User user = (User)super.clone(); return user; } //深复制 public Object clone() throws CloneNotSupportedException { //return super.clone(); ObjectOutputStream out=null; ObjectInputStream in=null; try { ByteArrayOutputStream bo = new ByteArrayOutputStream(); out = new ObjectOutputStream(bo); out.writeObject(this); out.flush(); byte[] bs = bo.toByteArray(); ByteArrayInputStream bi = new ByteArrayInputStream(bs); in = new ObjectInputStream(bi); Object o = in.readObject(); return o; } catch (IOException e) { e.printStackTrace(); return null; } catch (ClassNotFoundException e) { e.printStackTrace(); return null; } finally{ try { out.close(); in.close(); } catch (IOException e) { e.printStackTrace(); } } } } class Father implements Serializable{}原型模式与调用构造函数相比,复制创建的新对象会包括原始对象的某些状态,尤其当多个对象的类在属性上存在细微区别,方法全然同样时候。
浅复制与深复制还存在一个问题就是引用类型成本的问题。对于代码来说就是 Father 值的问题。上面的代码改动下。
class Father implements Serializable{ String name = "father"; } public static void main(String[] args) throws Exception { Father f = new Father(); User u1 = new User("123456",f); User u2 = (User)u1.clone(); User u3 = (User) u1.shallowClone(); u1.f.name = "aaaa"; System.out.println(u1.f.name); //aaaa 原型 System.out.println(u2.f.name); //father 深复制 System.out.println(u3.f.name); //aaaa 浅复制 }这样应该能跟深刻的理解了。
(六)适配器模式
适配器的意义在于,使用不同接口的类所提供的服务为client提供它所期望的接口。原类型不做不论什么改变。用一个适配器把一个接口转成还有一个接口,扩展了新的接口。适配器是面向对象的精髓。适配器模式主要分为三类:类的适配器模式、对象的适配器模式、接口的适配器模式。
类的适配器模式:
Source类。拥有一个方法。待适配,目标接口 Targetable 。通过 Adapter 类将source的功能扩展到 targetable 。
class Source{ public void method1(){ System.out.println("this is original method!"); } } interface Targetable{ //原类中的方法 public void method1(); //新类中的方法 public void method2(); } class Adapter extends Source implements Targetable{ //能够覆写Source的方法。也能够删去method1.会调用Source的 public void method1() { super.method1(); System.out.println("targetable method1"); } public void method2() { System.out.println("targetable method2"); } } public class AdapterTest { public static void main(String[] args) { Targetable target = new Adapter(); target.method1(); target.method2(); } }对象的适配器模式:
跟类的适配器模式基本同样,仅仅是不继承Source 类,持有Source类的实例。
class Adapter implements Targetable{// extends Source implements Targetable{ private Source source; public Adapter(Source source){ super(); this.source = source; } //能够覆写Source的方法。也能够删去method1.会调用Source的 public void method1() { source.method1(); System.out.println("targetable method1"); } public void method2() { System.out.println("targetable method2"); } } public class AdapterTest { public static void main(String[] args) { Source source = new Source(); Adapter target = new Adapter(source); target.method1(); target.method2(); } }接口适配器:
接口适配器跟前两种有点差别。一个接口会有多个抽象方法,我们写接口的实现类的时候,必须实现该接口全部的方法,可是并非全部方法都是我们须要的,为了解决问题。我们引入了接口适配器。借助于一个抽象类,改抽象类实现了上面的接口,并实现了全部的方法。而我们不和原始的接口打交道,仅仅和该抽象类取得联系。
我们最后写一个类,继承该抽象类。重写我们须要的方法。
interface Sourceable{ public void method1(); public void method2(); } abstract class Wrapper implements Sourceable{ //父类或者子类必须有一个实现method1 跟method2接口 public void method1(){System.out.println("Wrapper method1");} public void method2(){System.out.println("Wrapper method2");} } class SourceSub1 extends Wrapper{ //由于父类已经实现了method2所以不会报错 public void method1(){ System.out.println("SourceSub1"); } } class SourceSub2 extends Wrapper{ public void method2(){ System.out.println("SourceSub2"); } } public class AdapterInterface { public static void main(String[] args){ SourceSub1 source1 = new SourceSub1(); SourceSub2 source2 = new SourceSub2(); source1.method1(); //SourceSub1 source1.method2(); //Wrapper method2 source2.method1(); //Wrapper method1 source2.method2(); //SourceSub2 } }
版权声明:本文博客原创文章,博客,未经同意,不得转载。