装饰模式:为对象增加额外的功能。
这么说来可能比较难以理解,举个例子:不同的工厂组装不同的手机,都需要安装CPU、主板、听筒、屏幕这几个部分!
A厂除了安装上述部分外,还可能需要安装摄像头;
B厂除了安装上述部分外,还可能需要安装距离传感器;
1、首先我们先建立一个组装手机的接口
/* * Copyright (c) 2017. Xiaomi.Co.Ltd All rights reserved */ package com.pt.decoration; /** * @description 生产手机的抽象接口 * @author panteng * @date 17-2-9. */ public interface ProducePhone { public void produce(); }
2、实现通用功能的一个类(被装饰者类)
/* * Copyright (c) 2017. Panteng.Co.Ltd All rights reserved */ package com.pt.decoration; /** * @description 通用工作 即被装饰者 * @author panteng * @date 17-2-9. */ public class GeneralWork implements ProducePhone { public void produce(){ System.out.print("CPU 主板 屏幕 听筒"); } }
3、装饰者(抽象类)
/* * Copyright (c) 2017. Xiaomi.Co.Ltd All rights reserved */ package com.pt.decoration; /** * @description 装饰者抽象类,其他装饰者都从此类继承 * @author panteng * @date 17-2-9. */ public abstract class ProduceDecoration implements ProducePhone { ProducePhone producer; public ProducePhone getProducer(){ return producer; } public void setProducer(ProducePhone producer){ this.producer = producer; } /** * 实现接口,调用通用功能 */ public void produce(){ producer.produce(); } }
4、装饰者类(同时也可以作为被装饰者)
/* * Copyright (c) 2017. Xiaomi.Co.Ltd All rights reserved */ package com.pt.decoration; /** * @description 真实装饰者 * @author panteng * @date 17-2-9. */ public class RealWork1 extends ProduceDecoration implements ProducePhone { public RealWork1(){ } public RealWork1(ProducePhone in_producer){ this.producer = in_producer; } @Override public void produce(){ super.produce(); System.out.print(" 摄像头"); } }
/* * Copyright (c) 2017. Xiaomi.Co.Ltd All rights reserved */ package com.pt.decoration; /** * @description 真实装饰者 * @author panteng * @date 17-2-9. */ public class RealWork2 extends ProduceDecoration implements ProducePhone { public RealWork2(){ } public RealWork2(ProducePhone in_producer){ this.producer = in_producer; } public void produce(){ super.produce(); System.out.print(" 距离传感器"); } }
5、调用方式
/* * Copyright (c) 2017. Xiaomi.Co.Ltd All rights reserved */ package com.pt.decoration; import org.junit.Test; /** * @description * @author panteng * @date 17-2-9. */ public class RealWorkTest { @Test public void produceTest(){ //使用方式1 GeneralWork generalWork = new GeneralWork(); ProducePhone produce1 = new RealWork1(generalWork); produce1.produce(); System.out.println(); ProducePhone produce2 = new RealWork2(produce1); produce2.produce(); System.out.println(); //使用方式2 produce1 = new RealWork2(produce1);//为1赋予新的功能 produce1.produce(); } }
装饰模式与继承的区别
装饰模式比继承更加灵活,如果是继承的话,可能需要多级继承,增加系统复杂性;
使用起来也更加方便,代码易读性比较好!