服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Java教程 - 深入理解Java设计模式之装饰模式

深入理解Java设计模式之装饰模式

2022-07-11 09:03一指流砂~ Java教程

这篇文章主要介绍了JAVA设计模式之装饰模式的的相关资料,文中示例代码非常详细,供大家参考和学习,感兴趣的朋友可以了解下

一、前言

装饰模式实际上是一直提倡的组合代替继承的实践方式,个人认为要理解装饰者模式首先需要理解为什么需要组合代替继承,继承又是为什么让人深恶痛绝.

为什么建议使用组合代替继承?

面向对象的特性有继承与封装,但两者却又有一点矛盾,继承意味子类依赖了父类中的实现,一旦父类中改变实现则会对子类造成影响,这是打破了封装性的一种表现. 而组合就是巧用封装性来实现继承功能的代码复用.

二、什么是装饰模式

1.定义:

装饰器模式又名包装(wrapper)模式。装饰器模式以对客户端透明的方式拓展对象的功能,是继承关系的一种替代方案。

2.意图

动态地给一个对象添加一些额外的职责。就增加功能来说,decorator模式相比生成子类更为灵活。

3.别名

包装器wrapper

4.动机

有时我们希望给某个对象而不是整个类添加一些功能。例如,一个图形用户界面工具箱允许你对任意一个用户界面组件添加一些组件,例如边框,或是一些行为,例如窗口滚动等。

5.作用

在不修改原有的接口的情况下,让类表现的更好。

6.问题

自然是继承有一些问题

继承会导致超类和子类之间存在强耦合性,当超类改变时,子类也会随之改变;

超类的内部细节对于子类是可见的,继承常常被认为破坏了封装性;

三、装饰模式的结构

深入理解Java设计模式之装饰模式

在装饰器模式中的角色有:

  • 抽象构件(component)角色:给出一个抽象接口,已规范准备接收附加责任的对象。
  • 具体构件(concretecomponent)角色:定义一个将要接收附加责任的类
  • 装饰(decorator)角色:持有一个构件(component)对象的实例,并定义一个与抽象构件接口一致的接口。
  • 具体装饰(concretedecorator)角色:负责给构件对象“贴上”附加的责任。

四、装饰模式的使用场景

1.需要扩展一个类的功能或给一个类增加附加责任。

2.需要动态地给一个对象增加功能,这些功能可以再动态地撤销。

3.需要增加由一些基本功能的排列组合而产生的非常大量的功能

五、装饰模式的优缺点

优点:

1.装饰这模式和继承的目的都是扩展对象的功能,但装饰者模式比继承更灵活

2.通过使用不同的具体装饰类以及这些类的排列组合,设计师可以创造出很多不同行为的组合

3.装饰者模式有很好地可扩展性

缺点:

装饰者模式会导致设计中出现许多小对象,如果过度使用,会让程序变的更复杂。并且更多的对象会是的差错变得困难,特别是这些对象看上去都很像。

六、装饰模式的实现

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
/// <summary>
    /// 手机抽象类,即装饰者模式中的抽象组件类
    /// </summary>
    public abstract class phone
    {
        public abstract void print();
    }
     /// <summary>
    /// 苹果手机,即装饰着模式中的具体组件类
    /// </summary>
    public class applephone:phone
    {
        /// <summary>
        /// 重写基类方法
        /// </summary>
        public override void print()
        {
            console.writeline("开始执行具体的对象——苹果手机");
        }
    }
     /// <summary>
    /// 装饰抽象类,要让装饰完全取代抽象组件,所以必须继承自photo
    /// </summary>
    public abstract class decorator:phone
    {
        private phone phone;
         public decorator(phone p)
        {
            this.phone = p;
        }
         public override void print()
        {
            if (phone != null)
            {
                phone.print();
            }
        }
    }
     /// <summary>
    /// 贴膜,即具体装饰者
    /// </summary>
    public class sticker : decorator
    {
        public sticker(phone p)
            : base(p)
        {
        }
         public override void print()
        {
            base.print();
             // 添加新的行为
            addsticker();     
        }
         /// <summary>
        /// 新的行为方法
        /// </summary>
        public void addsticker()
        {
            console.writeline("现在苹果手机有贴膜了");
        }
    }
     /// <summary>
    /// 手机挂件
    /// </summary>
    public class accessories : decorator
    {
        public accessories(phone p)
            : base(p)
        {
        }
         public override void print()
        {
            base.print();
             // 添加新的行为
            addaccessories();         
        }
         /// <summary>
        /// 新的行为方法
        /// </summary>
        public void addaccessories()
        {
            console.writeline("现在苹果手机有漂亮的挂件了");
        }
    }

