首页 31天重构学习系列-中文

31天重构学习系列-中文

举报
开通vip

31天重构学习系列-中文概念:本文所讲的封装集合就是把集合进行封装,只提供调用端需要的接口 31 天重构学习笔记1. 封装集合 概念:本文所讲的封装集合就是把集合进行封装,只提供调用端需要的接口。 正文:在很多时候,我们都不希望把一些不必要的操作暴露给调用端,只需要给它所需要的操作或数据就行,那么做法就是封装。这个重构在 微软的代码库也经常遇到。比如最经典的属性对字段的封装就是一个很好的例子,那么下面我们将看到对集合的封装,如下代码所示,调用端只需要一个集合的信 息,而我们则提供了一个IList的集合,大家都知道IList具有对集合的所有...

31天重构学习系列-中文
概念:本文所讲的封装集合就是把集合进行封装,只提供调用端需要的接口 31 天重构学习笔记1. 封装集合 概念:本文所讲的封装集合就是把集合进行封装,只提供调用端需要的接口。 正文:在很多时候,我们都不希望把一些不必要的操作暴露给调用端,只需要给它所需要的操作或数据就行,那么做法就是封装。这个重构在 微软的代码库也经常遇到。比如最经典的属性对字段的封装就是一个很好的例子,那么下面我们将看到对集合的封装,如下代码所示,调用端只需要一个集合的信 息,而我们则提供了一个IList的集合,大家都知道IList具有对集合的所有操作,所以这会带来很多隐患,最好的 做法就是对它进行重构。 using System.Collections.Generic; namespace LosTechies.DaysOfRefactoring.EncapsulateCollection.Before { public class Order { private List _orderLines; private double _orderTotal; public IList OrderLines { get { return _orderLines; } } public void AddOrderLine(OrderLine orderLine) { _orderTotal += orderLine.Total; _orderLines.Add(orderLine); } public void RemoveOrderLine(OrderLine orderLine) { orderLine = _orderLines.Find(o => o == orderLine); if (orderLine == null) return; _orderTotal -= orderLine.Total; _orderLines.Remove(orderLine); } } public class OrderLine { public double Total { get; private set; } } }   那么重构之后,我们把IList换成了IEnumerable,大家都知道只包括一个返回值为 IEnumerator的GetEnumerator()方法,所以这样只能遍历取出它的值,而不能对这个集合做出改变,这正是我们所需要的结果,具体代 码如下: using System.Collections.Generic; namespace LosTechies.DaysOfRefactoring.EncapsulateCollection.After { public class Order { private List _orderLines; private double _orderTotal; public IEnumerable OrderLines { get { return _orderLines; } } public void AddOrderLine(OrderLine orderLine) { _orderTotal += orderLine.Total; _orderLines.Add(orderLine); } public void RemoveOrderLine(OrderLine orderLine) { orderLine = _orderLines.Find(o => o == orderLine); if (orderLine == null) return; _orderTotal -= orderLine.Total; _orderLines.Remove(orderLine); } } public class OrderLine { public double Total { get; private set; } } }   总结 初级经济法重点总结下载党员个人总结TXt高中句型全总结.doc高中句型全总结.doc理论力学知识点总结pdf :这个例子很容易让我们想到以前系统间耦合常喜欢用数据库。每个系统都会操作数据库,并且有些系统还会对数据库的 关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf 结构或字段进 行修改,那么这很容易就会造成维护的地狱,很明智的一个做法就是使用SOA来隔开这些耦合,让一些只需要数据展示的系统得到自己需要的数据即可。 31 天重构学习笔记2. 移动方法 概念:本文所讲的移动方法就是方法放在合适的位置(通常指放在合适的类中)。   正文:移动方法是一个很简单也很常见的重构,只要是系统就会存在很多类,那么类里面包括很多方法,如果一个方法经常被另外一个类使用 (比本身的类使用还多)或者这个方法本身就不应该放在这个类里面,那么这个适合应该考虑把它移到合适的类中。代码如下: namespace LosTechies.DaysOfRefactoring.MoveMethod.Before { public class BankAccount { public BankAccount(int accountAge, int creditScore, AccountInterest accountInterest) { AccountAge = accountAge; CreditScore = creditScore; AccountInterest = accountInterest; } public int AccountAge { get; private set; } public int CreditScore { get; private set; } public AccountInterest AccountInterest { get; private set; } public double CalculateInterestRate() { if (CreditScore > 800) return 0.02; if (AccountAge > 10) return 0.03; return 0.05; } } public class AccountInterest { public BankAccount Account { get; private set; } public AccountInterest(BankAccount account) { Account = account; } public double InterestRate { get { return Account.CalculateInterestRate(); } } public bool IntroductoryRate { get { return Account.CalculateInterestRate() < 0.05; } } } }   移动以后大家可以看到BankAccount类的职责也单一,同时CalculateInterestRate也放到了经常使用且适合它的类中了,所以此重构是一个比较好的重构,能让整个代码变得更加合理。 namespace LosTechies.DaysOfRefactoring.MoveMethod.After { public class AccountInterest { public BankAccount Account { get; private set; } public AccountInterest(BankAccount account) { Account = account; } public double InterestRate { get { return CalculateInterestRate(); } } public bool IntroductoryRate { get { return CalculateInterestRate() < 0.05; } } public double CalculateInterestRate() { if (Account.CreditScore > 800) return 0.02; if (Account.AccountAge > 10) return 0.03; return 0.05; } } }   namespace LosTechies.DaysOfRefactoring.MoveMethod.After { public class BankAccount { public BankAccount(int accountAge, int creditScore, AccountInterest accountInterest) { AccountAge = accountAge; CreditScore = creditScore; AccountInterest = accountInterest; } public int AccountAge { get; private set; } public int CreditScore { get; private set; } public AccountInterest AccountInterest { get; private set; } } } 总结:这个重构法则在很多时候能让我们把代码组织的结构调整得更合理,同时也能给以后的维护带来方便。 31 天重构学习笔记3. 提升方法 概念:提升方法是指将一个很多继承类都要用到的方法提升到基类中。   正文:提升方法是指将一个很多继承类都要用到的方法提升到基类中,这样就能减少代码量,同时让类的结构更清晰。如下代码所 示,Turn方法在子类Car 和Motorcycle 都会用到,因为Vehicle 都会有这个方法,所以我们就会想到把它提到基类 中。 namespace LosTechies.DaysOfRefactoring.PullUpMethod.Before { public abstract class Vehicle { // other methods } public class Car : Vehicle { public void Turn(Direction direction) { // code here } } public class Motorcycle : Vehicle { } public enum Direction { Left, Right } } 重构后的代码如下,那么现在Car 和Motorcycle 都具有Turn这个方法,如果这个方法修 改也只需要修改基类即可,所以给维护和以后的重构带来了方便。 namespace LosTechies.DaysOfRefactoring.PullUpMethod.After { public abstract class Vehicle { public void Turn(Direction direction) { // code here } } public class Car : Vehicle { } public class Motorcycle : Vehicle { } public enum Direction { Left, Right } } 总结:这个重构要根据具体情况使用,如果不是每个子类都有这个方法的话,可以考虑使用接口或者其他方式。 31 天重构学习笔记4. 降低方法 概念:本文中的降低方法和前篇的提升方法整好相反,也就是把个别子类使用到的方法从基类移到子类里面去。   正文:如下代码所示,Animal 类 中的方法Bark只有在其子类Dog 中使用,所以最 好的 方案 气瓶 现场处置方案 .pdf气瓶 现场处置方案 .doc见习基地管理方案.doc关于群访事件的化解方案建筑工地扬尘治理专项方案下载 就是把这个方法移到子类Dog 中。 namespace LosTechies.DaysOfRefactoring.PushDownMethod.Before { public abstract class Animal { public void Bark() { // code to bark } } public class Dog : Animal { } public class Cat : Animal { } }   重构后的代码如下,同时如果在父类Animal 中 如果没有其他的字段或者公用方法的话,可以考虑把Bark方法做成一个接口,从而去掉Animal 类。 namespace LosTechies.DaysOfRefactoring.PushDownMethod.After { public abstract class Animal { } public class Dog : Animal { public void Bark() { // code to bark } } public class Cat : Animal { } }   总结:面向对象三大特征(继承、封装、多态)很多时候可以帮助我们,但同时也可能会造成使用过度或者使用不当,所以如何把握好设计, 这个就变得至关重要。在什么时候使用继承的方式,在什么时候使用组合和聚合,接口和继承类的选择等久成了我们的重点。 31 天重构学习笔记5. 提升字段 概念:本文中的提升字段和前面的提升方法颇为相似,就是把子类公用的字段提升到基类中,从而达到公用的目的。   正文:如下代码所示, Account 的 两个子类CheckingAccount 和SavingsAccount 都有 minimumCheckingBalance 字段,所以可以考虑把这个字段提到基类中。 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace LosTechies.DaysOfRefactoring.PullUpField.Before { public abstract class Account { } public class CheckingAccount : Account { private decimal _minimumCheckingBalance = 5m; } public class SavingsAccount : Account { private decimal _minimumSavingsBalance = 5m; } }   重构后的代码如下,这样提的前提是这些子类有一个基类或者有很多相似的字段和方法,不然为了一个字段而单独建立一个抽象类是不可取的,所以这个就需 要具体权衡。 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace LosTechies.DaysOfRefactoring.PullUpField.After { public abstract class Account { protected decimal _minimumBalance = 5m; } public class CheckingAccount : Account { } public class SavingsAccount : Account { } }   总结:这个重构的策略比较简单,同时也是比较常用的一些做法,最主要就是要注意权衡是否真的有这个必要,看这样做究竟有没有什么好处 (比如只需要改一个地方,维护简便了,同时代码量也更少了等)。 31 天重构学习笔记6. 降低字段 概念:本文中的降低字段和前篇的提升字段正好相反,就是把基类中只有某些少数类用到的字段降低到使用它们的子类中。   正文:如下代码所示,基类Task 类 中的_resolution字段只会在子类BugTask 中 用到,所以就考虑把它放到BugTask 类中。 namespace LosTechies.DaysOfRefactoring.PushDownField.Before { public abstract class Task { protected string _resolution; } public class BugTask : Task { } public class FeatureTask : Task { } }   重构后的代码如下所示,这样做的好处可以简化基类,同时让其他没有使用它的子类也变得更加简单,如果这样的字段比较多的话,使用此重构也能节约一部分内 存。 namespace LosTechies.DaysOfRefactoring.PushDownField.After { public abstract class Task { } public class BugTask : Task { private string _resolution; } public class FeatureTask : Task { } } 总结:此重构也是一个非常简单的重构,在很多时候我们都会不自觉的使用它。 31 天重构学习笔记7. 重命名(方法,类,参数) 概念:本文中的改名(方法,类,参数)是指在写代码的时候对类、方法、参数、委托、事件等等元素取一个有意义的名称。   正文:如下代码所示,加入一个公司建立一个员工的类,类中有一个员工名字的字段和一个按照小时计算员工收入的方法,那么下面代码的取 名就显得很难理解了,所以我们会重构名称。 namespace LosTechies.DaysOfRefactoring.Rename.Before { public class Person { public string FN { get; set; } public decimal ClcHrlyPR() { // code to calculate hourly payrate return 0m; } } }   重构后代码如下所示,这样看起来就非常清晰,如果有新进项目组的成员,也会变得很乐意看这个代码。 namespace LosTechies.DaysOfRefactoring.Rename.After { // Changed the class name to Employee public class Employee { public string FirstName { get; set; } public decimal CalculateHourlyPay() { // code to calculate hourly payrate return 0m; } } }   总结:此重构经常被广大程序员所忽视,但是带来的隐患是不可估量的,也许老板要修改功能,那我们来看这段没有重构的代码(就算是自己 写的,但由于时间和项目多等关系,我们也很难理解了),然后就会变得焦头烂额。相反重构后的代码就会觉得一目了然、赏心悦目。 31 天重构学习笔记8. 使用委派代替继承 概念:本文中的“使用委派代替继承”是指在根本没有父子关系的类中使用继承是不合理的,可以用委派的方式来代替。   如下代码所示,Child 和Sanitation (公共设施)是没有逻辑上的父子关系,因为 小孩不可能是一个公共设施吧!所以我们为了完成这个功能可以考虑使用委派的方式。 namespace LosTechies.DaysOfRefactoring.ReplaceInheritance.Before { public class Sanitation { public string WashHands() { return "Cleaned!"; } } public class Child : Sanitation { } }   重构后的代码如下,把Sanitation 委 派到Child 类中,从而可以使用 WashHands这个方法,这种方式我们经常会用到,其实IOC也使用到了这个原理,可以通过构造注入和方法注入等。 namespace LosTechies.DaysOfRefactoring.ReplaceInheritance.After { public class Sanitation { public string WashHands() { return "Cleaned!"; } } public class Child { private Sanitation Sanitation { get; set; } public Child() { Sanitation = new Sanitation(); } public string WashHands() { return Sanitation.WashHands(); } } }   总结:这个重构是一个很好的重构,在很大程度上解决了滥用继承的情况,很多设计模式也用到了这种思想(比如桥接模式、适配器模式、策 略模式等)。 31 天重构学习笔记9. 提取接口 概念:本文中的“提取接口” 是指超过一个的类要使用某一个类中部分方法时,我们应该解开它们之间的依赖,让调用者使用接口,这很容易实现也可以降低代码的耦合性。   正文:如下代码所示,RegistrationProcessor 类只使用到了ClassRegistration 类 中的Create方法和Total 字段,所以可以考虑把他们做成接口给RegistrationProcessor 调用。 namespace LosTechies.DaysOfRefactoring.ExtractInterface.Before { public class ClassRegistration { public void Create() { // create registration code } public void Transfer() { // class transfer code } public decimal Total { get; private set; } } public class RegistrationProcessor { public decimal ProcessRegistration(ClassRegistration registration) { registration.Create(); return registration.Total; } } }   重构后的代码如下,我们提取了一个IClassRegistration 接口,同时让ClassRegistration 继 承此接口,然后调用端RegistrationProcessor 就 可以直接通过IClassRegistration 接 口进行调用。 namespace LosTechies.DaysOfRefactoring.ExtractInterface.After { public interface IClassRegistration { void Create(); decimal Total { get; } } public class ClassRegistration : IClassRegistration { public void Create() { // create registration code } public void Transfer() { // class transfer code } public decimal Total { get; private set; } } public class RegistrationProcessor { public decimal ProcessRegistration(IClassRegistration registration) { registration.Create(); return registration.Total; } } }   总结:这个重构策略也是一个常见的运用,很多设计模式也会在其中运用此思想(如简单工程、抽象工厂等都会通过接口来解开依赖)。 31 天重构学习笔记10. 提取方法 概念:本文中的把某些计算复杂的过程按照功能提取成各个小方法,这样就可以使代码的可读性、维护性得到提高。   正文:如下代码所示,CalculateGrandTotal方法里面包含了多个逻辑,第一计算subTotal 的总和,第二subTotal 要循环减去discount,也就是计算Discounts,第三就是计算Tax。所以我们可以根据功能把他们拆分成三个小方法。 using System.Collections.Generic; namespace LosTechies.DaysOfRefactoring.ExtractMethod.Before { public class Receipt { private IList Discounts { get; set; } private IList ItemTotals { get; set; } public decimal CalculateGrandTotal() { decimal subTotal = 0m; foreach (decimal itemTotal in ItemTotals) subTotal += itemTotal; if (Discounts.Count > 0) { foreach (decimal discount in Discounts) subTotal -= discount; } decimal tax = subTotal * 0.065m; subTotal += tax; return subTotal; } } }   重构后的代码如下,然后CalculateGrandTotal方法就直接调用CalculateSubTotal、 CalculateDiscounts、CalculateTax,从而是整个逻辑看起来更加清晰,并且可读性和维护性也得到了大大提高。 using System.Collections.Generic; namespace LosTechies.DaysOfRefactoring.ExtractMethod.After { public class Receipt { private IList Discounts { get; set; } private IList ItemTotals { get; set; } public decimal CalculateGrandTotal() { decimal subTotal = CalculateSubTotal(); subTotal = CalculateDiscounts(subTotal); subTotal = CalculateTax(subTotal); return subTotal; } private decimal CalculateTax(decimal subTotal) { decimal tax = subTotal * 0.065m; subTotal += tax; return subTotal; } private decimal CalculateDiscounts(decimal subTotal) { if (Discounts.Count > 0) { foreach (decimal discount in Discounts) subTotal -= discount; } return subTotal; } private decimal CalculateSubTotal() { decimal subTotal = 0m; foreach (decimal itemTotal in ItemTotals) subTotal += itemTotal; return subTotal; } } }   总结:这个重构在很多公司都有一些的代码 规范 编程规范下载gsp规范下载钢格栅规范下载警徽规范下载建设厅规范下载 作为参考,比如一个类不能超过多少行代码,一个方法里面不能超过多少行代码,这在一定程度上也能使程序员把这些 复杂的逻辑剥离成意义很清楚的小方法。 31 天重构学习笔记11. 使用策略类 概念:本文中的“使用策略类” 是指用设计模式中的策略模式来替换原来的switch case和if else语句,这样可以解开耦合,同时也使维护性和系统的可扩展性大大增强。   正文:如下面代码所示,ClientCode 类 会更加枚举State的值来调用ShippingInfo 的不同方法,但是这样就会产生很多的判 断语句,如果代码量加大,类变得很大了的话,维护中改动也会变得很大,每次改动一个地方,都要对整个结构进行编译(假如是多个工程),所以我们想到了对它 进行重构,剥开耦合。 namespace LosTechies.DaysOfRefactoring.SwitchToStrategy.Before { public class ClientCode { public decimal CalculateShipping() { ShippingInfo shippingInfo = new ShippingInfo(); return shippingInfo.CalculateShippingAmount(State.Alaska); } } public enum State { Alaska, NewYork, Florida } public class ShippingInfo { public decimal CalculateShippingAmount(State shipToState) { switch (shipToState) { case State.Alaska: return GetAlaskaShippingAmount(); case State.NewYork: return GetNewYorkShippingAmount(); case State.Florida: return GetFloridaShippingAmount(); default: return 0m; } } private decimal GetAlaskaShippingAmount() { return 15m; } private decimal GetNewYorkShippingAmount() { return 10m; } private decimal GetFloridaShippingAmount() { return 3m; } } }   重构后的代码如下所示,抽象出一个IShippingCalculation 接口,然后把ShippingInfo 类 里面的GetAlaskaShippingAmount、GetNewYorkShippingAmount、 GetFloridaShippingAmount三个方法分别提炼成三个类,然后继承自IShippingCalculation 接口,这样在调用的时候就可以通过IEnumerable 来解除之前的switch case语句,这和IOC的做法颇为相似。   using System; using System.Collections.Generic; using System.Linq; namespace LosTechies.DaysOfRefactoring.SwitchToStrategy.After_WithIoC { public interface IShippingInfo { decimal CalculateShippingAmount(State state); } public class ClientCode { [Inject] public IShippingInfo ShippingInfo { get; set; } public decimal CalculateShipping() { return ShippingInfo.CalculateShippingAmount(State.Alaska); } } public enum State { Alaska, NewYork, Florida } public class ShippingInfo : IShippingInfo { private IDictionary ShippingCalculations { get; set; } public ShippingInfo(IEnumerable shippingCalculations) { ShippingCalculations = shippingCalculations.ToDictionary(calc => calc.State); } public decimal CalculateShippingAmount(State shipToState) { return ShippingCalculations[shipToState].Calculate(); } } public interface IShippingCalculation { State State { get; } decimal Calculate(); } public class AlaskShippingCalculation : IShippingCalculation { public State State { get { return State.Alaska; } } public decimal Calculate() { return 15m; } } public class NewYorkShippingCalculation : IShippingCalculation { public State State { get { return State.NewYork; } } public decimal Calculate() { return 10m; } } public class FloridaShippingCalculation : IShippingCalculation { public State State { get { return State.Florida; } } public decimal Calculate() { return 3m; } } }   总结:这种重构在设计模式当中把它单独取了一个名字——策略模式,这样做的好处就是可以隔开耦合,以注入的形式实现功能,这使增加功能变得 更加容易和简便,同样也增强了整个系统的稳定性和健壮性。 31 天重构学习笔记12. 分解依赖 概念:本文中的“分解依赖” 是指对部分不满足我们要求的类和方法进行依赖分解,通过装饰器来达到我们需要的功能。   正文:正如下面代码所示,如果你要在你的代码中加入单元测试但有一部分代码是你不想测试的,那么你应用使用这个的重构。下面的例子中 我们应用静态类来完成某些工作,但问题是在单元测试时我们无法mock静态类,所以我们只能引入静态类的装饰接口来分解对静态类的依赖。从而我们使我们的 调用类只需要依赖于装饰接口就能完成这个操作。 namespace LosTechies.DaysOfRefactoring.BreakDependencies.Before { public class AnimalFeedingService { private bool FoodBowlEmpty { get; set; } public void Feed() { if (FoodBowlEmpty) Feeder.ReplenishFood(); // more code to feed the animal } } public static class Feeder { public static void ReplenishFood() { // fill up bowl } } }     重构后代码如下,我们添加一个接口和一个实现类,在实现类中调用静态类的方法,所以说具体做什么事情没有改变,改变的只是形式,但这样做的一个好处是增加了了代码的可测试性。 在应用了分解依赖模式后,我们就可以在单元测试的时候mock一个IFeederService对象并通过AnimalFeedingService的构造函数传递给它。这样就可以完成我们需要的功能。 namespace LosTechies.DaysOfRefactoring.BreakDependencies.After { public class AnimalFeedingService { public IFeederService FeederService { get; set; } public AnimalFeedingService(IFeederService feederService) { FeederService = feederService; } private bool FoodBowlEmpty { get; set; } public void Feed() { if (FoodBowlEmpty) FeederService.ReplenishFood(); // more code to feed the animal } } public interface IFeederService { void ReplenishFood(); } public class FeederService : IFeederService { public void ReplenishFood() { Feeder.ReplenishFood(); } } public static class Feeder { public static void ReplenishFood() { // fill up bowl } } }   总结:这个重构在很多时候和设计模式中的一些思想类似,使用中间的装饰接口来分解两个类之间的依赖,对类进行装饰,然后使它 31 天重构学习笔记13. 提取方法对象 概念:本文中的“提取方法对象”是指当你发现一个方法中存在过多的局部变量时,你可以通过使用“提取方法对象”重构来引入一些方法, 每个方法完成任务的一个步骤,这样可以使得程序变得更具有可读性。   正文:如下代码所示,Order 类 中的Calculate方法要完成很多功能,在之前我们用“提取方法”来进行重构,现在我们采取“提取方法对象”来完成重构。 using System.Collections.Generic; namespace LosTechies.DaysOfRefactoring.ExtractMethodObject.Before { public class OrderLineItem { public decimal Price { get; private set; } } public class Order { private IList OrderLineItems { get; set; } private IList Discounts { get; set; } private decimal Tax { get; set; } public decimal Calculate() { decimal subTotal = 0m; // Total up line items foreach (OrderLineItem lineItem in OrderLineItems) { subTotal += lineItem.Price; } // Subtract Discounts foreach (decimal discount in Discounts) subTotal -= discount; // Calculate Tax decimal tax = subTotal * Tax; // Calculate GrandTotal decimal grandTotal = subTotal + tax; return grandTotal; } } }   正如下代码所示,我们引入了OrderCalculator类,该类实现了所有的计算方法,Order类将自身传递给 OrderCalculator类并调用Calculate方法完成计算过程。 using System.Collections.Generic; namespace LosTechies.DaysOfRefactoring.ExtractMethodObject.After { public class OrderLineItem { public decimal Price { get; private set; } } public class Order { public IEnumerable OrderLineItems { get; private set; } public IEnumerable Discounts { get; private set; } public decimal Tax { get; private set; } public decimal Calculate() { return new OrderCalculator(this).Calculate(); } } public class OrderCalculator { private decimal SubTotal { get; set; } private IEnumerable OrderLineItems { get; set; } private IEnumerable Discounts { get; set; } private decimal Tax { get; set; } public OrderCalculator(Order order) { OrderLineItems = order.OrderLineItems; Discounts = order.Discounts; Tax = order.Tax; } public decimal Calculate() { CalculateSubTotal(); SubtractDiscounts(); CalculateTax(); return SubTotal; } private void CalculateSubTotal() { // Total up line items foreach (OrderLineItem lineItem in OrderLineItems) SubTotal += lineItem.Price; } private void SubtractDiscounts() { // Subtract Discounts foreach (decimal discount in Discounts) SubTotal -= discount; } private void CalculateTax() { // Calculate Tax SubTotal += SubTotal * Tax; } } }   总结:本文的重构方法在有的时候还是比较有用,但这样会造成字段的增加,同时也会带来一些维护的不便,它和“提取方法”最大的区别就 是一个通过方法返回需要的数据,另一个则是通过字段来存储方法的结果值,所以在很大程度上我们都会选择“提取方法”。 31 天重构学习笔记14. 分离职责 概念:本文中的“分离职责”是指当一个类有许多职责时,将部分职责分离到独立的类中,这样也符合面向对象的五大特征之一的单一职责原 则,同时也可以使代码的结构更加清晰,维护性更高。   正文:如下代码所示,Video类 有两个职责,一个是处理video rental,另一个是计算每个客户的总租金。我们可以将这两个职责分离出来,因为计算每个客户的总租金可以在Customer计算,这也比较符合常理。 using System.Collections.Generic; using System.Linq; namespace LosTechies.DaysOfRefactoring.BreakResponsibilities.Before {     public class Video    {         public void PayFee(decimal fee)         {         }         public void RentVideo(Video video, Customer customer)         {             customer.Videos.Add(video);         }         public decimal CalculateBalance(Customer customer)         {             returncustomer.LateFees.Sum();         }     }     public class Customer    {         public IList LateFees { get; set; }         public IList
本文档为【31天重构学习系列-中文】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_027479
暂无简介~
格式:doc
大小:287KB
软件:Word
页数:64
分类:互联网
上传时间:2011-06-06
浏览量:23