接下来用一个女屌丝变白富美的案例,来描述装饰模式。
一、女孩接口
首先,无论是女屌丝,还是白女孩、富女孩、美女孩,都是女孩。
所以定义女孩接口IGirl如下,其中show方法,就是女孩来展现自己现在的状态......
public interface IGirl { public void show(); }
二、女屌丝登场
女屌丝:BaseGirl。意思就是最基础、一无所有的女孩(女屌丝)。
show方法实现了接口,女屌丝目前一无所有,只能说:我是女孩
public class BaseGirl implements IGirl { public BaseGirl() { // TODO Auto-generated constructor stub } @Override public void show() { // TODO Auto-generated method stub System.out.println("我是女孩"); } }
三、装饰类RichGirl:变富
女孩虽然出身贫困,但是有一颗难得的上进心,她工作努力、团结同事,终于在某公司当上了个小领导,
从此迈入了小康生活。
此时,show方法中,女孩骄傲地说:我富....
public class RichGirl implements IGirl { IGirl girl; public RichGirl(IGirl girl) { this.girl = girl; } @Override public void show() { //基本功能 girl.show(); //添加装饰 System.out.println("我富"); } }
四、装饰类WhiteGirl:变白
女孩自从变有钱后,开始慢慢随着主流开始化妆。
为了让自己皮肤变白,女孩买了好多化妆品。
此时,show方法中,女孩高兴地说:我白....
public class WhiteGirl implements IGirl { IGirl girl; public WhiteGirl(IGirl girl) { this.girl=girl; } @Override public void show() { //基本功能 girl.show(); //添加装饰 System.out.println("我白"); } }
五、装饰类BeautifulGirl:变美
女孩现在是又白又富,高傲气质也自然而然的流露出来。
此时的show方法,女孩激动的说:我美...
此时,一个女屌丝不见了,一个白富美诞生了...故事也结束了...
public class BeautifulGirl implements IGirl { IGirl girl; public BeautifulGirl(IGirl girl) { this.girl = girl; } @Override public void show() { //基本功能 girl.show(); //添加装饰 System.out.println("我美"); } }
六、运行
流程很简单,首先创建一个朴素女孩(gril对象),她此时show,只会说:我是一个女孩
经过三个装饰类(白、富、美)依次装饰,此时的女孩(gril对象),再次show的时候,已经是:我是一个女孩,我白,我富,我美
public class Main { public static void main(String[] args) { // TODO Auto-generated method stub // 创建出一个朴素的女孩 IGirl girl = new BaseGirl(); girl.show(); System.out.println(" ----------------------------------- "); // 女孩变白了 girl = new WhiteGirl(girl); girl.show(); System.out.println(" ----------------------------------- "); // 女孩变有钱了 girl = new RichGirl(girl); girl.show(); System.out.println(" ----------------------------------- "); // 女孩变漂亮了 girl = new BeautifulGirl(girl); girl.show(); } }
七、总结
有时候,你说人会变的,其实人真的变了。
每一次被装饰后得到的girl,已经不是以前的girl了。
变白、换了一个人
变富、换了一个人
变美、换了一个人
此时,我们也发现,每装饰一次,都是产生一个新的对象。
此模式非常类似于我们的字符串,A字符串:abc,如果在A前面装饰上123,那么产生的新字符串就是123abc,而老的abc仍然在内存中等待gc回收。
因此这种设计模式缺点:大量创建对象,大量产生无用对象。