如何理解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年11月11日
  • openwrt 怎么重置网络设置(openwrt节点订阅怎么设置)

    技术Openwrt中luci界面的设置步骤以及作为二级路由的设置是什么这篇文章主要介绍了Openwrt中luci界面的设置步骤以及作为二级路由的设置是什么,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章

    攻略 2021年12月18日
  • Java数组中一维数组如何修改元素

    技术Java数组中一维数组如何修改元素这篇文章给大家分享的是有关Java数组中一维数组如何修改元素的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。/**
    修改scores数组索引index位

    攻略 2021年11月19日
  • 怎么用Java实现判断括号的合法性

    技术怎么用Java实现判断括号的合法性本篇内容介绍了“怎么用Java实现判断括号的合法性”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,

    攻略 2021年11月15日
  • java如何简单快速处理 json 中的数据

    技术java如何简单快速处理 json 中的数据java如何简单快速处理 json 中的数据,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。JSONstr.j

    攻略 2021年12月2日
  • Apple Remote Desktop for Mac(远程桌面管理软件)

    技术Apple Remote Desktop for Mac(远程桌面管理软件) Apple Remote Desktop for Mac(远程桌面管理软件)远程管理Apple Remote Deskt

    礼包 2021年12月7日