如何理解Java设计模式的装饰模式

技术如何理解Java设计模式的装饰模式这篇文章主要介绍“如何理解Java设计模式的装饰模式”,在日常操作中,相信很多人在如何理解Java设计模式的装饰模式问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望

本文主要介绍“如何理解Java设计模式的装饰器模式”。在日常操作中,相信很多人对于如何理解Java设计模式的装饰器模式问题都有疑问。边肖查阅了各种资料,整理出简单易用的操作方法,希望能帮助大家解答“如何理解Java设计模式的decorator模式”的疑惑!接下来,请和边肖一起学习!

一、前言

装饰器模式实际上提倡的是组合而不是继承的做法。个人认为,要理解decorator模型,首先要理解为什么需要组合而不是继承,为什么继承让人深恶痛绝。

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

面向对象的特性包括继承和封装,但它们之间存在矛盾。继承是指子类依赖于父类中的实现,一旦父类中的实现发生变化,就会影响子类,这是打破封装的一种表现形式,而组合就是巧妙地利用封装来实现继承函数的代码重用。

二、什么是装饰模式

1.定义:

装饰器模式也称为Wrapper模式。装饰器模式以对客户端透明的方式扩展对象的功能,这是继承关系的一种替代。

2.意图

动态地给对象添加一些额外的职责。在添加函数方面,Decorator模式比生成子类更灵活。

00-1010包装

00-1010有时我们想给一个对象而不是整个类添加一些函数。例如,图形用户界面工具箱允许您向任何用户界面模块添加一些组件,如边框,或一些行为,如窗口滚动。

00-1010让类在不修改原始接口的情况下表现得更好。

3.别名

自然,继承也有一些问题。

继承会导致超类和子类之间的强耦合。当超类改变时,子类也会改变。

超类的内部细节对子类是可见的,继承通常被认为会破坏封装。

4.动机

如何理解Java设计模式的装饰模式

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

组件角色:给出一个抽象接口,并标准化准备接受额外职责的对象。

具体组件角色:定义一个将接受额外职责的类。

装饰角色:保存一个组件对象的实例,并定义一个与抽象组件接口一致的接口。

混凝土装饰者角色:负责给组件对象附加额外的职责。

00-1010 1.有必要扩展一个类的功能或者给一个类增加额外的职责。

2.需要向对象动态添加函数,这些函数可以动态撤销。

3.需要增加大量由一些基本函数的排列组合而成的函数。

5.作用

优点:

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

2.设计师可以通过使用不同的混凝土装饰类以及这些类的排列和组合来创建许多不同行为的组合。

3.装饰器模式具有良好的可扩展性

缺点:

装饰器模式会导致设计中出现许多小对象。如果过度使用,会使程序更加复杂。而且对象多了会很难出错,尤其是长得都差不多的时候。

6.问题

///摘要

///手机抽象类,即decorator模式下的抽象组件类。

////摘要

publicabstractclassPhone

{

publicatabstractvoitprint();

}

///摘要

///苹果手机,也就是装饰图案中的具体组件类。

  /// </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("现在苹果手机有漂亮的挂件了");
        }
    }

客户端代码

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

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);

到此,关于“如何理解Java设计模式的装饰模式”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/76876.html

(0)

相关推荐

  • MySQL索引面试题有哪些

    技术MySQL索引面试题有哪些这篇文章主要介绍“MySQL索引面试题有哪些”,在日常操作中,相信很多人在MySQL索引面试题有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”MySQL索

    攻略 2021年12月3日
  • 如何使用sysbench做oltp测试

    技术如何使用sysbench做oltp测试小编给大家分享一下如何使用sysbench做oltp测试,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧

    攻略 2021年10月27日
  • Java如何实现家政服务平台系统

    技术Java如何实现家政服务平台系统这期内容当中小编将会给大家带来有关Java如何实现家政服务平台系统,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。一、项目简述功能包括: 家政服务网站

    攻略 2021年11月24日
  • 美国服务器搭建游戏服务端有什么好USA-IDC

    技术美国服务器搭建游戏服务端有什么好USA-IDC通过服务器设置,您可以将其视为更像是为其玩家托管视频游戏的远程计算机。由于美国服务器不在游戏引擎上运行,因此它需要使用上述图形卡那样呈现任何内容。然而,它的作用是指示客户

    礼包 2021年12月23日
  • 正三棱柱的性质,正三棱柱与直三棱柱有区别吗

    技术正三棱柱的性质,正三棱柱与直三棱柱有区别吗根据三棱柱的基本性质和分类,可知正三棱柱和直三棱柱的区别为底面不同正三棱柱的性质、侧面不同、范围不同,具体区别如下:1、棱柱的底面不同正三棱柱的底面是全等的正三角形,直三棱柱

    生活 2021年10月30日
  • 设计模式21-状态模式,State)

    技术设计模式21-状态模式,State) 设计模式21-状态模式(State)如果一个实体具备状态,且在不同状态下会在同一业务场景执行不同的业务逻辑时,就可以考虑使用状态模式。设计模式21-状态模式(S

    礼包 2021年10月28日