引入契约式设计

概念:本文中的”引入契约式设计”是指我们应该对应该对输入和输出进行验证,以确保系统不会出现我们所想象不到的异常和得不到我们想要的结果。

正文:契约式设计规定方法应该对输入和输出进行验证,这样你便可以保证你得到的数据是可以工作的,一切都是按预期进行的,如果不是按预期进行,异常或是错误就应该被返回,下面我们举的例子中,我们方法中的参数可能会值为null的情况,在这种情况下由于我们没有验证,NullReferenceException异常会报出。另外在方法的结尾处我们也没有保证会返回一个正确的decimal值给调用方法的对象。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LosTechies.DaysOfRefactoring.SampleCode.Day25_DesignByContract
{
    public class CashRegister
    {
        public decimal TotalOrder(IEnumerable<Product> products, Customer customer)
        {
            decimal orderTotal = products.Sum(product => product.Price);

            customer.Balance += orderTotal;

            return orderTotal;
        }
    }
}

对上面的代码重构是很简单的,首先我们处理不会有一个null值的customer对象,检查我们最少会有一个product对象。在返回订单总和之前先确保我们会返回一个有意义的值。如果上面说的检查有任何一个失败,我们就抛出对应的异常,并在异常里说明错误的详细信息,而不是直接抛出NullReferenceException。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Contracts;

namespace LosTechies.DaysOfRefactoring.SampleCode.DesignByContract.After
{
    public class CashRegister
    {
        public decimal TotalOrder(IEnumerable<Product> products, Customer customer)
        {
            if (customer == null)
                throw new ArgumentNullException("customer", "Customer cannot be null");
            if (products.Count() == 0)
                throw new ArgumentException("Must have at least one product to total", "products");

            decimal orderTotal = products.Sum(product => product.Price);

            customer.Balance += orderTotal;

            if (orderTotal == 0)
                throw new ArgumentOutOfRangeException("orderTotal", "Order Total should not be zero");

            return orderTotal;
        }
    }
}

上面的代码中添加了额外的代码来进行验证,虽然看起来代码复杂度增加了,但我认为这是非常值得做的,因为当NullReferenceException发生时去追查异常的详细信息真是很令人讨厌的事情。

总结:微软在处理代码乃至产品的时候,很喜欢应用此重构,你如果认真看它的代码库,认真看一下WCF的设计,就不难发现了。这个重构建议大家经常使用,这会增强整个系统的稳定性和健壮性。

版权声明:本文为博主http://www.zuiniusn.com 原创文章,未经博主允许不得转载。

时间: 2024-10-16 05:03:46

引入契约式设计的相关文章

小酌重构系列[16]&mdash;&mdash;引入契约式设计

概述 试想这样一个场景,你提供了一些API给客户端调用,客户端传入了一些参数,然后根据这些参数执行了API逻辑,最终返回一个结果给客户端. 在这个场景中,有两个隐患,它们分别是: 客户端调用API时,传入的参数是否准确,参数是否满足API的执行前提 API逻辑执行完时,返回的结果是否准确,结果是否符合客户端的预期 这两个隐患都和"准确性"相关的,API要求(Require)传入的参数是否准确,它也要确保(Ensure)返回的结果是否准确.软件的准确性决定了软件的可靠性.通俗地讲,即用户

6.3 契约式设计

3.契约式设计 Design by Contract ? 可信软件设计的基础思想 ? 谚语: When ideas fail, words come in very handy ! 他人译文“殚思竭虑之时,文字将成为利器” 本人认为“当想法失败时,总会出来许多理由辩解”3.1 问题的引入 由谁负责系统的可靠性?3.2 Contract (契约) History ? Tony Hoare,把“操作契约 Operation contract”引入了计算机科学的 “形式化规范说明formal spec

契约式设计(DbC)感想(二)

