【转】[重构]Primitive Obsession

http://blog.csdn.net/wxr0323/article/details/7913950

 

Primitive Obsession(基本类型偏执)

偏执这个词实在是有点难懂。百度百科传送门

定义:Coding的时候总喜欢用基本类型,而不喜欢用对象。

影响:增加扩展和修改的复杂性。

 

来看两个函数。

Primitive:

[csharp] view plain copy
 
  1. public void Method(string id, string name, string address)  
  2.         {  
  3.             //...  
  4.         }  

Object:

[csharp] view plain copy
 
  1. public void Method(object obj)  
  2.         {  
  3.             //obj.id.....  
  4.             //obj.name....  
  5.             //...  
  6.         }  

随着需求日益变化,我们的参数会越来越多。那么使用基本类型的Method就会有很长的参数,演变成Long Parameter。Long Parameter会导致可读性差以及维护成本增加,直觉是这个方法职责太多。

Demo:媒婆、有Iphone4的小伙

小伙:

[csharp] view plain copy
 
  1. class Boy  
  2.     {  
  3.         public string Name { get; set; }  
  4.         public string TelephoneNumber { get; set; }  
  5.     }  

媒婆:

[csharp] view plain copy
 
  1. class WomanMatchmaker  
  2.     {  
  3.         private readonly Boy boy;  
  4.         ...  
  5.         public string getBoyTelephoneNumberLastFourDigit()  
  6.         {  
  7.             const int digit = 4;  
  8.             var length = boy.TelephoneNumber.Length;  
  9.             return length > digit ? boy.TelephoneNumber.Substring(length - digit, length) : boy.TelephoneNumber;  
  10.         }  
  11.     }  

媒婆需要小伙电话号码的后四位与姑娘电话号码后四位配对。配对成功后,问姑娘还有什么要求?

姑娘说只要用IPone4的小伙。无奈之下只好给小伙添加个属性。

[csharp] view plain copy
 
  1. class Boy  
  2.    {  
  3.        public string Name { get; set; }  
  4.        public string TelephoneNumber { get; set; }  
  5.        public string TelePhoneType { get; set; }  
  6.    }  

相应的还要给媒婆类添加一个方法:

[csharp] view plain copy
 
  1. class WomanMatchmaker  
  2.     {  
  3.         private readonly Boy boy;  
  4.   
  5.         public WomanMatchmaker(Boy boy)  
  6.         {  
  7.             this.boy = boy;  
  8.         }  
  9.   
  10.         public string GetBoyTelephoneNumberLastFourDigit()  
  11.         {  
  12.             const int digit = 4;  
  13.             var length = boy.TelephoneNumber.Length;  
  14.             return length > digit ? boy.TelephoneNumber.Substring(length - digit, length) : boy.TelephoneNumber;  
  15.         }  
  16.   
  17.         public string GetBoyTelephoneType()  
  18.         {  
  19.             return boy.TelePhoneType;  
  20.         }  
  21.     }  

到此为止。如果姑娘还要问手机用的什么操作系统,那还要加属性加方法?另外这段代码有个很明显的BadSmell:Feature Envy。

重构:将基本类型替换为Object。 将所有关于手机的信息放在一起。

Extract Phone Class:

[csharp] view plain copy
 
  1. class Phone  
  2.     {  
  3.         private const int DIGIT = 4;  
  4.   
  5.         public string Number { get; set; }  
  6.         public string Category { get; set; }  
  7.   
  8.         public string GetLastFourDigit()  
  9.         {  
  10.             var length = Number.Length;  
  11.             return length > DIGIT ? Number.Substring(length - DIGIT, length) : Number;  
  12.         }  
  13.   
  14.         public string GetCategory()  
  15.         {  
  16.             return BuildCategory(Category);  
  17.         }  
  18.     }  

小伙带个手机就行了:

[csharp] view plain copy
 
  1. class Boy  
  2.     {  
  3.         public string Name { get; set; }  
  4.         public Phone phone { get; set; }  
  5.     }  

媒婆也轻松了:

[csharp] view plain copy
 
  1. class WomanMatchmaker  
  2.     {  
  3.         private readonly Boy boy;  
  4.   
  5.         public R_WomanMatchmaker(Boy boy)  
  6.         {  
  7.             this.boy = boy;  
  8.         }  
  9.   
  10.         public string getBoyTelephoneNumberLastFourDigit()  
  11.         {  
  12.             return boy.phone.GetLastFourDigit();  
  13.         }  
  14.   
  15.         public string GetBoyTelephoneCategory()  
  16.         {  
  17.             return boy.phone.GetCategory();  
  18.         }  
  19.     }  

姑娘问手机是哪个地方产的? 我们就在Phone中添加一属性,媒婆类里加一委托即可。

posted on 2016-08-30 17:52  mimime  阅读(491)  评论(0编辑  收藏  举报