欢乐狗 发表于 2024-12-11 17:06:08

装饰器模式

引言

           在一样寻常生存中,我们会碰到一种情景,买了新手机,给手机买个手机壳,装饰一下,手机壳不会改变手机原有功能,也不会影响到手机的工作,这种通过动态装饰扩展手机功能(保护功能、美观功能)的思想就是装饰模式的核心思想。
1.概念

        装饰模式(Decorator Pattern):动态地给一个对象增加一些额外的职责,就增加对象功能来说装饰模式比天生子类实现更为灵活。装饰模式是一种对象布局型模式。
           明白:装饰模式是一种用于替代继承的技能,它通过一种无须定义子类的方式来给对象动态增加职责,利用对象之间的关联关系取代类之间的继承关系。在装饰模式中引入了装饰类,在装饰类中既可以调用待装饰的原有类的方法,还可以增加新的方法,以扩充原有类的功能。
2.模式布局

https://i-blog.csdnimg.cn/direct/4cc630749d3f484bb1eb83a5cd0ac7df.png
3.模式分析

        Component:抽象构件,具体构件和抽象装饰类的共同父类,声明白在具体构件中实现的业务方法,它的引入可以使客户端以同等的方式处置惩罚未被装饰的对象以及装饰之后的对象,实现客户端的透明操纵。
        ConcreteComponent:具体构件,抽象构件类的子类,用于定义具体的构件对象,实现了在抽象构件中声明的方法,装饰器可以给它增加额外的职责(方法)。
        Decorator:抽象装饰类,抽象构件类的子类,用于给具体构件增加职责,但是具体职责在其子类中实现。它维护一个指向抽象构件对象的引用,通过该引用可以调用装饰之前构件对象的方法,并通过其子类扩展该方法,以达到装饰的目标。核心代码如下:
    class Decorator implements Component{

        private Component component; //维持一个对抽象构件对象的引用

        public Decorator(Component component){

            this.component=component;//注入一个抽象构件类型的对象

        }

        public void operation(){

            component.operation();//调用原有业务方法

        }

    }         ConcreteDecorator:具体装饰类,抽象装饰类的子类,负责向构件添加新的职责。每一个具体装饰类都定义了一些新的行为,它可以调用在抽象装饰类中定义的方法,并可以增加新的方法用以扩充对象的行为。核心代码如下:
    class ConcreteDecorator extends Decorator{

        public ConcreteDecorator(Component component){

            super(component);

        }

        public void operation(){

            super.operation();//调用原有业务方法

            addedBehavior();//调用新增业务方法

        }

        //新增业务方法

        public void addedBehavior(){



        }

    } 4.具体实例分析

https://i-blog.csdnimg.cn/direct/a02e4687bf1d4c8f8a6e2afe6f6671d2.png
        PhoneComponent:抽象构件类,表示手机构件,包含手机的基本功能利用手机方法play()。实例代码如下:
//抽象构件类

public abstract class PhoneComponent {

    public abstract void play();

}         Huawei:具体构件类,表示华为手机,继承PhoneComponent,实现了其中的抽象方法play()。实例代码如下:
//具体构件类

public class Huawei extends PhoneComponent {

    public void play(){

        System.out.println("玩华为手机");

    }

}         Xiaomi:具体构件类,表示小米手机,继承PhoneComponent,实现了其中的抽象方法play()。实例代码如下:
//具体构件类

public class Xiaomi extends PhoneComponent {

    public void play(){

        System.out.println("玩小米手机");

    }

}         PhoneDecorator:抽象装饰类,表示手机扩展的功能,继承PhoneComponent,其中包含PhoneComponent类型的引用。实例代码如下:
//抽象装饰类

public class PhoneDecorator extends PhoneComponent {

    private PhoneComponent phoneComponent;

    public PhoneDecorator(PhoneComponent phoneComponent){

        this.phoneComponent = phoneComponent;

    }

    public void play(){

        phoneComponent.play();

    }

}         ShellDecorator:具体装饰类,表示新增安装手机壳的功能,继承PhoneDecorator,并新增业务方法:装手机壳,通过重写play()方法来为手机对象新增装手机壳的功能。实例代码如下:
//具体装饰类

public class ShellDecorator extends PhoneDecorator{

    public ShellDecorator(PhoneComponent phoneComponent){

        super(phoneComponent);

    }

    public void play(){

        this.setPhoneShell();

        super.play();

    }

    //新增业务方法:装手机壳

    public void setPhoneShell(){

        System.out.println("给手机装上蓝色手机壳");

    }

}         RadiatorDecorator:具体装饰类,表示新增安装散热器的功能,继承PhoneDecorator,并新增业务方法:装散热器,通过重写play()方法来为手机对象新增装散热器的功能。实例代码如下:
//具体装饰类

public class RadiatorDecorator extends PhoneDecorator{

    public RadiatorDecorator(PhoneComponent phoneComponent){

        super(phoneComponent);

    }

    public void play(){

        this.setRadiator();

        super.play();

    }

    //新增业务方法:装散热器

    public void setRadiator(){

        System.out.println("给手机装上散热器");

    }

}         Client:客户端,具体代码如下:
public class Client {

    public static void main(String[] args) {

        PhoneComponent huaweiPhoneComponent = new Huawei();

        PhoneComponent xiaomiPhoneComponent = new Xiaomi();

        PhoneComponent shellWithPhone = new ShellDecorator(huaweiPhoneComponent);

        PhoneComponent radiatorWithPhone = new RadiatorDecorator(xiaomiPhoneComponent);

        shellWithPhone.play();

        radiatorWithPhone.play();

    }

}         运行代码,结果如下:
https://i-blog.csdnimg.cn/direct/a532e9a194ed4d7183282ec86c180e6d.png
5.优缺点

        主要优点如下:
        (1)对于扩展一个对象的功能,装饰模式比继承更加灵活性,不会导致类的个数急剧增加。
        (2)可以通过一种动态的方式来扩展一个对象的功能,通过配置文件可以在运行时选择不同的具体装饰类,从而实现不同的行为。
        (3)可以对一个对象举行多次装饰,通过利用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不偕行为的组合,得到功能更为强大的对象。
        (4)具体构件类与具体装饰类可以独立变化,用户可以根据必要增加新的具体构件类和具体装饰类,原有类库代码无须改变,符合“开闭原则”。
        主要缺点如下:
        (1)利用装饰模式举行体系筹划时将产生很多小对象,这些对象的区别在于它们之间相互连接的方式有所不同,而不是它们的类或者属性值有所不同,大量小对象的产生势必会占用更多的体系资源,在一定程序上影响程序的性能。
        (2)装饰模式提供了一种比继承更加灵活机动的解决方案,但同时也意味着比继承更加易于堕落,排错也很困难,对于多次装饰的对象,调试时探求错误可能必要逐级排查,较为繁琐。
6.适用环境

        (1)在不影响其他对象的环境下,以动态、透明的方式给单个对象添加职责。
        (2)当不能采取继承的方式对体系举行扩展或者采取继承不利于体系扩展和维护时可以利用装饰模式。不能采取继承的环境主要有两类:第一类是体系中存在大量独立的扩展,为支持每一种扩展或者扩展之间的组合将产生大量的子类,使得子类数目呈爆炸性增长;第二类是由于类已定义为不能被继承(如Java语言中的final类)。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 装饰器模式