设计模式 | 装饰模式(decorator)

定义:

装饰模式是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。

结构:(书中图,侵删)

一个被装饰接口类:从具体类中抽象出来,拥有用于修饰的一个公共方法
若干被装饰具体类;继承于被装饰接口类
一个抽象装饰类:继承于被装饰接口类
若干具体装饰类:具体的装饰方法
 
装饰模式是为了扩展原有方法(即已经存在的方法)的功能 ,所以是为了给方法添加功能,而不是给类新增方法。(我一开始就这么误解了,导致整个看下来感觉怪怪的,后面才后知后觉的反应过来)。
直接在原类中增加违反了开放-封闭原则;使用继承都写在子类中没有那么灵活,且不好复用。

实例:

模拟宠物去做造型
美容院提供:洗澡、染色、修剪、穿衣服等服务。
 
被装饰接口类:宠物类
package designpattern.decorator;

public abstract class Pet {
    String name;

    Pet() {// 因为子类要使用其他参数的构造函数,需要调用父类的默认(无参)构造方法
    }

    Pet(String name) {
        this.name = name;
    }

    Pet(String name, int test) {
        this.name = name;
    }

    public abstract void beautify();
}

若干被装饰具体类:猫、狗

package designpattern.decorator;

public class Cat extends Pet {
    public Cat(String name) {
        this.name = name;
    }

    @Override
    public void beautify() {
        System.out.println(name + ":猫正在打扮~");
    }

}
package designpattern.decorator;

public class Dog extends Pet {
    public Dog(String name) {
        this.name = name;
    }

    @Override
    public void beautify() {
        System.out.println(name + ":狗正在打扮~");
    }

}

抽象装饰类:美容类

package designpattern.decorator;

public class Beautify extends Pet {
    Pet pet;

    Beautify(Pet pet) {
        this.pet = pet;
    }

    @Override
    public void beautify() {
        System.out.println("装饰父类beautify()");
        pet.beautify();
    }

}
若干具体装饰类:洗澡、染色、修剪、穿衣服
package designpattern.decorator;

public class Shower extends Beautify{

    Shower(Pet pet) {
        super(pet);
    }

    @Override
    public void beautify() {
        super.beautify();
        System.out.println("洗澡");
    }

}
package designpattern.decorator;

public class Dye extends Beautify {

    Dye(Pet pet) {
        super(pet);
    }

    @Override
    public void beautify() {
        super.beautify();
        System.out.println("染色");
    }
}
package designpattern.decorator;

public class Trim extends Beautify {

    Trim(Pet pet) {
        super(pet);
    }

    @Override
    public void beautify() {
        super.beautify();
        System.out.println("修剪");
    }
}
package designpattern.decorator;

public class Dress extends Beautify {

    Dress(Pet pet) {
        super(pet);
    }

    @Override
    public void beautify() {
        super.beautify();
        System.out.println("穿衣服");
    }
}

客户端调用:

package designpattern.decorator;

public class Client {
    public static void main(String[] args) {
        Cat cat = new Cat("小喵");
        // 直接调用
        cat.beautify();
        System.out.println("----------------");
        // 装饰后调用
        Shower showerCat = new Shower(cat);
        Dye dyeCat = new Dye(showerCat);
        Trim trimCat = new Trim(dyeCat);
        trimCat.beautify();
System.
out.println("==================");
Dog dog
= new Dog("小汪"); // 直接调用 dog.beautify(); System.out.println("----------------"); // 装饰后调用 Shower showerDog = new Shower(dog); Dress dressDog = new Dress(showerDog); dressDog.beautify(); } }

结果:

小喵:猫正在打扮~
----------------
装饰父类beautify()
装饰父类beautify()
装饰父类beautify()
小喵:猫正在打扮~
洗澡
染色
修剪
==================
小汪:狗正在打扮~
----------------
装饰父类beautify()
装饰父类beautify()
小汪:狗正在打扮~
洗澡
穿衣服
从输出能看出,有几层装饰,就会调用几次装饰父类的 beautify()方法。
以上例的狗小汪为例:
通过最底层的穿衣服Dress的方法:
进入方法中
通过super.beautify()方法,调用父类的方法:
再通过多态调用具体的父类,此处为洗澡Shower的方法,重复上述步骤直至最顶层狗Dog类的beautify()方法:
再回来执行方法中的其余语句,有一点类似于递归的感觉。

总结:

装饰模式虽然能灵活复用,且能够规定各个装饰办法的执行顺序。
但是一旦装饰类变多后,客户端的调用会变得相当繁琐。
 
 
 
 
 
 

转载于:https://www.cnblogs.com/imoqian/p/10330427.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值