走向.NET架构设计—第五章—业务层模式,原则,实践(中篇)

简介:

走向.NET架构设计第五章业务层模式,原则,实践(中篇)

  前言:设计模式并不是什么很高深的东西,至少不是那么“神乎其神”。说到底,设计模式就是一些设计思想。下面我们就走进项目,看看这些项目中这些思想是如何体现的。本系列文章会在后续文章中陆陆续续的,在恰当的时候介绍一些相应的设计模式,而不是一股脑的一起上。 
本篇的议题如下:
架构模式
设计模式
设计原则
 
 
 
 
 
  设计模式
  本篇文章主要是讨论的在业务层可以采用的或者常用的一些设计模式:
  Factory Method
  Decorator
  Template Method
  State
  Strategy
 
  Factory Method
相信很多朋友对这个模式很熟悉了,平时在项目中或多或少总能看到Factory, Provider等。确实Factory Method一种创建型的模式,它的主要目的就是隐藏对象创建的细节。也就是说,客户程序(或者成为调用者)不用特定来什么创建某一种具体的类,也不依赖于特定的类,而且依赖接口或者抽象类,这样就达到了解耦,专业点的说法就是“依赖倒置”,更加直白的说法就是:客户程序可以使用很多不同的实现类,而保持代码不变。因为在需要的时候,传入一些信息,Factory Methods就返回接口或者抽象类的实现类。
 
         很多情况下,我们一般是这样来使用Factory Method模式的:建立一个Factory类,这个类有一个静态的方法,这个方法返回一个抽象的类或者接口。然后,客户程序(或者调用程序)就传入一些信息给Factory类来,要求Factory来创建相对应,需要的具体的实现类。
 
         下面我们就看看一个Factory MethodUML图:
 
 
 
   在图中,可以得出以下几点信息:
Client类通过Factory类来获取实现了IProduct的具体子类。
Client类依赖IProduct接口,而不是依赖具体的子类。
Factory类复杂创建具体的子类,向Client隐藏具体的细节。
 
  
    现在网上购物已经很流行了,在选择支付方式的时候,一般有几种选择,比如:网银支付,货到付款支付等。对于网银支付,又可以进一步细分为:中国银行支付、工商银行支付等。不同的银行支付,最后调用的接口都不一样,而且以后系统可能会支持更多的银行。所以在设计支付功能的时候需要考虑到扩展性。本例将会介绍如何采用工厂方法模式来实现支付功能。
 
   请看下图:
 
         
  下面我们就通过代码来讲述:(大家可以一起动手)  
     IPayment支付方式的接口代码如下所示:
 
public interface IPayment
{
      bool Payfor(decimal money);
}
 
支付实现者ABCPayment支付类的代码如下所示:
 
public class ABCPayment:IPayment
  {
        public bool Payfor(decimal money)
        {
           //调用中国农业银行提供的支付接口进行支付
            return true;
        }
   }
       ICBCPaymentAOCPayment的实现同理。
       PaymentFactory的任务就是根据传入的条件来创建不同的具体支付者:
 
public class PaymentFactory
{
        public static IPayment CreatePayment(string bank)
        {
            IPayment result = null;
            switch (bank)
            {
                case "ABC":
                    result = new ABCPayment();
                    break;
                case "ICBC":
                    result = new ICBCPayment();
                    break;
            }
            return result;
        }
}
 
      当然,可以采用更好的方式来实现PaymentFactoryCreatePayment方法,例如采用配置文件,动态加载程序集的方式。
    Decorator
  
        为了更好地理解“装饰”的概念,我们首先抛开枯燥的阐述,来看看现在流行的网游。在网游中玩家可以给自己的账号购买不同的装备,而且不同的装备其特性也不一样,比如重量、防御能力、攻击能力等。下面就以装备中的铠甲为引子来讲述“装饰”。
       下面,我们就看看如何实现铠甲的升级功能:从最初的青铜甲一步步升级到麒麟甲。
 
        其中:
Knight:代表武将。
IArmour:铠甲接口。QTArmour为青铜铠甲,BLGJArmour为百炼钢甲,QLArmour为麒麟甲。
        每次铠甲升级,都是通过工厂武将创建新的铠甲子类替换原来的铠甲。
 
        如果以后有新的铠甲或要对现有的铠甲功能进行增强,可以采用继承的方式实现。例如现在麒麟铠甲要增加隐形功能,本着“开放关闭原则”,最容易想到的就是添加一个新的子类,从QLArmour(青铜铠甲)继承现有的功能,同时再加上新的功能。如果再要新加上其他功能,其步骤也与此类似,原本就想通过继承来重用现有的代码,现在这个目的达到了,但是最后系统中存在了很多的功能相近的类,导致类的数目急剧膨胀。
       如果能够在现有铠甲上面通过不断的改造,增加新的功能,类似于变形金刚变身那样,使加入了新功能的青铜甲铠甲演变成麒麟甲,成为新类型的铠甲,那么类的数目就不会像之前那样膨胀了。     
       网游的例子到此暂告一个段落,主要就是想让大家了解一下“装饰”的含义,至于如何实现,在讲完下面的例子之后大家就清楚了。
要遵循“开放关闭”原则,同时又要规避使用继承带来的类膨胀问题,如何实现?装饰者模式回答了这个问题。
 
 
    如图,先不管图中类名的定义,首先看看主要类的含义:
         (1 OnlineSitePriceDecorator代表购物站点的打折。
         (2 SupplierPriceDecorator代表供应商的打折。
         (3 PolicyPriceDecorator代表政府要求的打折。
 
      在打折的时候,需要考虑:打折就是改变产品的价格,而很多时候,价格往往只是产品的一个属性,例如,通常会采用decimal等数据类型。
      现在因为价格总是在不断地根据打折算法的变换而变化,那么现在“价格”就成了一个变化点;另一方面,更加准确的说:打折算法是用在价格之上的,这样才能实现对产品的打折。考虑把价格这个变化点引出去,成为一个业务实体Price,然后把打折算法都累积在这个实体上面进行,产品类Product丝毫不知道Price类是否应用了打折算法,只管引用Price获取最后的价格。
 
  public interface IPrice
   {
        decimal Cost { getset; }
   }

public class Product
    {
        public string Name { getset; }
        public IPrice Price { getset; }
    }
 
下面,开始添加不同打折算法的实现。
    首先我们来回想一下之前装备升级的例子,我们是希望通过不断地改造青铜甲,在原有的基础上加上新的功能,最后达到装备升级的目的。此时,在价格打折上面,因为同时要采用很多的打折算法,也类似于给价格不断的“升级”:在原有的价格上不断进行包装。所以OnlineSitePriceDecorator购物网站推出的打折方法如下:
 
public class OnlineSitePriceDecorator : IPrice
{
        private IPrice price;

        public OnlineSitePriceDecorator(IPrice price)
        {
            this.price = price;
        }

        public decimal Cost
        {
            get
            {
                return price.Cost * 0.9M;
            }
            set
            {
                price.Cost = value;
            }
        }
}
 
    从上面的代码中我们可以看出,拿到商品的原价后进行包装:proce.Cost*0.9M。在经过OnlineSitePriceDecorator包装之后把价格抛出来,进行下一个包装:供应商打折。供应商打折的代码如下所示:
 
public class SupplierPriceDecorator : IPrice
{
        private IPrice price;

        public SupplierPriceDecorator(IPrice price)
        {
            this.price = price;
        }

        public decimal Cost
        {
            get
            {
                return price.Cost * 0.85M;
            }
            set
            {
                price.Cost = value;
            }
        }
}
 
下面看看如何实现累积打折算法,代码如下:
 
public class ProductService
{
        private IProductRepository productRepository;

        public ProductService(IProductRepository productRepository)
        {
            this.productRepository = productRepository;
        }

        public List<Product> GetProducts()
        {
            var products = productRepository.GetAllProduct();
            products.ApplyDiscount();
            return products;
        }
}

//其中ApplyDiscount为List的扩展方法,如下所示:
public static class DiscountExtension
{
        public static List<Product> ApplyDiscount(this List<Product> products)
        {
            if (products != null && products.Count > 0)
            {
                foreach (var product in products)
                {
                    product.Price = new OnlineSitePriceDecorator(product.Price);
                    product.Price = new SupplierPriceDecorator(product.Price);
                    product.Price = new PolicyPriceDecorator(product.Price, 0.88M);
                }
          }
            return products;
        }
 
价格包装的过程如图所示。
 
  以上就是本篇的内容,讲述的很粗略,希望见谅,还没有写完,待续!

















本文转自yanyangtian51CTO博客,原文链接:
http://blog.51cto.com/yanyangtian/427127
 ,如需转载请自行联系原作者




















相关文章
|
14天前
|
Kubernetes 安全 Java
构建高效微服务架构:从理论到实践
【4月更文挑战第9天】 在当今快速迭代与竞争激烈的软件市场中,微服务架构以其灵活性、可扩展性及容错性,成为众多企业转型的首选。本文将深入探讨如何从零开始构建一个高效的微服务系统,覆盖从概念理解、设计原则、技术选型到部署维护的各个阶段。通过实际案例分析与最佳实践分享,旨在为后端工程师提供一套全面的微服务构建指南,帮助读者在面对复杂系统设计时能够做出明智的决策,并提升系统的可靠性与维护效率。
|
7天前
|
消息中间件 运维 监控
现代化软件开发中的微服务架构设计与实践
本文将深入探讨现代化软件开发中微服务架构的设计原则和实践经验。通过分析微服务架构的优势、挑战以及常见的设计模式,结合实际案例,帮助开发者更好地理解如何构建可靠、可扩展、高效的微服务系统。
|
7天前
|
负载均衡 Java 开发者
细解微服务架构实践:如何使用Spring Cloud进行Java微服务治理
【4月更文挑战第17天】Spring Cloud是Java微服务治理的首选框架,整合了Eureka(服务发现)、Ribbon(客户端负载均衡)、Hystrix(熔断器)、Zuul(API网关)和Config Server(配置中心)。通过Eureka实现服务注册与发现,Ribbon提供负载均衡,Hystrix实现熔断保护,Zuul作为API网关,Config Server集中管理配置。理解并运用Spring Cloud进行微服务治理是现代Java开发者的关键技能。
|
8天前
|
敏捷开发 监控 前端开发
深入理解自动化测试框架Selenium的架构与实践
【4月更文挑战第16天】 在现代软件开发过程中,自动化测试已成为确保产品质量和加快迭代速度的关键手段。Selenium作为一种广泛使用的自动化测试工具,其开源、跨平台的特性使得它成为业界的首选之一。本文旨在剖析Selenium的核心架构,并结合实际案例探讨其在复杂Web应用测试中的高效实践方法。通过详细解读Selenium组件间的交互机制以及如何优化测试脚本,我们希望为读者提供深入理解Selenium并有效运用于日常测试工作的参考。
14 1
|
11天前
|
Linux 数据安全/隐私保护
Linux基础与服务器架构综合小实践
【4月更文挑战第9天】Linux基础与服务器架构综合小实践
1234 8
|
13天前
|
存储 人工智能 架构师
数据库架构模式:分片
本文介绍了数据库分片的概念,以及各自的使用场景,分片可提升可扩展性、性能和高可用性。
|
17天前
|
前端开发 安全 JavaScript
计算机软件从 CS 模式到 BS 架构迁移背后的动因
计算机软件从 CS 模式到 BS 架构迁移背后的动因
21 0
|
20天前
|
消息中间件 监控 API
构建高性能微服务架构:从理论到实践
【4月更文挑战第4天】 在当今互联网应用的快速迭代和高并发需求下,传统的单体应用架构已不足以满足市场的灵活性与扩展性要求。微服务架构以其独立部署、弹性伸缩、技术多样性等优势,成为众多企业转型升级的首选方案。本文将深入探讨如何构建一个高性能的微服务系统,涵盖关键组件的选择、系统设计的考量以及性能优化的策略,旨在为开发者和架构师提供一套实用的指导思路和具体实践步骤。
|
22天前
|
消息中间件 安全 API
构建高效微服务架构:策略与实践
【4月更文挑战第1天】在数字化转型的浪潮中,微服务架构已成为企业追求敏捷、可扩展和灵活部署的重要技术手段。本文将深入探讨如何通过合理的设计原则和先进的技术栈,构建一个高效的微服务系统。我们将剖析微服务设计的核心要点,包括服务的划分、通信机制、数据一致性以及安全性问题,并结合案例分析,展示如何在现实世界中应用这些策略以提升系统的可靠性和性能。
|
23天前
|
设计模式 API 持续交付
构建高效微服务架构:从理论到实践
在当今快速迭代和部署的软件开发环境中,微服务架构已成为一种流行的设计模式,它允许开发团队以模块化的方式构建、维护和扩展应用程序。本文将深入探讨微服务的核心概念,包括其定义、优势、挑战以及如何在实际项目中实施。我们将通过一个实际案例来展示如何将传统的单体应用拆分成一系列独立、松耦合的服务,并通过容器化、服务发现、API网关和持续集成/持续部署(CI/CD)等技术手段来管理这些服务。