[重构]Primitive Obsession

来源:互联网 发布:情报大数据分析平台 编辑:程序博客网 时间:2024/05/17 20:13

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中添加一属性,媒婆类里加一委托即可。