Primitive Obsession(基本类型偏执)
偏执这个词实在是有点难懂。百度百科传送门
定义:Coding的时候总喜欢用基本类型,而不喜欢用对象。
影响:增加扩展和修改的复杂性。
来看两个函数。
Primitive:
public void Method(string id, string name, string address) { //... }Object:
public void Method(object obj) { //obj.id..... //obj.name.... //... }随着需求日益变化,我们的参数会越来越多。那么使用基本类型的Method就会有很长的参数,演变成Long Parameter。Long Parameter会导致可读性差以及维护成本增加,直觉是这个方法职责太多。
Demo:媒婆、有Iphone4的小伙
小伙:
class Boy { public string Name { get; set; } public string TelephoneNumber { get; set; } }媒婆:
class WomanMatchmaker { private readonly Boy boy; ... public string getBoyTelephoneNumberLastFourDigit() { const int digit = 4; var length = boy.TelephoneNumber.Length; return length > digit ? boy.TelephoneNumber.Substring(length - digit, length) : boy.TelephoneNumber; } }
媒婆需要小伙电话号码的后四位与姑娘电话号码后四位配对。配对成功后,问姑娘还有什么要求?
姑娘说只要用IPone4的小伙。无奈之下只好给小伙添加个属性。
class Boy { public string Name { get; set; } public string TelephoneNumber { get; set; } public string TelePhoneType { get; set; } }
相应的还要给媒婆类添加一个方法:
class WomanMatchmaker { private readonly Boy boy; public WomanMatchmaker(Boy boy) { this.boy = boy; } public string GetBoyTelephoneNumberLastFourDigit() { const int digit = 4; var length = boy.TelephoneNumber.Length; return length > digit ? boy.TelephoneNumber.Substring(length - digit, length) : boy.TelephoneNumber; } public string GetBoyTelephoneType() { return boy.TelePhoneType; } }
到此为止。如果姑娘还要问手机用的什么操作系统,那还要加属性加方法?另外这段代码有个很明显的BadSmell:Feature Envy。
重构:将基本类型替换为Object。 将所有关于手机的信息放在一起。
Extract Phone Class:
class Phone { private const int DIGIT = 4; public string Number { get; set; } public string Category { get; set; } public string GetLastFourDigit() { var length = Number.Length; return length > DIGIT ? Number.Substring(length - DIGIT, length) : Number; } public string GetCategory() { return BuildCategory(Category); } }小伙带个手机就行了:
class Boy { public string Name { get; set; } public Phone phone { get; set; } }媒婆也轻松了:
class WomanMatchmaker { private readonly Boy boy; public R_WomanMatchmaker(Boy boy) { this.boy = boy; } public string getBoyTelephoneNumberLastFourDigit() { return boy.phone.GetLastFourDigit(); } public string GetBoyTelephoneCategory() { return boy.phone.GetCategory(); } }
姑娘问手机是哪个地方产的? 我们就在Phone中添加一属性,媒婆类里加一委托即可。