这是个自己总结的架构,半领域驱动。
实际项目结构:
1. Sample.Web:表示层
2. Sample.App:应用程序层
3. Sample.Core:业务逻辑层
4. Sample.Impl:各个具体实现
5. Frameworks:常用组件图
表示层代码:
1. NewsApplication newsApp = new NewsApplication(this.contextUserId);
a. new一个ApplicationLayer的News对象,传入当前用户ID
2. PostNewsRequest request = GetUserInput();
a. 根据用户的输入,生成Request对象(如同消息一样,分Request/Response2个)
3. PostNewsResponse response= newsApp.PostNews(request);
a. 传入request对象,执行函数,返回response对象
4. newsApp.BindBrokenMessages2WebPageBindableFieldValidators(this);
a. 如果函数执行出现问题,在newsApp对象中有个属性List<Message> BrokenRules, 里面存放着此次函数执行过程中出现的异常,BindBrokenMessages2WebPageBindableFieldValidators这个函数会根据这个BrokenRules列表往webpage中设置出错表示信息
业务逻辑层代码
业务逻辑层工程结构图
NewsManager代码
Post新闻业务方法代码
建议业务方法中代码块的顺序:
1. 清除异常消息列表
2. 调用验证类来实现业务对象的有效性验证
3. 执行非验证类型业务逻辑
想要在业务逻辑中不强耦合具体外部类,需要使用接口。
在这个业务逻辑中使用了下面三个接口,定义如下:
要把某个具体实现了某接口的类注入到业务逻辑中,共有2种方式:构造函数注入和属性注入,我们首选构造函数注入方式,代码如下:
userId代表当前调用这个业务方法的用户ID
BaseMgr类定义
BrokenMessageEnabled类定义(继承这个class的类能够记录下所有的异常信息到BrokenRuleMessage List中)
实体定义
通过使用System.ComponentModel.DataAnnotations命名空间下的Attribute来自动化验证特性(需要引用程序集 System.ComponentModel.DataAnnotations.dll)
如何验证实体
左边是业务逻辑层中进行验证动作时所写的代码
右边是具体验证类,继承在BaseValidator<NewsEntity>,是个范型类,里面的T就是上面定义的NewsEntity;在这个新的验证类(PostNewsValidator)中,只有一个方法需要override,而且名称为ValidateExtraRules,之所以命名为Extra,而没有命名为Basic,是因为BaseValidator<NewsEntity>已经为我们进行了Basic的验证(就是写在NewsEntity中的那些Attribute);这里的ExtraRules是指那些需要较多运算的规则,比如:当Body中包含有ABC字符串时,Body可以任意输入,或者验证中需要使用到数据库操作、文件操作等等依赖外部系统的、较复杂的规则
仓储接口定义
这个仓储可以简单的认为是以前的DAL层
再拿上面说到的业务逻辑代码作示范:
INewsRepository只有个空壳子
Insert方法哪里来的?如下:
添加、修改、删除、获取都已经定义了,所以如果只是调用普通操作就不需要额外定义方法了
但是如果需要使用到其他方法,比如:SearchUser(userName, encryptedPassword),那就要在INewsRepository中定义这个方法了
应用程序层代码
作用
由于业务逻辑层中已经将所有外部系统操作定义成了接口形式,因此表示层要能使用业务逻辑方法就需要将实现了那些接口的具体实现类注入到业务逻辑操作类中,考虑到解耦以及代码的封装简化目的,所以出现了应用程序层,由这个层来完成接口的注入。
BootStrap类
给各个接口关联具体实现类(使用了开源工具StructureMap)
代码如下:
此时,ObjectFactory.GetInstance<IEmailSender>()这句代码就能返回SNF.EmailSenderProvider实例。
消息请求/回应
这里只的是一种消息模式,比如:PostNews这个,按照新的消息模式的话共分3步:
生成PostNews的Request消息
调用PostNews业务方法
接收PostNews业务方法返回的Response消息
表示层调用应用程序层的代码如下:
NewsApplication说明
注意此时的构造函数只传入一个userId代表当前操作的userId,具体外部具体实现类会在构造函数中通过StructureMap工具来获得
PostNews方法已经换成了传入Request参数、传出Response对象的形式
在PostNews方法中,没有业务逻辑,此时这个函数重点在于对象转换、接口引用等装配上的工作。
单元测试
需要针对业务逻辑层中的类进行单元测试
学习方向
DDD(Domain Driven Developing, 领域驱动编程)
单元测试的艺术
设计模式
分层、各层的作用
O(∩_∩)O~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
致力于为欧美企业提供IT综合服务的软件商
O(∩_∩)O~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~