摘要: LINQ,语言集成查询(Language INtegrated Query)是一组用于c#和Visual Basic语言的扩展。它允许编写C#或者Visual Basic代码以查询数据库相同的方式操作内存数据。从技术角度而言,LINQ定义了大约40个查询操作符,如select、from、in、where以及order by(C#中)。使用这些操作符可以编写查询语句。不过,这些查询还可以基于很多类型的数据,每个数据类型都需要一个单独的LINQ类型。看图,不解释 阅读全文
posted @ 2013-02-05 13:35 于为 阅读(185) 评论(0) 推荐(0) 编辑
摘要: 划分职责:根据方法实现的逻辑来安排方法所在的类。 举例理解:这个重构的方法是对单一职责原则(SRP)的贯彻,在Coding的时候,我们不仅仅需要把方法中的逻辑单一化(主要使用 Extract Method),还要把类中的方法安置合理化。比如说有个Book()的类,那么对于Book的一些操作,如增加减少书,设置书的属性那可以交给这个类做;而如另一些方法,如买书,租书就可以交给Custom()的类来处理,因为买书,租书的逻辑主体都是Custom。 项目实例:就个人而言,这个重构方法我觉得大家在Coding的时候都会注意到,因为谁都会把相关的方法放在一个类中;唯一可能出现的问题就是出现大神类(G.. 阅读全文
posted @ 2013-02-05 10:48 于为 阅读(191) 评论(0) 推荐(0) 编辑
摘要: 提取工厂类:使用一个简单工厂类来新建对象实例。 举例理解:对于一个客户端事件,我们可能需要初始化一个对象实例,并调用其中的几个方法做一系列的操作。如果客户端事件经常需要扩展,那可能每次初始化的对象实例可能都是不同的,那么为了把这个初始化对象的动作封装起来,为了使这个行为更加便于维护,我们就需要把初始化对象的动作交给简单工厂类来统一完成。 项目实例:做过一个小型的购物商城。其中有个需求简述如下:管理员可以通过后台自助增删改当前商品的打折比例和打折类型。一开始我们想的都很简单,以为用户仅仅是打折而已,OK,加个下拉列表然后里面放上1-9折就行了,然后售价X这个折数就好了。想不到设计好后,当时就.. 阅读全文
posted @ 2013-02-05 10:46 于为 阅读(222) 评论(0) 推荐(0) 编辑
摘要: 提取接口:当有多余一个类使用另外一个类中的方法时,可以考虑引入接口,解除这种依赖。 举例理解:比如说类A中有个方法为Call(Type T),类B和类C中都有方法都要调用Call这个方法,那么我们推荐引入一个接口,这样传参时可以直接new一个接口,可以解除调用方法和实现方法之间的耦合关系。面向接口编程也算是OO中比较重要的吧。 项目实例:一般而言在设计的时候,对于比较可能扩展的部分都会用接口或者是抽象方法来处理,对于接口,个人并不是很喜欢,因为接口写好了要修改就很困难,只能再加新的接口,这对设计的要求很高,抽象方法相对好用点。下面的代码扩展于原文的Demo Code,希望可以讲得稍微详细点.. 阅读全文
posted @ 2013-02-05 10:34 于为 阅读(609) 评论(0) 推荐(0) 编辑
摘要: 使用多态替换条件:指在进行类型检查和执行某些类型操作时,最好将算法封装在类中,并且使用多态来对代码中的调用进行抽象 举例理解:看定义可能比较迷糊,其实说的简单一点,对于使用分支语句并且分支条件是和类型检查相关的程序段,如 if(type == typeof(TypeA)){...}else if(type == typeof(TypeB)){...},可以把{...}中的Code,尝试放到if的条件中去。然后通过检查Type就可以直接返回需要的东东了,这样做可以利用已有的继承层次进行计算,比较便于维护。如果还是觉得说的太抽象,可以看看下面的代码感觉一下。 项目实例:用WPF做一个网游的客户.. 阅读全文
posted @ 2013-02-05 10:30 于为 阅读(369) 评论(0) 推荐(0) 编辑
摘要: 封装集合:将集合中的某些方法封装起来,这些方法一般会牵扯到其他的逻辑。 举例理解:比如你给一个List<T>里面加一个对象的同时,可能还有一个计数器在计算List中对象的个数,我们不用暴露计数器,这样List.Add()和List.Remove()我们就可以封装起来了。 项目实例:我记得我有个项目需要不断的从数据库中读取User的Guid然后狂发Mail。开始的想法很简单,根据Window ID 去 CorpDirectory 抓Guid和Mail Address就好了。实际情况也就这么简单,但是后来Debug的时候发现程序很慢,弄了半天终于发现是这个抓Guid和Mail的动作太慢 阅读全文
posted @ 2013-02-05 10:25 于为 阅读(253) 评论(0) 推荐(0) 编辑
摘要: 5.提取主类:提取一个基类,抽象出共有方法,比较常用的重构,这里的基类也许并不存在,需要自己新建立。 用法场景:当有一个类中的某个方法需要经常被其他的类调用的时候,说明这个方法重用率很高,可以考虑把它抽象出来,放到一个基类中。//重构前publicclass Dog{ publicvoid EatFood() { // eat some food } publicvoid Groom() { // perform grooming }}//重构后publicclass Animal{ ... 阅读全文
posted @ 2013-02-05 10:21 于为 阅读(124) 评论(0) 推荐(0) 编辑
摘要: 本文主要讲几个涉及到继承方面的重构,继承一般会涉及到抽象类,接口,我们通常把有相似Func的类提取同类项,也就是抽象出接口或者抽象类;这样做的好处不言而喻,可以方便的扩展,修改,维护子类的共有方法,属性,索引等等。使用基类不仅仅是把各个子类联系起来了,更是降低了各个子类间的耦合度,再次体现了面向接口、继承编程的思想。 1.提升方法:指将方法向继承链的上层迁移的过程。 用法场景:当子类A中的一个方法需要被多个子类调用的时候,需要把这个方法提升到基类中,而不能让其它的子类都去Call子类A中的这个方法。这样做唯一的缺点是扩充了基类的接口、增加了其复杂性,因此需谨慎使用。只有当一个以上的子类需... 阅读全文
posted @ 2013-02-05 10:17 于为 阅读(173) 评论(0) 推荐(0) 编辑
摘要: 概念:本文中的”使用多态代替条件判断”是指如果你需要检查对象的类型或者根据类型执行一些操作时,一种很好的办法就是将算法封装到类中,并利用多态性进行抽象调用。正文:本文展示了面向对象编程的基础之一“多态性”, 有时你需要检查对象的类型或者根据类型执行一些操作时,一种很好的办法就是将算法封装到类中,并利用多态性进行抽象调用。如下代码所示,OrderProcessor类的ProcessOrder方法根据Customer的类型分别执行一些操作,正如上面所讲的那样,我们最好将OrderProcessor类中这些算法(数据或操作)封装在特定的Customer 子类中。using System;using 阅读全文
posted @ 2013-02-05 10:15 于为 阅读(215) 评论(0) 推荐(0) 编辑
摘要: 概念: 本文中的”尽快返回”是指把原来复杂的条件判断等语句用尽快返回的方式简化代码。正文:如首先声明的是前面讲的”分解复杂判断“,简单的来说,当你的代码中有很深的嵌套条件时,花括号就会在代码中形成一个长长的箭头。我们经常在不同的代码中看到这种情况,并且这种情况也会扰乱代码的可读性。下代码所示,HasAccess方法里面包含一些嵌套条件,如果再加一些条件或者增加复杂度,那么代码就很可能出现几个问题:1,可读性差 2,很容易出现异常 3,性能较差using System.Collections.Generic;using System.Linq;using LosTechies.DaysOfRef 阅读全文
posted @ 2013-02-05 10:14 于为 阅读(218) 评论(0) 推荐(0) 编辑
摘要: 概念:本文中的”去除中间人对象”是指把 在中间关联而不起任何其他作用的类移除,让有关系的两个类直接进行交互。正文:有些时候在我们的代码会存在一些”幽灵类“,设计模式大师Fowler称它们为“中间人”类,“中间人”类除了调用别的对象之外不做任何事情,所以“中间人”类没有存在的必要,我们可以将它们从代码中删除,从而让交互的两个类直接关联。如下代码所示,Consumer类要得到AccountDataProvider的数据,但中间介入了没起任何作用的AccountManager类来关联,所以我们应当移除。using LosTechies.DaysOfRefactoring.PullUpField.Af 阅读全文
posted @ 2013-02-05 10:13 于为 阅读(181) 评论(0) 推荐(0) 编辑
摘要: 概念:本文中的”为布尔方法命名”是指如果一个方法带有大量的bool参数时,可以根据bool参数的数量,提取出若干个独立的方法来简化参数。正文:我们现在要说的重构并不是普通字面意义上的重构,它有很多值得讨论的地方。当一个方法带有大量的bool参数时,会导致方法很容易被误解并产生非预期的行为,根据布尔型参数的数量,我们可以决定提取出若干个独立的方法来。具体代码如下:using LosTechies.DaysOfRefactoring.BreakResponsibilities.After;namespace LosTechies.DaysOfRefactoring.SampleCode.Renam 阅读全文
posted @ 2013-02-05 10:12 于为 阅读(187) 评论(0) 推荐(0) 编辑
摘要: 概念:本文中的”去除上帝类”是指把一个看似功能很强且很难维护的类,按照职责把自己的属性或方法分派到各自的类中或分解成功能明确的类,从而去掉上帝类。正文:我们经常可以在一些原来的代码中见到一些类明确违反了SRP原则(单一原则),这些类通常以“Utils”或“Manager”后缀结尾,但有时这些类也没有这些特征,它仅仅是多个类多个方法的组合。另一个关于上帝类的特征是通常这些类中的方法被用注释分隔为不同的分组。那么久而久之,这些类被转换为那些没有人愿意进行归并到合适类的方法的聚集地,对这些类进行重构是将类中的代码按照职责分派到各自的类中,这样就解除了上帝类,也减轻了维护的负担。using Syste 阅读全文
posted @ 2013-02-05 10:11 于为 阅读(181) 评论(0) 推荐(0) 编辑
摘要: 概念:本文中的”避免双重否定”是指把代码中的双重否定语句修改成简单的肯定语句,这样即让代码可读,同时也给维护带来了方便。正文:避免双重否定重构本身非常容易实现,但我们却在太多的代码中见过因为双重否定降低了代码的可读性以致于非常让人容易误解真正意图。存在双重否定的代码具有非常大的危害性,因为这种类型的代码容易引起错误的假设,错误的假设又会导致书写出错误的维护代码,最终会导致bug产生。具体可以看下面的代码:using System.Collections.Generic;using LosTechies.DaysOfRefactoring.SampleCode.BreakMethod.Aft.. 阅读全文
posted @ 2013-02-05 10:10 于为 阅读(196) 评论(0) 推荐(0) 编辑
摘要: 概念:本文中的”引入契约式设计”是指我们应该对应该对输入和输出进行验证,以确保系统不会出现我们所想象不到的异常和得不到我们想要的结果。正文:契约式设计规定方法应该对输入和输出进行验证,这样你便可以保证你得到的数据是可以工作的,一切都是按预期进行的,如果不是按预期进行,异常或是错误就应该被返回,下面我们举的例子中,我们方法中的参数可能会值为null的情况,在这种情况下由于我们没有验证,NullReferenceException异常会报出。另外在方法的结尾处我们也没有保证会返回一个正确的decimal值给调用方法的对象。using System;using System.Collections. 阅读全文
posted @ 2013-02-05 10:09 于为 阅读(147) 评论(0) 推荐(0) 编辑
摘要: 概念:本文中的”分解复杂判断”是指把原来复杂的条件判断等语句用尽快返回等方式简化代码。正文:简单的来说,当你的代码中有很深的嵌套条件时,花括号就会在代码中形成一个长长的箭头。我们经常在不同的代码中看到这种情况,并且这种情况也会扰乱代码的可读性。如下代码所示,HasAccess方法里面包含一些嵌套条件,如果再加一些条件或者增加复杂度,那么代码就很可能出现几个问题:1,可读性差。 2,很容易出现异常。 3,性能较差。using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace 阅读全文
posted @ 2013-02-05 10:08 于为 阅读(235) 评论(0) 推荐(0) 编辑
摘要: 概念:本文中的“引入参数对象”是指当一个方法的参数过多或者过为复杂时,可以考虑把这些参数封装成一个单独的类。正文:如果一个方法所需要的参数大于5个,理解该方法的签名就变得比较困难,因为这样感觉参数很长、样式不好并且没有分类,所以我们有必要把参数进行封装。namespace LosTechies.DaysOfRefactoring.SampleCode.ParameterObject.Before{ public class Registration { public void Create(decimal amount, Student student, IEnume... 阅读全文
posted @ 2013-02-05 10:07 于为 阅读(313) 评论(0) 推荐(0) 编辑
摘要: 概念:本文中的”分解方法”是指把我们所做的这个功能不停的分解方法,直到将一个大方法分解为名字有意义且可读性更好的若干个小方法。正文:如下代码所示,因为现实中AcceptPayment方法不会做这么多的事情。,所以我们通过几次分解将 AcceptPayment拆分成若干个名字有意义且可读性更好的小方法。using System.Collections.Generic;using System.Linq;namespace LosTechies.DaysOfRefactoring.SampleCode.BreakMethod.Before{ public class CashRegister... 阅读全文
posted @ 2013-02-05 10:06 于为 阅读(228) 评论(0) 推荐(0) 编辑
摘要: 概念:本文中的”合并继承”是指如果子类的属性和方法也适合于基类,那么就可以移除子类,从而减少依赖关系。正文:上一篇我们讲到“提取子类”重构是指当基类中的一个责任不被所有的子类所需要时,将这些责任提取到合适的子类中。而我们今天所要讲的的“合并继承”重构一般用在当我们觉得不需要子类的时候。如下代码所示,StudentWebSite子类除了有一个属性用来说明网站是否是活动的外没有别的责任,在这种情形下我们意识到IsActive属性可以应用到所有的网站,所以我们可以将IsActive属性上移到基类中,并去掉StudentWebSite类。using System.Collections.Generic 阅读全文
posted @ 2013-02-05 10:05 于为 阅读(188) 评论(0) 推荐(0) 编辑
摘要: 概念:本文中的”提取子类”是指把基类中的一些不是所有子类都需要访问的方法调整到子类中。正文:当你的基类中存在一些方法不是所有的子类都需要访问,你想将它们调整到子类中时,这个重构会变得很有用了。如下代码所示,我们需要一个 Registration类用来处理学生选课的信息。但是当Registration类开始工作后,我们意识到我们会在两种不同的上下文中使用Registration类,NonRegistrationAction和Notes只有在我们处理未注册情况下才用到。所以我们将NonRegistration和Notes提到单独的NonRegistration类中。using System;nam 阅读全文
posted @ 2013-02-05 10:04 于为 阅读(196) 评论(0) 推荐(0) 编辑