如何理解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月2日
  • CF1506A Strange Table 题解

    技术CF1506A Strange Table 题解 CF1506A Strange Table 题解CF1506A Strange Table 题解Content
    给定一个 \(n\times m\)

    礼包 2021年12月16日
  • 心形线,如何用几何画板画出笛卡尔心形线

    技术心形线,如何用几何画板画出笛卡尔心形线1心形线、新建参数。右键绘图区空白处,“新建参数”,标签为a,数值为4,单位“无”。
    2、快捷键“Ctrl+G”,调出绘制新函数编辑器。点“方程”,选极坐标方程。在编辑

    生活 2021年10月30日
  • 如何进行java在hashmap初始化时赋初值过程的解析

    技术如何进行java在hashmap初始化时赋初值过程的解析如何进行java在hashmap初始化时赋初值过程的解析,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习

    攻略 2021年12月8日
  • Steam游戏代理加速服务器首选香港服务器香港主机

    技术Steam游戏代理加速服务器首选香港服务器香港主机随着很多游戏的火爆,现在玩Steam国际服的玩家越来越多,虽然也有很多游戏加速器提供此类网络优化服务,但是如果不充值昂贵的VIP会员的话根本无法满足用户的需求,此外由

    礼包 2021年10月19日
  • js中setInterval和setTimeout区别和用法

    技术js中setInterval和setTimeout区别和用法 js中setInterval和setTimeout区别和用法setTimeout
    setTimeout() //- 在指定时间后执行代码

    礼包 2021年11月14日