设计模式(一):装饰器模式和策略模式

装饰器模式

简介

装饰器模式是基于对象组合的方式(CRP 合成复用原则)来动态的给对象添加所需要的功能。
装饰器会持有一个构件对象的实例。
装饰器模式

示例

// 对应于图片中Componet
public interface Coat {
    public void show();
}

// 对应于ConcreteComponent
public class CoatImpl implements Coat {
    @Override public void show() {
        System.out.println("原始show方法");
    }
}

//对应于ConcreteDecorator
public class TDress implements Coat {
	//持有实现接口对象的引用
    public Coat coat;
    public TDress(Coat coat) {
        super();
        this.coat = coat;
    }

    @Override public void show() {
        System.out.println("TDress 装饰器前");
        coat.show();
        System.out.println("TDress 装饰器后");
    }
}

//对应于ConcreteDecorator
public class Tshirt implements Coat {
    public Coat coat;
    public Tshirt(Coat coat) {
        super();
        this.coat = coat;
    }

    @Override public void show() {
        System.out.println("Tshirt 装饰器前");
        coat.show();
        System.out.println("Tshirt 装饰器后");
    }
}

//客户端测试类
public class Test {
    public static void main(String[] args) {
    	//客户端应当声明Component对象
        Coat coat = new CoatImpl();
        Coat Tshirt = new Tshirt(coat);
        Tshirt.show();

        Coat TDress = new TDress(coat);
        TDress.show();
    }
}

扩展及应用

装饰器模式意味着在不改变接口的情况下,增强对象的功能。但在实际应用中,往往需要添加新的公开方法,即“半透明”式装饰器。即允许装饰器改变接口,增加新方法。此时客户端使用的是具体的ConcreteDecorator对象。
java中的典型应用举例:
FilterInputStream的类结构图
InputStream代表Component对象。
FileInputStream代表ConcreteComponent对象。
FilterInputStream代表Decorator对象,并持有InputStream的对象实例的引用。
BufferedInputStream、DataInputStream等代表ConcreteDecorator对象。

 String pathname = "home/upsmart/input.txt"; 
 File filename = new File(pathname);
 InputStreamReader reader = new InputStreamReader( new FileInputStream(filename));
 BufferedReader br = new BufferedReader(reader);
public abstract class InputStream implements Closeable {
	......
}

public class FileInputStream extends InputStream
{
	......
}
	
public class FilterInputStream extends InputStream {
    protected volatile InputStream in;
    protected FilterInputStream(InputStream in) {
        this.in = in;
        ......
}

策略模式

简介

是对算法的封装,把使用算法的责任和算法本身分割开来,委托给不同的对象管理。其可用于多重条件的判断。但其缺点也很明显,所有策略类都需要对外暴露。
策略模式

示例

// context类
public class Context {
    private Strategy strategy;

    public Context(Strategy strategy) {
        super();
        this.strategy = strategy;
    }

    public Strategy getStrategy() {
        return strategy;
    }

    public void setStrategy(Strategy strategy) {
        this.strategy = strategy;
    }

    public int calculate(int a, int b) {
        return strategy.calculate(a, b);
    }
}

//Strategy接口
public interface Strategy {
    public int calculate(int a, int b);
}
//具体策略实现类
public class AddStrategy implements Strategy {
    @Override public int calculate(int a, int b) {
        return a + b;
    }
}
//具体策略实现类
public class SubstractStrategy implements Strategy {
    @Override public int calculate(int a, int b) {
        return a - b;
    }
}
// 客户端测试类,客户端需要知道所有的策略类
public class Test {
    public static void main(String[] args) {
        //加法
        Context context=new Context(new AddStrategy());
        System.out.println(context.calculate(10, 5));
        //减法
        Context context2=new Context(new SubstractStrategy());
        System.out.println(context2.calculate(3, 2));
    }
}

扩展及应用

Spring中的代理对象的创建
Spring中代理对象创建的策略模式
其中ProxyFactoryBean代表Context角色,通过依赖的方法来关联具体策略对象,通过调用策略对象的getProxy(ClassLoader classLoader)方法来完成操作。其根据条件选择JDK代理方式还是CGLIB方式。
其中AopProxy代表Strategy角色,Cglib2AopProxy和JdkDynamicAopProxy分别代表具体的策略模式。
AopProxyFactory、DefaultAopProxyFactory、ProxyCreatorSupport主要负责创建具体的策略对象。

猜你喜欢

转载自blog.csdn.net/qq_28376741/article/details/88892911