• c#设计模式之装饰者模式


    装饰者模式是动态地扩展一个对象的功能。下面看一个例子:网页中要使用图片,我要上传图片,具体规则:

    1、对于一些比较大,甚至几兆的图片,上传后,生成缩略图,生成缩略图可以按照指定尺寸,或者固定宽,高按比例缩放。

    2、对于tif格式的图片,通常都比较大,需要转jpg格式的图片,或者转jpg格式后,若发现图片还是很大,再进行压缩处理。

    3、对于合适大小的图片,上传上去不做处理。

    首先定义一个抽象类,用来实现上传:

     1  public abstract class AbstractUpload
     2     {
     3        
     4         public Stream FileStream { set; get; }
     5 
     6 
     7         public UploadInfo Result { set; get; }
     8  
     9         public abstract byte[] GetContent();
    10 
    11         public virtual UploadInfo Upload(string listTitle, string fileName, bool isRename = true){
    12           //具体上传方法
    13         }
    14          public virtual UploadInfo GetResult(){
    15 
    16            //获取上传结果
    17          }
    18 }

    然后定义装饰者的抽象类:

    1  public abstract class UploadDecrator:AbstractUpload
    2     {
    3         public AbstractUpload UpLoader { set; get; }
    4 
    5     }

    下面是按照规定尺寸生成缩略图:

     public class ThumbUpload:UploadDecrator
        {
    
            public ThumbImageInfo ImgInfo { set; get; }
    
             public ThumbUpload(AbstractUpload upload,ThumbImageInfo imgInfo)
            {
    
                this.UpLoader = upload;
    
                this.ImgInfo = imgInfo;
            }
    
            public override byte[] GetContent()
            {
               var img= MakeSmallPic();
    
               return StringUlity.ImgToByte(img);
            }
    }

    接着,我们实现tif图片的处理:

     1  public class TifImageUpload : UploadDecrator
     2     {
     3         public ThumbImageInfo ImgInfo { set; get; }
     4 
     5         public bool IsCacularMode { set; get; }
     6 
     7         public TifImageUpload(AbstractUpload upload, ThumbImageInfo imgInfo, bool isCacularMode)
     8         {
     9 
    10             this.UpLoader = upload;
    11 
    12             this.ImgInfo = imgInfo;
    13 
    14             this.IsCacularMode = isCacularMode;
    15         }
    16 
    17         public TifImageUpload(AbstractUpload upload, bool isCacularMode)
    18         {
    19 
    20             this.UpLoader = upload;
    21             this.IsCacularMode = isCacularMode;
    22         }
    23 
    24 
    25         public override byte[] GetContent()
    26         {
    27             var img = MakeSmallPic();
    28 
    29             return StringUlity.ImgToByte(img);
    30         }
    31 }

    看到这儿,可能有人会有疑问,具体的类,为什么不直接继承AbstractUpload呢?因为AbstractUpload类是一个抽象类,它还为其它的各种文件上传使用,为了不影响这个基础的抽象类,所以我们单独定义自己的装饰者抽象类。

    看看客户端是如何调用的?

    这个是上传tif图片,处理为jpg格式,然后再上传。

    看到这里,是不是觉得FileStreamUpload f ,这个有点问题,与构造函数的类型不一致呢?且看下文:

     1   /// <summary>
     2     /// 上传文件
     3     /// </summary>
     4     public class FileStreamUpload : AbstractUpload
     5     {
     6 
     7         public FileStreamUpload(Stream stream)
     8         {
     9 
    10             this.FileStream = stream;
    11         }
    12 
    13         public override byte[] GetContent()
    14         {
    15             int iLength = (int)FileStream.Length;
    16 
    17 
    18             Byte[] filecontent=null;
    19 
    20             if (iLength > 0)
    21             {
    22                 filecontent = new byte[iLength];
    23                 FileStream.Read(filecontent, 0, iLength);
    24             }
    25             return filecontent;
    26         }
    27     }

    这个是所有文件上传类,也继承自抽象类AbstractUpload。且看这些类之间的关系:

    上图是装饰者模式的uml图,其巧妙之处在于装饰者类UploadDecrator组合了自己的一个基类。这是一个组合优于继承的设计原则体现。说到这儿,我们回顾下面向对象设计的基本原则:

    1、单一职责:一个类只做一件事情。

    2、开闭原则:对修改关闭,对扩展开放。

    3、依赖倒置:高层模块不应该依赖于低层模块,两者均依赖于抽象。这个抽象是从高层模块抽象出来的。

    4、里氏替换:子类可以替换父类,可以在运行时决定是哪个子类替代父类实现,它是实现开闭原则的重要方式。

    5、接口隔离:尽量使用“瘦”接口。

    6、迪米特法则:最少知识原则,一个对象对其它对象有尽可能少的了解。

    7、组合/聚合复用原则:组合优于继承。

    前5个为基本原则。设计模式会体现这些设计原则,所以我们必须得好好参悟。

        

  • 相关阅读:
    RabbitMQ指南之一:"Hello World!"
    Java8新特性之五:Optional
    Java8新特性之四:接口默认方法和静态方法
    Java8新特性之三:Stream API
    Java8新特性之二:方法引用
    Notepad++编辑器——Verilog代码片段和语法检查
    数电(5):半导体存储电路
    数电(4):组合逻辑电路
    DDR3_新版(1):IP核调取和官方例程仿真
    数电(2):逻辑代数的基本定理
  • 原文地址:https://www.cnblogs.com/wangqiang3311/p/5924427.html
Copyright © 2020-2023  润新知