装饰模式
定义:动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更灵活
需求: 现在有一个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网页,里面有很多图片,但是还是可以很快的打开它,此时你可以看到文字,但是图片却是一张一张下载后才能看到,未打开的图框,就是通过虚拟代理替代了真实的图片
安全代理
用来控制真实对象访问时的权限
一般用于对象应该有不同的访问权限的时候
智能指引
当调用真实的对象时,代理处理另外一些事
例如计算真实对象的引用次数