.NET框架设计中一些常被忽视的C#设计技巧
1.被忽视的特性(Attribute)设计方式
通常在一些框架中对Entity进行逻辑上的关联用的,比如我们比较熟悉的ORM,都会在Entity的上面加上一个类似 [Table(TableName=”Order”)] 这样的特性声明,然后再在自己的框架中通过反射的方式去在运行时差找元数据找到这个特性,然后就可以对附加了这个特性的类型进行相关的处理;这其实没有问题,很正常的设计思路,也是比较通用的设计方法;但是我们的思维被前人固化了,难道特性就只能作为代码的声明吗?问过自己这个问题吗?
现在我们假设需要在Entity上面加上两个特性第一个用来断定它是否需要做Cache,第二个用来确定关于Entity操作验证的特性;
看代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /// <summary> 2 /// Order. 3 /// </summary> 4 [EntityCache(10, true)] 5 [EntityValidator(ValidatorOperationType.All)] 6 public class Order 7 {}
代码应该很明了,第一EntityCache用来设计实体的缓存,参数是缓存的过期时间;第二个特性EntityValidator用来设置当实体进行相关处理的时候需要的验证类型,这里选择是所有操作;现在的问题是关于特性的优先级,对于Order类的处理到底是先Cache然后验证,还是先验证然后Cache或者说内部没有进行任何的逻辑处理;如果我们将特性的视为代码的标识而不是真正的逻辑,那么对于优先级的处理会比较棘手,你需要设计如何将不同的特性处理逻辑关联起来;比较合理的设计方法是特性的处理链表;也是用的链表的方式将所有的特性按照顺序串联起来然后将对象穿过特性内部逻辑,
看代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 Codeusing System; 2 namespace Infrastructure.Common 3 { 4 [AttributeUsage(AttributeTargets.Class)] 5 public abstract class EntityOperation : Attribute 6 { 7 protected EntityOperation NextOperation { get; set; } 8 } 9 }
我们抽象出所有的处理,然后在内部包含下一个处理逻辑的特性实例;然后让各自的Attribute继承自它;
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 namespace Infrastructure.Common.Cache 7 { 8 [AttributeUsage(AttributeTargets.Class)] 9 public class EntityCache : EntityOperation 10 { 11 public EntityCache(int cacheTime, bool IsEnable) 12 { 13 this.ExpireTime = cacheTime; 14 } 15 public int ExpireTime { get; set; } 16 } 17 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 namespace Infrastructure.Common.Validator 7 { 8 public enum ValidatorOperationType 9 { 10 Insert, 11 Delete, 12 Update, 13 Select, 14 All 15 } 16 [AttributeUsage(AttributeTargets.Class)] 17 public class EntityValidator : EntityOperation 18 { 19 public EntityValidator(ValidatorOperationType validatorType) 20 { 21 } 22 } 23 }
根据特性在类的先后顺序就可以控制他们的优先级:
上图很直观的表现了链表设计思想,再通过仔细的加工应该会很不错的。
2.链式编程(设计符合大脑思维习惯的处理流程)
其实那么多的C#新特性都是为了能让我们编写代码能更方便,总之一句话是为了更符合大脑思维习惯的编程模式;
C#从纯面向对象渐渐的加入了函数式模式,从静态类型逐渐加人动态类型特性;C#现在变成多范式编程语言,其实已经很大程度满足我们的日常需求;以往我们都会为了动态行为编写复杂的Emit代码,用很多CodeDom的技术;现在可以使用Dymanic解决了;
这是对需求的理解能力;可以将链式思想用在很多地方,只要有逻辑有流程的地方都可以进行相关设计,首先你要保证你是一个正常思考问题的人,别设计出来的方法是反的,那么用的人会很不爽的。