如何理解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)

相关推荐

  • 电动车好学吗,大提琴好学还是中提琴好学

    技术电动车好学吗,大提琴好学还是中提琴好学我是学小提琴的电动车好学吗,我只想告诉楼主大提琴你上了高中开始学都来的及,中提琴难度和小提琴差不多,必须从小开始练琴,我们好多现在学中提琴的同学都是从小提琴转过来的,练大提琴的同

    生活 2021年10月22日
  • 内存

    技术内存 内存一、物理内存和虚拟内存
    1、虚拟内存每个程序都有4G虚拟内存,相当于空头支票
    只有真正要用的时候,才会在物理内存中给你分配一块物理内存
    4kb页式管理,一页是4kb大小(物理页)2、虚拟内

    礼包 2021年12月24日
  • 怎么理解python的第三方库pandas

    技术怎么理解python的第三方库pandas本篇内容介绍了“怎么理解python的第三方库pandas”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希

    攻略 2021年11月10日
  • HDFS分布式存储有什么优势特点

    技术HDFS分布式存储有什么优势特点这篇文章主要介绍了HDFS分布式存储有什么优势特点,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。近年,随着区块链、大数

    攻略 2021年12月9日
  • 映射ADO.NET如何设置参数

    技术映射ADO.NET如何设置参数这篇文章主要为大家展示了“映射ADO.NET如何设置参数”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“映射ADO.NET如何设置参数”这篇文

    攻略 2021年12月1日
  • 如何理解Solidity的Bytecode和Opcode

    技术如何理解Solidity的Bytecode和Opcode本篇文章为大家展示了如何理解Solidity的Bytecode和Opcode,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收

    攻略 2021年11月23日