客户端代码

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class customer
    {
        static void main(string[] args)
        {
            // 我买了个苹果手机
            phone phone = new applephone();
             // 现在想贴膜了
            decorator applephonewithsticker = new sticker(phone);
            // 扩展贴膜行为
            applephonewithsticker.print();
            console.writeline("----------------------\n");
             // 现在我想有挂件了
            decorator applephonewithaccessories = new accessories(phone);
            // 扩展手机挂件行为
            applephonewithaccessories.print();
            console.writeline("----------------------\n");
             // 现在我同时有贴膜和手机挂件了
            sticker sticker = new sticker(phone);
            accessories applephonewithaccessoriesandsticker = new accessories(sticker);
            applephonewithaccessoriesandsticker.print();
            console.readline();
        }

从上面的客户端代码可以看出,客户端可以动态地将手机配件增加到手机上,如果需要添加手机外壳时,此时只需要添加一个继承decorator的手机外壳类,从而,装饰模式扩展性也非常好。

七、装饰模式的.net应用

在.net 类库中也有装饰者模式的实现,该类就是system.io.stream

?
1
2
3
4
5
6
7
memorystream memorystream = new memorystream(new byte[] {95,96,97,98,99});
             // 扩展缓冲的功能
            bufferedstream buffstream = new bufferedstream(memorystream);
             // 添加加密的功能
            cryptostream cryptostream = new cryptostream(memorystream,new aesmanaged().createencryptor(),cryptostreammode.write);
            // 添加压缩功能
            gzipstream gzipstream = new gzipstream(memorystream, compressionmode.compress, true);

八、总结

装饰者模式本质上来说是aop思想的一种实现方式,其持有被装饰者,因此可以控制被装饰者的行为从而达到了aop的效果。

要点:

1:继承属于扩展形式一种,但不见的是达到弹性设计的最佳方式,组合优于继承。

2:应该允许行为可以被拓展,而无需修改现有的代码。

3:装饰者模式意味着一群装饰者类,这些类用来包装具体组件。

4:装饰者类反映出被装饰组件类型。

5:可以使用无数个装饰者包装一个组件。

6:装饰者会导致设计中出现许多小对象,如果过度使用,会让程序变得很复杂。

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注服务器之家的更多内容!

原文链接:https://www.cnblogs.com/xuwendong/p/10180943.html

延伸 · 阅读

精彩推荐
  • Java教程解决Intellij IDEA覆盖tomcat配置的问题

    解决Intellij IDEA覆盖tomcat配置的问题

    分析并解决Intellij IDEA覆盖tomcat配置的问题/解决修改server.xml无效的问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要...

    ttzzn7802021-08-08
  • Java教程详谈Spring框架之事务管理

    详谈Spring框架之事务管理

    下面小编就为大家带来一篇详谈Spring框架之事务管理。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    ThreadLocal_J11472021-01-07
  • Java教程浅谈springboot项目中定时任务如何优雅退出

    浅谈springboot项目中定时任务如何优雅退出

    这篇文章主要介绍了浅谈springboot项目中定时任务如何优雅退出?具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    格调1004272020-09-30
  • Java教程Java初学者入门之继承和多态

    Java初学者入门之继承和多态

    Java 面向对象编程有三大特性:封装、继承、多态,学好继承和多态是面向对象开发语言中非常重要的一个环节,这篇文章主要给大家介绍了关于Java初学者入...

    满天星辰只为你闪耀8212021-09-24
  • Java教程java实现Flappy Bird游戏源代码

    java实现Flappy Bird游戏源代码

    这篇文章主要为大家详细介绍了java实现Flappy Bird游戏源代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    Koma_Wong8122021-06-24
  • Java教程一篇文章从无到有详解Spring中的AOP

    一篇文章从无到有详解Spring中的AOP

    Spring AOP 是基于 AOP 编程模式的一个框架,它的使用有效减少了系统间的重复代码,达到了模块间的松耦合目的,这篇文章主要给大家介绍了关于Spring中AOP的...

    笑容不是为了我11922021-12-03
  • Java教程RateLimit-使用guava来做接口限流代码示例

    RateLimit-使用guava来做接口限流代码示例

    这篇文章主要介绍了RateLimit-使用guava来做接口限流代码示例,具有一定借鉴价值,需要的朋友可以参考下...

    jiesa10682021-03-24
  • Java教程java实现四子棋游戏

    java实现四子棋游戏

    这篇文章主要为大家详细介绍了java实现四子棋游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    孤风寒雪7802021-08-24