• Java设计模式(三)原型模型 适配器型号


    (五岁以下儿童)原型模型 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
    	}
    }




    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    数据库系统原理:范式理论
    数据库系统原理:MVCC
    数据库系统原理:悲观锁、乐观锁
    数据库系统原理:封锁
    数据库系统原理:四大隔离级别
    数据库系统原理:ACID的作用以及实现原理
    计算机网络HTTP:长连接与短连接
    计算机网络HTTP:HTTP缓存
    计算机网络HTTP:状态码
    yum安装Docker
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4644612.html
Copyright © 2020-2023  润新知