zoukankan      html  css  js  c++  java
  • [译文] 应用领域驱动设计, 第五章

    原文: Applied Domain-Driven Design (DDD), Part 5 - Domain Service

    Domain Service is not be confused with Application Service or Web Service. Domain Service lives in the Domain Model Layer. Unlike Application or Web Service, Domain Service should not be called each time to access Domain Model Layer. You can call your repository interface in the Application Layer and get the Domain Entity directly.

    不要将领域服务与应用服务, Web Service 弄混淆了. 领域服务位于领域模型层. 与应用服务或者 Web Service 不同, 不应该每次都通过调用领域服务去访问领域模型层. 你可以在应用层中调用数据仓储接口, 直接获取领域实体.

    需求 Requirement

    Your business is responsible for collecting and paying Value Added Tax (VAT) based off your business location, your customer's location, and the type of product you are selling.

    你的企业通过 营业地点, 客户所在的地点 以及 要销售的产品类型 来负责收取和支付增值税 (VAT).

    领域服务示例 Domain Service Sample

    public class TaxDomainService : ITaxDomainService
    {
        readonly IRepository<ProductTax> productTax; /** 产品类型数款. */
        readonly IRepository<CountryTax> countryTax; /** 客户所在的地点税款. */
        readonly Settings settings; /** 营业地点税款. */
    
        public TaxDomainService(Settings settings,
                                IRepository<ProductTax> productTax,
                                IRepository<CountryTax> countryTax)
        {
            this.productTax = productTax;
            this.countryTax = countryTax;
            this.settings = settings;
        }
    
        public decimal Calculate(Customer customer, Product product)
        {
            CountryTax customerCountryTax = this.countryTax.FindById(customer.Country.Id);
            CountryTax businessCountryTax = this.countryTax.FindById(settings.BusinessCountry.Id);
            ProductTax productTax = this.productTax.FindById(product.Code.Id);
    
            return (product.Cost * customerCountryTax.Percentage) +
                   (product.Cost * businessCountryTax.Percentage) +
                   (product.Cost * productTax.Percentage);
        }
    }
    

    使用范例 Example usage

    Customer customer = this.repositoryCustomer.FindById(customerId);
    Product product = this.repositoryProduct.FindById(productId);
     
    decimal tax = this.taxDomainService.Calculate(customer, product);
     
    customer.Cart.Add(CartProduct.Create(customer.Cart, product, productQuantity, tax));
    

    总结 Summary

    • Domain Service allows you to capture logic that doesn't belong in the Domain Entity.
    • 可以通过领域服务捕获不属于领域实体的业务逻辑.
    • Domain Service allows you to orchestrate between different Domain Entities.
    • 可以通过领域服务在不同的领域实体间进行协调.

    技巧 Tips

    • Don't create too many Domain Services, most of the logic should reside in the domain entities, event handlers, etc.
    • 不要创造太多的领域服务, 绝大多数的逻辑应该驻留在领域实体, 事件处理代码等中.
    • It's a great place for calculation and validation as it can access entities, and other kind of objects (e.g. Settings) that are not available via the entity graph.
    • 领域服务是放置计算, 验证的最佳场所, 因为领域服务可以访问实体和其他无法通过实体图谱 (entity graph) 访问的对象, 例如 Settings.
    • Methods should return primitive types, custom enums are fine too.
    • 方法应该返回原始类型, 自定义枚举类型也可以.

    *Note: Code in this article is not production ready and is used for prototyping purposes only. If you have suggestions or feedback please do comment.

    *注意: 本文中的代码尚未准备好投入生产, 仅用于原型设计. 如果有建议和反馈, 请发表评论.

  • 相关阅读:
    加班的价值
    webApp 阅读器项目实践
    Oak Seeds 网站项目回顾
    [Echarts]用Echarts绘制饼状图
    [转载] 编程每一天(Write Code Every Day)
    对杀毒软件技术的浅浅理解
    记我的第二次自动化尝试——selenium+pageobject+pagefactory实现自动化下单、退款、撤销回归测试
    学习Selenium遇到的问题和解决方案
    记我的第一次自动化尝试
    jmeter环境配置、使用以及参数化之CSV Data Set Config
  • 原文地址:https://www.cnblogs.com/xixixiao/p/applied-domain-driven-design-ddd-part-5.html
Copyright © 2011-2022 走看看