适配器模式、装饰模式、代理模式和外观模式

适配器模式:将一个接口转换成客户端希望的另一个接口,实现不同接口的兼容。有对象适配和类适配两种,用得较多的是对象适配。对象适配其类图如下:


示例代码如下:

package com.peacentury.adapter;

public interface Target {
	public void request();
}

package com.peacentury.adapter;

public class Adapter implements Target{
	Adaptee adaptee;
	
	public Adapter(Adaptee adaptee){
		this.adaptee = adaptee;
	}
	
	@Override
	public void request() {
		adaptee.specificRequest();
	}
}

package com.peacentury.adapter;

public class Adaptee {
	public void specificRequest(){
		System.out.println("adaptee mothod");
	}
}

package com.peacentury.adapter;

public class Client {
	public static void main(String[] args) {
		Adaptee adaptee = new Adaptee();
		
		Target target = new Adapter(adaptee);
		target.request();
	}
}

类适配中,需要适配器继承被适配的类,则此时Target只能是接口(Interface),否则会违背Java中当继承的原则。其类图如下:


装饰模式,总是觉得装饰模式好像挺熟悉的,因为IO中的读写流都用到了装饰,正真理解起来还是花了点时间。装饰模式多数用于动态的添加相关类的功能,比生成子类更灵活,同时实现代码的复用。装饰模式中的角色有1、抽象构件(Component)2、具体构件(Concrete Component)3、装饰器(Decorator)4、具体装饰器(Concrete Decorator)。其类图如下:


具体例子的类图如下:


示例代码如下:

package com.peacentury.decorator;

public interface TransportationTool {
	public void move();
}

package com.peacentury.decorator;

public class Car implements TransportationTool {
	@Override
	public void move() {
		System.out.println("the car can move.");
	}
}

package com.peacentury.decorator;

public class Bus implements TransportationTool {
	@Override
	public void move() {
		System.out.println("the bus can move.");
	}
}

package com.peacentury.decorator;

public class Decorator implements TransportationTool {
	private TransportationTool tool;
	
	public Decorator(TransportationTool tool) {
		this.tool = tool;
	}
	
	@Override
	public void move() {
		tool.move();
	}
}

package com.peacentury.decorator;

public class RunDecorator extends Decorator {
	public RunDecorator(TransportationTool tool) {
		super(tool);
	}
	
	@Override
	public void move() {
		super.move();
		this.run();
	}
	
	public void run(){
		System.out.println("it can run.");
	}
}

package com.peacentury.decorator;

public class SwimDecorator extends Decorator {
	public SwimDecorator(TransportationTool tool) {
		super(tool);
	}
	
	@Override
	public void move() {
		super.move();
		this.swim();
	}
	
	public void swim(){
		System.out.println("it can swim.");
	}
}

package com.peacentury.decorator;

public class FlyDecorator extends Decorator {

	public FlyDecorator(TransportationTool tool) {
		super(tool);
	}
	
	@Override
	public void move() {
		super.move();
		this.fly();
	}
	
	public void fly(){
		System.out.println("it can fly.");
	}
}

package com.peacentury.decorator;

public class Client {
	public static void main(String[] args) {
		TransportationTool car = new Car();
		new FlyDecorator(new SwimDecorator(new RunDecorator(car))).move();
		
		System.out.println("------- a bus in Wuhan--------");
		TransportationTool wuhanBus = new Bus();
		new SwimDecorator(new RunDecorator(wuhanBus)).move();
	}
}

代理模式:为对象提供一种代理以控制对这个对象的访问。其类图如下:


示例代码如下:

package com.peacentury.proxy;

public interface Subject {
	public void doAction();
}

package com.peacentury.proxy;

public class RealSubject implements Subject {
	@Override
	public void doAction() {
		System.out.println("doAction in the RealSubject!");
	}

}

package com.peacentury.proxy;

public class Proxy implements Subject {
	Subject subject = new RealSubject();
	@Override
	public void doAction() {
		this.preDoAction();
		System.out.println("this is the doAction");
		this.postDoAction();
	}

	public void preDoAction(){
		System.out.println("this is the method before doAction.//身份验证,权限管理。。");
	}
	
	public void postDoAction(){
		System.out.println("this is the method after doAction.//记录,打印日志。。");
	}
}

package com.peacentury.proxy;

public class Client {
	public static void main(String[] args) {
		Proxy proxy = new Proxy();
		proxy.doAction();
	}
}

外观模式:为子系统中的一组接口提供统一的入口,方便调用。其类图如下:


 

示例代码如下:

package com.peacentury.facade;

public class Cpu {
	public void startUp(){
		System.out.println("the cpu startup.");
	}
	
	public void shutDown(){
		System.out.println("the cpu shutdown.");
	}
}

package com.peacentury.facade;

public class Memory {
	public void startUp(){
		System.out.println("the memory startup.");
	}
	
	public void shutDown(){
		System.out.println("the memory shutdown.");
	}
}

package com.peacentury.facade;

public class Disk {
	public void startUp(){
		System.out.println("the disk startup.");
	}
	
	public void shutDown(){
		System.out.println("the disk shutdown.");
	}
}

package com.peacentury.facade;

public class Computer {
	private Cpu cpu;
	private Memory memory;
	private Disk disk;
	
	public Computer(){
		cpu = new Cpu();
		memory = new Memory();
		disk = new Disk();
	}
	
	public void startUp(){
		System.out.println("the computer is starting...");
		cpu.startUp();
		memory.startUp();
		disk.startUp();
		System.out.println("the start finished.");
	}
	
	public void shutDown(){
		System.out.println("the computer is closing...");
		cpu.shutDown();
		memory.shutDown();
		disk.shutDown();
		System.out.println("the close finished.");
	}
}

package com.peacentury.facade;

public class Client {
	public static void main(String[] args) {
		Computer computer = new Computer();
		computer.startUp();
		computer.shutDown();
	}
}

总结:适配器模式将一个不符合客户要求的对象包装成符合要求的对象,有对象适配和接口适配两种,其中,在对象适配中,被适配类和适配类没有继承关系。装饰模式用于动态的添加对象的功能和行为,一般具体装饰器会继承抽象装饰器。外观模式和装饰模式在中文感觉上似乎有些联系,其实并没有什么联系,外观模式将一群对象集中起来以简化其接口,简化调用。

       个人觉得最相似的是装饰模式和代理模式,对装饰器模式来说,装饰者(Decorator)和被装饰者(Decoratee)都实现同一个 接口。对代理模式来说,代理类(Proxy)和真实的主题类(RealSubject)都实现同一个接口。此外,不论使用哪一个模式,都可以很容易地在真实对象方法的前面或者后面加上自定义的方法。但两者的差别也不少,装饰器模式关注于在一个对象上动态的添加方法,然而代理模式关注于控制对对象的访问。换句话说,用代理模式,代理类可以对它的客户隐藏一个对象的具体信息。因此,当使用代理模式的时候,我们常常在一个代理类中创建一个对象的实例。当我们使用装饰器模式的时候,通常的做法是将原始对象作为一个参数传给装饰者的构造器。也可用另外一句话来总结这些差别:使用代理模式,代理类和真实对象之间的的关系通常在编译时就已经确定了,而装饰者能够在运行时递归地被构造。   


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值