设计模式之--(3)装饰模式|代理模式

装饰模式

定义:动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更灵活

需求: 现在有一个NewPerson类,有一个展示衣服的功能,现在需要给这个NewPerson新增几件衣服

代码设计

首先有一个NewPerson类,有一个名字,有一个展示的show()方法

public class NewPerson {

    private String name;

    public NewPerson() {
    }

    public NewPerson(String name) {
        this.name = name;
    }

    public void show() {
        System.out.println("三角裤衩装扮的" + name);
    }

}

要给NewPerson添加新衣服,所以有一个服饰类

public class Finery extends NewPerson {

    private NewPerson np = new NewPerson();

    public NewPerson decorate(NewPerson np) {
        this.np = np;
        return this;
    }

    public void show() {
        if (np != null) {
            np.show();
        }
    }

}

最后写出各种各样的衣服

public class BigTrouser extends Finery {

    public void show() {
        System.out.println("跨库");
        super.show();
    }
}
public class Tshirts extends Finery {

    public void show() {
        System.out.println("大T恤");
        super.show();
    }

}

客户端测试代码

public static void main(String[] args) {

        NewPerson np = new NewPerson("小菜");

        Tshirts ts = new Tshirts();
        BigTrouser bt = new BigTrouser();

        // 注意!!! 如果有 bt.decorate(bt); 会导致死循环
        // 实际执行顺序从下往上
        ts.decorate(np);
        bt.decorate(ts);
        bt.show();

        System.out.println();

        // 第二种写法
        new BigTrouser().decorate(new Tshirts().decorate(new NewPerson("小菜"))).show();

    }

总结

在此就是给NewPerson类新增功能
用法:
首先新建Finery类继承NewPerson
并在类内新建NewPerson对象及decorate()方法用于循环注入对象
重写show()核心职责的方法

然后新建 新功能的类BigTrouser继承Finery
并重写show()方法,在做完新增功能 前/后 调用super.show()

最后在下面main方法内运用装饰模式,为NewPerson的核心职责show()新增功能

代理模式

定义: 为其他对象提供一种代理以控制对这个对象的访问

模拟情景:追求者由于害羞让人代他给女孩送礼物

开始编码

由于追求者和代他的人有同样的操作,所以先定义送礼接口:

public interface GiveGift {

    void giveDolls();

    void giveFlowers();

    void giveChocolate();

}

定义一个心仪的女孩

public class SchoolGirl {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

追求者有一个心仪的女孩,并要给她送礼物:

public class Pursuit implements GiveGift {

    private SchoolGirl sg;

    public Pursuit(SchoolGirl sg) {
        this.sg = sg;
    }

    @Override
    public void giveDolls() {
        System.out.println(sg.getName() + "送你洋娃娃");
    }

    @Override
    public void giveFlowers() {
        System.out.println(sg.getName() + "送你花花");
    }

    @Override
    public void giveChocolate() {
        System.out.println(sg.getName() + "送你巧克力");
    }

}

但是这个人很害羞,所以他找了一个人代理自己送礼物:

public class Proxy implements GiveGift {

    private Pursuit ps;

    public Proxy(SchoolGirl sg) {
        ps = new Pursuit(sg);
    }

    @Override
    public void giveDolls() {
        ps.giveDolls();
    }

    @Override
    public void giveFlowers() {
        ps.giveFlowers();
    }

    @Override
    public void giveChocolate() {
        ps.giveChocolate();
    }

}

模拟送礼物啦

 public static void main(String[] args) {

        SchoolGirl sg = new SchoolGirl();
        sg.setName("大美女");

        Proxy proxy = new Proxy(sg);

        proxy.giveChocolate();
        proxy.giveDolls();
        proxy.giveFlowers();

    }

完事

最后看起来是代理送的礼物,实际上送礼物的人是追求者

应用

代理模式其实就是在访问对象时引入一定程度的间接性,因为这种间接性,可以附加多种用途

远程代理

为一个对象在不同的地址空间提供局部代理,这样可以隐藏一个对象存在于不同地址空间的事实

例如: WebService在.NET中的应用

虚拟代理

是根据需要创建开销很大的对象,通过它来存放实例化需要很长时间的真实对象,可以达到性能优化的目的

例如: 打开一个很大的html网页,里面有很多图片,但是还是可以很快的打开它,此时你可以看到文字,但是图片却是一张一张下载后才能看到,未打开的图框,就是通过虚拟代理替代了真实的图片

安全代理

用来控制真实对象访问时的权限
一般用于对象应该有不同的访问权限的时候

智能指引

当调用真实的对象时,代理处理另外一些事
例如计算真实对象的引用次数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值