在了解装饰模式之前,我们先出这么一个需求,看测试一代码
/**
* 装饰模式:
* 现在有这样一个需求:你的老板要去约会,但是他不知道怎么搭配衣服,现在让你写一个搭配不同服饰的系统,
* 你怎么搞?看第一版代码,很有可能你会这么写:Test1
* 一。你的技术组长看了看代码,问你,功能是实现了,老板要是想穿其他衣服呢,你是不是还要改这个类,
* 如果改的话,是不是就得动 源代码,那就违背了:开放——封闭原则,写好的代码不要去动
* 二。怎么办,想一想
* 1.那就把 衣服类提出来,一种衣服一个类,想穿其他衣服,就增加一个类,遵守开放——封闭原则
* 2.于是你的第二版代码出来了:Test2
* */
public class Test1 {
// 这个人类 :就是你的老板
class Person{
private String name;
public Person(String name) {
this.name=name;
}
// 下面是你给老板提供的衣服,让老板选择
public void WearTshirts() {
System.out.println("半袖");
}
public void WearNiuKuZi() {
System.out.println("牛仔褲");
}
public void WearQiuXie() {
System.out.println("球鞋");
}
public void WearSuit() {
System.out.println("西裝");
}
public void WearPiXie() {
System.out.println("皮鞋");
}
public void show() {
System.out.println("這個"+name+"帅哥穿了:");
}
}
// 你的老板要穿衣服了(客户端)
public static void main(String[] args) {
Person person = new Test1().new Person("程杰"); // 程杰 大话设计模式 作者
// 老板开始选择衣搭配
person.show();
person.WearNiuKuZi();
person.WearTshirts();
person.WearQiuXie();
}
}
這時候 你的第二版代碼出來了
person(你的老闆)
/**
* 人类:你的老板
*/
public class Person {
private String name;
public Person() {
};
public Person(String name) {
this.name = name;
}
public void show() {
System.out.println("这个" + name + "大帅哥穿了:");
}
}
衣服抽象類
/**
* 将衣服类抽象出来,有很多衣服的实现,想穿啥,就实现啥
*/
abstract class Yifu {
public abstract void show();
}
具體衣服類的實現
/**
* 各种衣服的实现
* 半袖
* */
public class Ts extends Yifu{
@Override
public void show() {
System.out.println("半袖");
}
}
/**
* 各种衣服的实现
* 球鞋
* */
public class QiuXie extends Yifu{
@Override
public void show() {
System.out.println("球鞋");
}
}
客戶端
/**
* 客户端:你的老板要穿衣服了
* 一。这时候,你的技术组长又来了,看了看你的代码,是不是很慌
* 1.问你:这样写意味着什么,衣服一个一个穿,(一个一个的调用show方法),你让老板在大庭广众之下
* 一个一个穿,多丢人,是不是应该穿好了再出来(一次性穿完)。
* 2.怎么办,我们的装饰模式立功的时候到了。看Test3,对了,看Test3之前先理解什么是装饰模式:看
* 下面
* */
public class Test2 {
public static void main(String[] args) {
Person person = new Person("程杰");
Ts ts = new Ts();
QiuXie qiuXie = new QiuXie();
person.show();
ts.show();
qiuXie.show();
}
}
來來,下面是裝飾模式的具體介紹
什麽是裝飾模式:
動態的 給一些對象添加一些額外的職責,就增加功能惡言, 裝飾模式比生成子類更加靈活。
看不懂沒關係,下面有代碼
Component
/**
* 定义一个对象接口,可以给这些对象动态的添加职责,
*/
abstract class Component {
public abstract void Operation();
}
ConcreteComponent
/**
* 定义了一个具体的对象,也可以给这个对象添加一些职责
* */
public class ConcreCompnent extends Component{
@Override
public void Operation() {
System.out.println("具体对象的操作");
}
}
Decorator 最重要的一部分
/**
* 装饰抽象类,她继承了Component,从外类来扩展Component类的功能,但对于Component来说,是无需知道 Decorator的存在的
*/
abstract class Decorator extends Component {
public void setComponent(Component component) {
this.component = component;
}
protected Component component;
// 设置Component
public void Component(Component component) {
this.component = component;
}
// 重写Operation 执行的是Component的Operation();
public void Operation(){
if (component!=null) {
component.Operation();
}
}
}
ConcreteDercratorA
/**
* ConcreteDercrator就是具体的装饰对象,起到给Component添加职责的功能
* */
public class ConcreteDercratorA extends Decorator{
private String addedState;//
public void Operation() {
super.Operation();
addedState="new State";
System.out.println("具体装饰对象A的操作");
}
}
ConcreteDercratorB
***
* 首先运行原 Compenent 的Operation();在执行本类的功能,如:Addedbehavior(),相当于对原Component
* 进行了装饰
* 从客户端代码可以看出:装饰模式是利用 SetComPonent 来对对象进行包装的,这样每个装饰对象的实现就想和
* 如何使用这个对象分离开了,每个装饰对象 只关心自己的功能,不需要关心如何被添加到对象链当中。
*
* */
public class ConcreteDercratorB extends Decorator{
public void Operation() {
super.Operation();
Addedbehavior();
System.out.println("具体装饰对象B的操作");
}
// 本类独有的方法
private void Addedbehavior() {
}
public static void main(String[] args) {
// 客户端代码
ConcreCompnent compnent=new ConcreCompnent();
ConcreteDercratorA concreteDercratorA=new ConcreteDercratorA();
ConcreteDercratorB concreteDercratorB=new ConcreteDercratorB();
concreteDercratorA.setComponent(compnent);
concreteDercratorB.setComponent(concreteDercratorA);
concreteDercratorB.Operation();
}
}
上面就是 裝飾模式的代碼部分,我知道,你有疑惑,具體咋用呢,看下面的代碼,針對我們這個需求
1.人類,可以用上面的Person 類
2.Decorator(你的服飾類)
/**
* 服饰类:也就是 装饰类
* */
public class Finery extends Person{
protected Person person;
// 打扮:
public void setPerson(Person person) {
this.person = person;
}
public void show() {
if (person!=null) {
person.show();
}
}
}
3。具體服飾類
/**
*
* */
public class Tshirts extends Finery{
public void show() {
super.show();
System.out.println("半袖");
}
}
public class DAtouPiXie extends Finery{
public void show() {
super.show();
System.out.println("大头皮鞋");
}
}
4.客戶端,你的老闆要穿衣服啦
/**
* 装饰模式(Decorator):动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式
* 比生成子类更为灵活
* Person 类用之前的
* 看到没有,这就是装饰模式,看了你的代码,老板很有面子
* 于是,你和技术组长分析了分析 装饰模式
* 1.我们就那这个需求来说吧
* 装饰模式是为了:为已有的功能动态的添加更多功能的一种方式。
* 老板去约会,最重要的是啥,是人得去啊(核心业务),穿什么衣服是装饰老板(装饰类的核心职责),
* 所以,把核心业务放一个类,要装饰的功能放在单独的类中,并让这个类包装她所要装饰对象,
* 因此,当需要执行特殊行为时,客户代码就可以在运行时根据需要,有选择地,按顺序地使用装饰功能
* 包装对象了。(应用场景:加密数据,过滤词汇,時間格式,不同的請求代理等等)
* */
public class Test3 {
public static void main(String[] args) {
Person person =new Person("程杰");
Tshirts tshirts =new Tshirts();
DAtouPiXie dAtouPiXie = new DAtouPiXie();
tshirts.setPerson(person);
dAtouPiXie.setPerson(tshirts);
dAtouPiXie.show();
}
}