业务逻辑-Domain Model

Posted lovetomato

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了业务逻辑-Domain Model相关的知识,希望对你有一定的参考价值。

Domain Model是对现实世界中的业务抽象为类,所以类不只包含数据,还包括方法(现实世界的业务逻辑)。但领域模型不包括数据的存取,一般通过仓储模式将(POCO)对象管理数据。
设计一个复杂的系统,应先将现实世界的业务逻辑分割为不同的界限上下文,其实每个界限上下文对应现实世界的一部分独立业务逻辑,将不同的独立业务逻辑拼成一个复杂系统。现实逻辑与程序界限逻辑对应利于代码管理。

仓储模型

这里用Entity Framwork作为仓储模型,因为Entity Framwork已经是仓储模型,没有必要再包一层仓储接口。
Entity Framwork可通过DbSet<T>获取保存复杂类型(一个业务类型的属性为一个业务类型,这样为属性的类型对应的数据表存在外键

案例

这里以一个银行系统为例

  1. 用户可用开户
  2. 用户可存入、取出、转账,都需要记日志

    代码

    代码[下载]]()

    数据层

    新建Domain.Data类库,通过包安装entity framwork
    定义类
    public class BankAccount
    {
        public Guid BankAccountId { get; set; }
        public decimal Balance { get; set; }
        public string CustomerRef { get; set; }

        /// <summary>
        /// 账户交易记录
        /// </summary>
        public virtual ICollection<Transaction> Transactions { get; set; }

        /// <summary>
        /// 是否有足够余额
        /// </summary>
        /// <param name="amount"></param>
        /// <returns></returns>
        public bool CanWithdraw(decimal amount)
        {
            return (Balance >= amount);
        }
        /// <summary>
        /// 取款
        /// </summary>
        /// <param name="amount"></param>
        /// <param name="reference"></param>
        public void Withdraw(decimal amount,string reference)
        {
            if (CanWithdraw(amount))
            {
                Balance -= amount;
                Transactions.Add(new Transaction() { BankAccountId=this.BankAccountId, Withdraw = amount, Reference = reference,Date =DateTime.Now});
            }
            else
            {
                throw new Exception("");
            }
        }

        /// <summary>
        /// 存款
        /// </summary>
        /// <param name="amount"></param>
        /// <param name="reference"></param>
        public void Deposit(decimal amount,string reference)
        {
            Balance += amount;
            Transactions.Add(new Transaction() { Deposit=amount,Reference=reference,Date=DateTime.Now});
        }
    }  

    public class Transaction
    {
        public int ID { get; set; }
        // 数据库建表为BankAccount的外键
        public Guid BankAccountId { get; set; }
        public decimal Deposit { get; set; }
        public decimal Withdraw { get; set; }
        public string Reference { get; set; }
        public DateTime Date { get; set; }

        public virtual BankAccount BankAccount { get; set; }
    }

数据处理上下文

    public class BankAccountContext:DbContext
    {
        public DbSet<BankAccount> BankAccounts { get; set; }
        public DbSet<Transaction> Transactions { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
        }
    }

新建MVC站点引用Domain.Data程序集





以上是关于业务逻辑-Domain Model的主要内容,如果未能解决你的问题,请参考以下文章

什么是领域模型(domain model)?贫血模型(anaemic domain model) 和充血模型(rich domain model)有什么区别

Domain Model & Code First

Domain Logic approaches

Domain Logic approaches

DDD Domain-Driven Design

domain logic approaches