zoukankan      html  css  js  c++  java
  • NLayerAppV3--DDD之领域层

    回顾:NLayerAppV3是一个使用.net 2.1实现的经典DDD的分层架构的项目。

    NLayerAppV3是在NLayerAppV2的基础上,使用.net core2.1进行重新构建的;它包含了开发人员和架构师都可以重用的DDD层。

    Github地址:https://github.com/cesarcastrocuba/nlayerappv3

    上一篇,介绍了NLayerAppV3项目Infrastructure(基础设施层)的Cross-Cutting部分,文章地址:https://www.cnblogs.com/net-yuan/p/NLayerAppV3-Infrastructure_CrossCutting.html

    NLayerAppV3的基础结构层一共分为两个部分。处理数据相关的基础组件Data和Cross-Cutting的基础组件。

    处理数据相关的基础组件Data主要包含UOW和仓储的实现;

    Cross-Cutting的基础组件目前主要包含数据适配器、国际化、验证;

    这篇本来应该介绍Infrastructure(基础设施层)的Data部分。

    可是仓储的具体实现是放在基础结构层的,而仓储的接口则是放在领域模型层的。

    所以,我们就先介绍领域层Domain。

    NLayerAppV3项目的Domain(领域层)分为两个部分:Seedwork和BoundedContext

    Seedwork部分定义了实体的契约、实体的基类、值对象的基类、仓储的契约、UOW的契约、规约等。

    BoundedContext部分定义了聚合相关,聚合、值对象、规约的具体实现、仓储的契约、领域服务等。

    以下描述引用自何老大的博文:

    聚合包装一组高度相关的对象,作为一个数据修改的单元。

    聚合最外层的对象称为聚合根,它是一个实体。聚合根划分出一个清晰的边界,聚合根外部的对象,不能直接访问聚合根内部对象,如果需要访问内部对象,必须首先访问聚合根,再导航到聚合的内部对象。

    聚合代表很强的包含关系,聚合内部的对象脱离了聚合,应该是毫无意义的,或不是你真正关注的,它是聚合的一个组成部分,这与UML中的组成聚合概念相近。

    有关聚合的相关知识可以查看何老大的博文 https://www.cnblogs.com/xiadao521/p/4141904.html

    以BankAccount聚合来看,BankAccount是聚合根,包含卡号BankAccountNumber这样的值对象,BankAccountNumber由国家或者地区银行编号、检查位等构成;Balance金额、Locked是否锁定、Customer用户实体、BankAccountActivity账户活动的集合等等、还包含锁定、解锁、存款等行为。这是一个充血的模型。

    BankAccountFactory是创建聚合BankAccount的工厂,它负责创建BankAccount。

    BankAccountSpecifications封装了BankAccount的查询规约

    public static class BankAccountSpecifications
        {
            /// <summary>
            /// Specification for bank accounts with number like to <paramref name="ibanNumber"/>
            /// </summary>
            /// <param name="ibanNumber">The bank account number</param>
            /// <returns>Associated specification</returns>
            public static ISpecification<BankAccount> BankAccountIbanNumber(string ibanNumber)
            {
                Specification<BankAccount> specification = new TrueSpecification<BankAccount>();
    
                if (!String.IsNullOrWhiteSpace(ibanNumber))
                {
                    specification &= new DirectSpecification<BankAccount>((b) => b.Iban
                                                                                  .ToLower()
                                                                                  .Contains(ibanNumber.ToLower()));
                }
    
                return specification;
            }
        }
    View Code

     IBankAccountRepository提供了BankAccount的仓储契约

    IBankTransferService提供了转账的领域服务契约,有一个转账方法

    void PerformTransfer(decimal amount, BankAccount originAccount, BankAccount destinationAccount);
    

    BankTransferService实现了IBankTransferService

    实现了转账领域服务的逻辑。

    public void PerformTransfer(decimal amount, BankAccount originAccount, BankAccount destinationAccount)
            {
                if (originAccount != null && destinationAccount != null)
                {
                    var messages = LocalizationFactory.CreateLocalResources();
    
                    if (originAccount.BankAccountNumber == destinationAccount.BankAccountNumber) // if transfer in same bank account
                        throw new InvalidOperationException(messages.GetStringResource(LocalizationKeys.Domain.exception_CannotTransferMoneyWhenFromIsTheSameAsTo));
    
                    // Check if customer has required credit and if the BankAccount is not locked
                    if (originAccount.CanBeWithdrawed(amount))
                    {
                        //Domain Logic
                        //Process: Perform transfer operations to in-memory Domain-Model objects        
                        // 1.- Charge money to origin acc
                        // 2.- Credit money to destination acc
    
                        //Charge money
                        originAccount.WithdrawMoney(amount, string.Format(messages.GetStringResource(LocalizationKeys.Domain.messages_TransactionFromMessage), destinationAccount.Id));
    
                        //Credit money
                        destinationAccount.DepositMoney(amount, string.Format(messages.GetStringResource(LocalizationKeys.Domain.messages_TransactionToMessage), originAccount.Id));
                    }
                    else
                        throw new InvalidOperationException(messages.GetStringResource(LocalizationKeys.Domain.exception_BankAccountCannotWithdraw));
                }
            }
    View Code

    参考: dax.net https://www.cnblogs.com/daxnet/archive/2011/06/07/2074451.html

                何镇汐 https://www.cnblogs.com/xiadao521/p/4141904.html

  • 相关阅读:
    csr_matrix参数解析
    SQL删除重复数据(根据多个字段),pandas的nan存入数据库报错
    XGBoost参数中文翻译以及参数调优
    pandas.DataFrame.quantile
    pandas.DataFrame.rank
    JOIN子句
    ORDER BY子句
    WHERE子句
    SELECT语句
    数据分析-基础
  • 原文地址:https://www.cnblogs.com/net-yuan/p/NLayerAppV3-Domain.html
Copyright © 2011-2022 走看看