设计模式——装饰器模式和代理模式

装饰器设计模式

装饰器设计模式,其实就是对一个类进行的装饰。 以完成在不进行继承的基础上,拓展一个类的功能。需要让每一个装饰者类实现相同的接口,被装饰的类也实现相同的接口。在IO流部分,对装饰器模式的使用比较多的。
下面就是装饰器模式的应用:

BufferedInputStream bufferedInputStream=new BufferedInputStream(new FileInputStream(new File("file\\装饰器模式")));
public class DecoratorTest {
    public static void main(String[] args) {
        Person p=new Person();
        Decorator decorator=new ShoesDecorator(new TrousersDecorator(new TshirtDecorator(p)));
        decorator.show();
    }
}
class Person implements Decorator{
    @Override
    public void show() {
        System.out.println("一个人站在这");
    }
}
interface Decorator{
    void show();
}
abstract class AbstractDecorator implements Decorator{
    protected Decorator decorator;
    public AbstractDecorator(Decorator decorator){
        this.decorator=decorator;
    }
}

class ShoesDecorator extends AbstractDecorator{
    public ShoesDecorator(Decorator decorator){
        super(decorator);
    }
    @Override
    public void show() {
        decorator.show();
        System.out.println("穿了一双鞋");
    }
}
class TshirtDecorator extends AbstractDecorator{
    public TshirtDecorator(Decorator decorator) {
        super(decorator);
    }

    @Override
    public void show() {
        decorator.show();
        System.out.println("穿了T恤衫");
    }

}
class TrousersDecorator extends AbstractDecorator {
    public TrousersDecorator(Decorator decorator) {
        super(decorator);
    }
    @Override
    public void show() {
        this.decorator.show();
        System.out.println("穿了一条裤子");
    }
}

代理模式

有些时候,需要自己去处理的一些逻辑、任务,此时由于种种原因,导致自己无法处理,委托给其他人去处理。这种模式,就是一个代理模式。找到一个代理,帮助我完成某些任务。
案例:代购。小明、小美、小娟,知道了老王要出国玩,想让老王帮忙代购苹果电脑。
在代理模式中,代理者与被代理者,应该具有相同的功能。

静态代理

public class StaticProxyTest {
    public static void main(String[] args) {
        // 1. 实例化三个购买方
        Buyer xiaoming = new Buyer("小明");
        Buyer xiaomei = new Buyer("小美");
        Buyer xiaojuan = new Buyer("小娟");

        // 2. 实例化一个代购方
        Proxy proxy = new Proxy("老王", xiaoming, xiaomei, xiaojuan);
        //购买
        proxy.buyMac("MacBook Pro");
    }
}
interface BuyMac{
    void buyMac(String type);
}
//实际购买者
class Buyer implements BuyMac{
    private String name;
    public Buyer(String name){
        this.name=name;
    }

    public String getName() {
        return name;
    }

    @Override
    public void buyMac(String type) {
        System.out.println(name+"买了一台"+type);
    }
}
//代购
class Proxy implements BuyMac{
    private String name;
    private Buyer[] buyers;
    public Proxy(String name,Buyer ... byers){
        this.name=name;
        this.buyers=byers;
    }
    @Override
    public void buyMac(String type) {
        System.out.println("代购"+this.name+"走进了店里");
        for (Buyer buyer : buyers) {
            System.out.println(buyer.getName()+"买了一台"+type);
        }
        System.out.println("代购"+this.name+"走出了店");
    }
}

动态代理

为了解决静态代理中的复杂的需求(每一个被代理者需求都不一样)
案例: 小明、小美、小娟三个人都需要购买苹果设备,找到了一个代购————老王。但是他们三个人的需求是不一样的: 小明需要买电脑、小美需要买手机、小娟需要买pad。

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @Author 昊
 * @Create 2020/5/10 9:47
 * @Description
 */
public class DynamicProxyTest {
    public static void main(String[] args) {
        // 小明需要购买电脑
        MacBuyer xiaoming = new MacBuyer("xiaoming");
        // 小美需要购买手机
        PhoneBuyer xiaomei = new PhoneBuyer("xiaomei");
        // 小娟需要购买pad
        PadBuyer xiaojuan = new PadBuyer("xiaojuan");

        // 实例化动态代理类对象
        DynamicProxy proxy = new DynamicProxy();
        //getBuyer得到的是Object对象,要强转成Buy
        Buy buyer = (Buy) (proxy.getBuyer(xiaoming));
        buyer.buy();
        Buy buyer1 = (Buy) (proxy.getBuyer(xiaomei));
        buyer1.buy();
        Buy buyer2 = (Buy) (proxy.getBuyer(xiaojuan));
        buyer2.buy();

    }
}
//实际购买者
abstract class Buyer{
    protected String name;
}
//购买行为
interface Buy{
    void buy();
}
class MacBuyer extends Buyer implements Buy{
    public MacBuyer(String name){
        this.name=name;
    }
    @Override
    public void buy() {
        System.out.println(this.name+"购买了一个MacBook Pro");
    }
}
class PhoneBuyer extends Buyer implements Buy{
   public PhoneBuyer(String name){
       this.name=name;
   }
    @Override
    public void buy() {
        System.out.println(this.name+"购买了 iphone 12 ");
    }
}
class PadBuyer extends Buyer implements Buy {
    public PadBuyer(String name) {
        this.name = name;
    }

    @Override
    public void buy() {
        System.out.println(this.name + "得到了一个 iPad Pro");
    }
}


//代购,必须实现InvocationHandler接口,并重写invoke方法
class DynamicProxy implements InvocationHandler{
    //实际购买者
    private Object buyer;
    public Object getBuyer(Object buyer){
        this.buyer=buyer;
        /*
         * Proxy: java.lang.reflect.Proxy类,专门用来表示动态代理的类
         * Proxy.newProxyInstance: 获取一个动态代理对象
         *
         * 参数1: ClassLoader: 指定产生代理类的类加载器,需要使用它来指定目标类的类加载器。
         * 参数2: 指定目标类实现的接口
         * 参数3: 指定了InvocationHandler实现类
         * 返回一个Object对象,所以购买者的类型是Object而不是Buyer
         */
        return Proxy.newProxyInstance(buyer.getClass().getClassLoader(),buyer.getClass().getInterfaces(),this);
    }

    /**
     *
     * @param o  购买者
     * @param method 代理的行为==>购买行为,即购买方法
     * @param objects  行为的参数
     * @return    执行结果
     * @throws Throwable  抛出的异常
     */
    @Override
    public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
        System.out.println("代购走进店里");
        return method.invoke(this.buyer,objects);
    }
}
上一篇:vue-property-decorator用法


下一篇:《设计模式之禅》之装饰模式