1.1 说明
1.2 C# 部分语法内容扩展
1.3 可重载运算符(Overloadable Operators)与
转换运算符(Conversion Operators)
1.4 面向插件架构和现场部署的配置系统设计
1.5 实现依赖注入
本章以工程化使用为目的,对C#和.NET Framework提供的几个平时开发时不引人注意的特征进行介绍,它们对于提高代码扩展性、灵活性很关键,务求用“很C#”的方式解决以往设计模式Example之外必须面临的一些问题。它们主要包括:
Namespace(命名空间);
Delegate(委托);
Generics(泛型);
Attribute(属性);
Indexer(索引器);
Iterator(迭代器);
Overloadable Operators(可重载运算符)与Conversion Operators(转换运算符);
Configuration(对象化配置访问);
由于降低类间耦合关系一直是设计上控制变化范围的常用手段之一,所以在设计模式之外补充有关用C#实现“依赖注入”(Dependency Injection)的方法。
有关设计模式在Threading(多线程)模型下实现需注意的内容,笔者将在相关章节的工程化分析部分介绍。
是否有很好的命名空间规划是工程化代码与非工程化代码一个很明显的区别。
尤其对于大型的组织而言,如果涉及的产品线、项目、公共平台很多,如何通过命名空间把所有的代码资源有效地组织起来,恐怕是实施项目前要考虑的主要问题。作为一个树形体系,最好有组织级统一的分类标准,目的很明确——用的时候能很容易找到。
做到这点并不容易,原因如下:
习惯中很难改变的缩写命名:CAD很容易在声明的时候被命名为.***CAD,但事实上Design Guideline建议的是Cad,这样使用者和定义者之间就存在一些小小的错位。在99%的情况下这个问题不会发生,因为您只要一个点,IntelliSense就帮您列出来了,另外的1%则发生在后绑定调用的情况下。
不统一的命名:涉及加密的库,可能A被定义为Encrypt,B被定义为Crypto或Cryptography。来自匈牙利命名法的“遗毒”也常常成为新旧开发人员统一命名的障碍,而且会直接影响到命名空间的定义。
组织或您上司的认同:技术总监不认为命名规范是他需要关心的事情,下面的架构师更关心的是结构,再下面的项目经理关注的是资源调度和进度,具体的实施人员恐怕没有多少机会规定其他同事该怎么命名,那么谁来关心命名空间呢?
无论如何,即便没有办法在组织级统一命名空间,为了您所带领的团队现在做的工作在以后能更容易地被应用,或者仅仅为你自己的职业生涯好好“储蓄”,在动笔编写第一行程序之前,先规划好命名空间吧。
可参考的建议来自Design Guideline,示例代码如下:
Txt
例如:Microsoft.WindowsMobile.DirectX.
本书选择了MarvellousWorks.PracticalPattern作为根命名空间,但前提是假设这个公司很小,相关的项目(或产品)很少,而且没有多少组织级通用的代码资源。如果假设它为一个大型软件企业,套用笔者自己组织的命名空间,总体命名空间的规划情况如下:
C#(一级命名空间)
namespace MarvellousWorks.Application
namespace MarvellousWorks.Foundation
namespace MarvellousWorks.Framework
namespace MarvellousWorks.Utility
namespace MarvellousWorks.Training
Application:代表项目或产品。
Foundation:代表公共库,类似Enterprise Library之类的公共基础库、基于企业设备和操作系统平台的通用的图形处理引擎等,但都是纯粹的Class Library,没有UI元素。
Framework:组织通用的框架,基于Foundation之上,面向某个开发领域扩充的Class Library和控件,其本身不能独立运行,但完全可以集成在具体的项目或产品中,比如通用的授权框架、完全Ajax化的前后端组件、报表和打印中间件。
Utility:企业内部各种工具,比如现场故障排查工具、Dump和日志分析工具。
Training:完全面向培训用途,是对企业自身Application、Foundation、Framework(甚至Utility)使用的Examples。
几个一级命名空间的布局如图1-1所示。
图1-1 一个建议的一级命名空间布局和调用关系
本次的PracticalPattern作为实际工程化代码,不属于MarvellousWorks.Training,而应划入MarvellousWorks.Foundation,并将它作为最核心的算法框架,放入MarvellousWorks. Foundation.Core.PracticalPattern。
不论您最终如何定义命名空间,其实它体现的是您意志中对代码资源的规划,如果您觉得工程化的设计模式不是您希望开发团队要考虑的内容,没关系,您可以忽略这部分内容。
这样MarvellousWorks.Foundation.Accessories.PracticalPattern
这样MarvellousWorks.Foundation.Core.Accessories.PracticalPattern
或者这样TestSolution. PracticalPattern
… …