zoukankan      html  css  js  c++  java
  • 业务应该这么写--特性

           特性真的好常见,用到地方也挺多的。

           在我平时工作中,看得比较多的特性有Web端:权限控制Authorize,过滤器,序列化,WCF,Webservice里面也有很多,WebMethod,DataContract,还有做桌面端的用得最多的DllImport(可以直接和Win32程序进行通信),还有我们常用到ORM,特性真的是无所不能,好像高逼格的地方,特性总是要来搞事。下面让我们一起来看看特性究竟是怎么样进行工作的。

       (一)特性出现的背景和初衷是什么,用来解决什么问题

               特性:给类,方法等提供附加的功能,增强了软件系统的灵活性,促进了功能的松散耦合。

               用特性呢,可以避免多个类似的代码段,创建更为可读和清晰的代码。如果我们可以用.Net自带的特性,我们应该积极的用。

       如果不能的话呢,我们就可以自己定义一个特性类。特性属于声明式编程的一种。

       (二)特性的好处和坏处,带来的挑战是什么

              特性的好处:在不破坏类型封装的前提下,增加一点额外的信息和功能。更加灵活了。就是可以把业务和非业务逻辑区分得更开。

              特性的坏处:定义。应用和反射特性能带来许多便利。所以很多开发人员都喜欢用这些技术。而特性是存在元数据里面的,可能会对性能有一些影响。因为要用反射的话,内部都必须扫描托管模块的元数据,执行字符串比较来定位到指定的特性类。这样操作是会耗费一定时间的。

    假如对性能要求比较高的话,可以缓存这些结果。

     (三)适用场景  

              1、业务场景

             我们平时很多公共逻辑,比如需要登录才可以进行授权。定义枚举的时候,要带上描述信息。ORM里面的表名,列名映射关系。等等,还有很多地方,欢迎大家补充。

       (四)特性的组成部分和关键点

               4/1 特性的基本组成

               

               从上图可以知道,特性是属于元数据里面的内容的,我们也可以通过反编译来看看一下就可以明白了。

               1、如下例子:

      class Program
        {
            [Text()]
            static void Main(string[] args)
            {
                Console.WriteLine("test");
            }
        }
    
        public class TextAttribute : Attribute
        {
            
        }

            我们直接来看反编译这段程序之后的IL;

            

               从上面可以看出,特性就是存在我们元数据中的,而且还会去调用这个特性类的构造函数。

               4/2 特性的基础知识点

               1、特性类,都必须要继承自Attribute。这是因为面向CLR的所有编译器都必须识别Attribute,并且最终能在元数据中生成特性信息。

               编译器有点傻的就是不管这个特性有没有用,都会生成对应的元数据。

                2、特性可以应用于程序集,模块,类型,字段,返回值,方法,参数,属性,事件。

                3、接下来我们思考一个问题,我们是不是定义一个特性,然后就可以随便用呢,用在属性,方法,程序集,等等这些属性上。假如我们不指定特性的使用范围呢,那我们反射的时候,是不是要从方法,属性,类上面都检测一下是否含有这个特性呢,想想这样会给我们性能带来多大的影响呢。所以C#的设计者给我们提供了一个 [AttributeUsage(AttributeTargets.All,AllowMultiple =true,Inherited =true)] 这个东西。

                   (1)AttributeUsage是一个特性类,可以通过reflector看看它里面就明白了

                     

         我们直接需要传三个参数的构造函数。 [AttributeUsage(AttributeTargets.All,AllowMultiple =true)]

                 AttributeTargets 这是一个枚举。这个主要是用来指定特性的作用范围。作为一个程序员,我们应该要根据需要来合理指定。

                 

                 Inherited: 这个是说这个特性是否要进行继承,如果要设置为true的话呢,我们反射去检查它的派生类是否应用了这个特性。

                  一般情况下,我们不会把这个值设置为true,这样除了会额外的检查,可能还会带来混淆。所以一般建议定义特性类的时候,把它

                 设定为sealed,减少混淆,避免这次检查。

                 AllowMultiple:一般来说,太多特性多次应用于同一个目标是没有意义的。没有什么特别必要把这个值设置为true。

               4/3 特性的三部曲。

              1、定义一个类,继承自Attribute类,并且类名是以Attribute结尾的。

              2、给指定的方法,属性,类等等,给需要用特性的地方,加上特性打上标记。 

              3、通过反射来调用,使得特性生效。

              很多人的错觉,就是以为写上特性就可以生效。所有让特性生效的地方一定是主动应用了这个特性。

        (五)特性的底层原理和关键实现

              定制特性能有效,完全是因为元数据和反射这个东东。

        (六)已有的实现和它进行对比

             之前我们没用特性的时候,我们普通的做法就是,假设现在是做Webservice开发,定义一个父类(Base),里面写一些通用的方法,然后所有的asmx都继承这个父类,之后在每个需要用的地方调用一下。

             估计还有其他做法,我之后再慢慢分享,今天实在是太累了...欢迎大家留言讨论,祝大家中秋快乐。

  • 相关阅读:
    JAVA 设计模式 组合模式
    JAVA 设计模式 模板方法模式
    SpringBoot 数据篇之使用JDBC
    [Spring]01_环境配置
    [spring]03_装配Bean
    [Spring]04_最小化Spring XML配置
    [Quartz笔记]玩转定时调度
    [Spring]支持注解的Spring调度器
    asp.net core 系列 13 日志
    asp.net core 系列 12 选项 TOptions
  • 原文地址:https://www.cnblogs.com/gdouzz/p/9684720.html
Copyright © 2011-2022 走看看