契约式设计6大原则的理解 在<Design by Contract原则与实践>中,作者定义了契约式设计的6大原则: 区分命令和查询: 将基本查询和派生查询区分开: 针对每个派生查询,设定一个后验条件,使用一个或多个基本查询的结果来定义它: 对于每个命令都撰写一个后验条件,规定每个基本查询的值: 对于每个查询和命令,采用一个合适的先验条件: 撰写不变式来定义对象的恒定特性. 前面5个针对operation层面而言,不论是面向对象也好,面向过程也好,函数式也好,都可以适用.最后1个针对data层面

契约式设计(DbC)感想

契约式设计可以理解为正则编程的一种实践: 如果用我的三脚猫能力将这种实践方法形式化的话,大致如下(如有不正确处,请不吝指正): 1.对于方法Method的precondition & postcondition: Function(RegularMthod) = ^ RegularFunction ^ General-Class-Method ^ Assert(precondition) ^ Assert(postcondition); => f1( f2 ) { f1, f2 : Regu

PHP 面向对象程序设计(oop)学习笔记(一) - 抽象类、对象接口、instanceof 和契约式编程

1.PHP中的抽象类 PHP 5 支持抽象类和抽象方法.定义为抽象的类不能被实例化.任何一个类,如果它里面至少有一个方法是被声明为抽象的,那么这个类就必须被声明为抽象的.被定义为抽象的方法只是声明了其调用方式(参数),不能定义其具体的功能实现.在类的声明中使用 abstract 修饰符可以将某个类声明为抽象的. 可以这样理解,抽象类作为一个基类,它把特定的细节留给继承者来实现.通过抽象概念,可以在开发项目中创建扩展性很好的架构. abstract class AbstractClass{   

.NET 4.0 中的契约式编程

契约式编程不是一门崭新的编程方法论.C/C++ 时代早已有之.Microsoft 在 .NET 4.0 中正式引入契约式编程库.博主以为契约式编程是一种相当不错的编程思想,每一个开发人员都应该掌握.它不但可以使开发人员的思维更清晰,而且对于提高程序性能很有帮助.值得一提的是,它对于并行程序设计也有莫大的益处. 我们先看一段很简单的,未使用契约式编程的代码示例. // .NET 代码示例 public class RationalNumber { private int numberator; p

响应式设计三部曲

随着智能手机的流行,响应式网页设计无疑成为了如今网页设计的大趋势.对于新手来时,响应设计听起来有点复杂,但它实际上是比你想象的更简单.只需下面的3个步骤即可构建一个响应式的网页! 1.Meta Tag 大多数移动浏览器扩展的HTML页面到宽视口宽度,以便在屏幕上适合.您可以使用viewport meta标签来重设此.下面的视口标签告诉使用该设备的宽度视口宽度和禁用初始规模浏览器. <meta name="viewport" content="width=device-w

响应式设计(一)

一.响应式设计(一)响应式设计初识,一个小小的demo,用来理解什么是响应式 今天的一个小小的demo,让我重新的认识了什么是响应式网页设计.我之前一直以为主要一个网页在不同的设备上浏览,网页可以自适应设备的屏幕大小,而不发生结构变形. 其实我觉得更准确去说是:根据不同的用户设备环境,页面可以做出不同的响应动作, 例如:在pc端浏览一行图片,看到的个数是4个,用手机看到的是2个图片,不同用户的设备环境,做出了不同的响应动作. 二.百度百科给出的概念: 响应式Web设计(Responsive We

响应式设计与自适应设计

响应式设计与自适应设计 相信从事前端页面设计的人都知道,页面呈现的效果及用户体验是非常重要的.当今社会移动设备的使用已超过了pc端,面对不同分辨率的设备,怎样做到页面体验的效果一样呢?这就成了最头疼的事情. 下面我们来看看响应式设计与自适应设计两者用法: 响应式Web设计(Responsive Web Design) :主要利用CSS3的媒介查询(Media Query)和Viewport来解决问题.通过媒介查询的设置,根据屏幕宽度.屏幕方向等各个属性来加载不同场景下不同的CSS文件来渲染页面的