设计模式-结构型模式
1.代理模式
2.装饰者模式
3.适配器模式
代理模式 :
在设计模式1中已解释
装饰者模式
概述:动态的给一个对象添加一些额外的职责,就增加功能来说,装饰者模式比生成子类更为灵活
适用:
1.动态,透明的给单个对象添加职责
2.处理某些可以撤销的职责
参与者:
component:定义一个对象接口,可以给这些对象动态的添加职责
concreteComponent:定义一个对象,可以给这个对象添加一些职责
decorator:维持一个指向component对象的指针,定义一个与component接口一致的接口,抽象实现类
ConcreteDecorator:向组件添加职责
创建一个煎饼果子(产品接口)(component)
public abstract class Battercake {
protected abstract String getMsg();
protected abstract Integer getPrice();
}
做一个基本的煎饼果子(产品基本实现)(ConcreteComponent)
public class BaseBattercake extends Battercake{
@Override
protected String getMsg() {
return "煎饼";
}
@Override
protected Integer getPrice() {
return 5;
}
}
创建拓展套餐的抽象修饰者(产品拓展,实现产品接口)(Decorator)
public class BattercakeDecorator extends Battercake {
//静态代理 委派
private Battercake battercake;
public BattercakeDecorator(Battercake battercake) {
this.battercake = battercake;
}
@Override
protected String getMsg() {
return battercake.getMsg();
}
@Override
protected Integer getPrice() {
return battercake.getPrice();
}
}
创建拓展套餐(实现拓展套餐的抽象修饰者)(ConcreteDecorator)
public class EggDecorator extends BattercakeDecorator {
public EggDecorator(Battercake battercake) {
//在基本套餐中增加功能
super(battercake);
}
@Override
protected String getMsg() {
return super.getMsg() + "add an egg";
}
@Override
protected Integer getPrice() {
return super.getPrice() + 1;
}
}
客户端实现
public class BattercakeTest {
public static void main(String[] args) {
//基本版
Battercake battercake = new BaseBattercake();
//加蛋
battercake = new EggDecorator(battercake);
//再加
battercake = new EggDecorator(battercake);
//跟静态代理区别在于静态代理不是is-a关系 晶体代理会做功能增强,使同一个职责变得不一样
//装饰者模式更多考虑扩展
}
}
装饰者和代理模式的区别
代理模式:是代理对象在自己构造方法里new一个被代理的对象,不是调用者传入的
装饰者模式:是使用者从外部传入对象,并对这个对象进行修饰
代理模式强调的是对对象的访问控制,装饰者模式强调的是给对象加强功能
适配器模式
概述:把原来不能用的变成能用的,像笔记本电脑的转换器
将一个类的接口转换成客户希望的另外一个接口,adapter模式使得原本由于接口不兼容而不能在一起工作的那些类可以一起工作
适用性:
1.你想使用一个已经存在的类,而他的接口不符合你的需求
2.想创建一个可以复用的类,该类可以与其他接口不兼容的类协同工作
3.需要一个统一的输出接口,但是输入类型不可预知
参与者
Target:定义client使用的与特定领域相关的接口,(客户所需要的接口可以是抽象类或者接口)
Client与符合Target接口的对象协同
Adaptee定义一个已经存在的接口,这个接口需要适配 (被适配的角色,定义了一个已经存在的接口,这个接口需要适配,包装好了客户希望的业务方法)
Adapter对Adaptee接口与Target接口进行适配 (作为转换器,对target,Adaptee进行适配)
/**
* 220V 电压对象被适配的对象
*/
public class AC220 {
public int output220V(){
return 220;
}
}
/**
* 5V 电压输出接口,用户需要的接口
*/
public interface DC5 {
int output5V();
}
适配器,转换器
public class PowerAdapter implements DC5 {
private AC220 ac220;
public PowerAdapter(AC220 ac220) {
this.ac220 = ac220;
}
@Override
public int output5V() {
if (this.ac220 != null) {
return (ac220.output220V() / 44);
}
return 0;
}
}
client
public static void main(String[] args) {
PowerAdapter powerAdapter = new PowerAdapter(new AC220());
System.out.println(powerAdapter.output5V());
}