[Refactoring]Feature Envy

Feature Envy(依恋情结)

官方的:函数对某个类的兴趣高过对自己所处类的兴趣。

影响:数据和行为不在一处,修改不可控。

Demo:媒婆、一小伙、一小姑娘

场景:函数的全部数据都来自于另外一个类

媒婆、小伙先出场

public class Boy
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public string Adress { get; set; }
        public bool IsSinglehood { get; set; }
        public bool IsHightRichHandsome { get; set; }
    }

    public class WomanMatchMaker
    {
        private readonly Boy boy;
        ...
        public string GetBoyInformation()
        {
            return string.Format("Name: {0} Age: {1} Adress: {2} the boys is {3} and he is {4}", 
                boy.Name, 
                boy.Age, 
                boy.Adress, 
                (boy.IsSinglehood ? "Singlehood " : "married"), 
                (boy.IsHightRichHandsome ? "HightRichHandsome" : "DiaoSi"));
        }
    }

从上面代码看出:GetBoyInformation函数中所有数据都是从Boy类中获取。如果Boy中的属性发生变化,就要改WomanMatchMaker类,修改多处。为了让数据和行为变化在一处,Boy应该负责提供本人信息的这种行为。

public class Boy
    {
        ...
        public string GetInformation()
        {
            return string.Format("Name: {0} Age: {1} Adress: {2} the boys is {3} and he is {4}", 
                Name, 
                Age, 
                Adress, 
                (IsSinglehood ? "Singlehood " : "married"), 
                (IsHightRichHandsome ? "HightRichHandsome" : "DiaoSi"));
        }
    }

    public class WomanMatchmaker
    {
        private readonly Boy boy;
        ...
        public string GetBoyInformation()
        {
            return boy.GetInformation();
        }
    }

将GetBoyInformation函数Move到Boy类中。然后WomanMatchMarker中用一委托。

 

场景二:函数有一部分数据来自于另一个类。

现在需求稍微有点变动。需要提供男孩信息的同时要提供媒婆信息。

public class WomanMatchmaker
    {
        public string Name { get; set; }
        public string Adress { get; set; }

        private readonly Boy boy;
        ...
        public string GetBoyInformationWithComeFromInformation()
        {
            return string.Format("Name: {0} Age: {1} Adress: {2} the boys is {3} and he is {4}, {5}",
                boy.Name, 
                boy.Age, 
                boy.Adress, 
                (boy.IsSinglehood ? "Singlehood " : "married"), 
                (boy.IsHightRichHandsome ? "HightRichHandsome" : "DiaoSi"), 
                GetInformationComeFrom());
        }        

        private string GetInformationComeFrom()
        {
            return string.Format("Information comes from: {0} Adress: {1}", Name, Adress);
        }
    }

此函数中有部分使用另一个类的数据。同第一种做法稍有不同,先把从Boy中来的数据Extract 到一个独立函数中,在把它移到它想去的地方。那么此方法就变成这个样子了。

public class WomanMatchMaker
    {
        public string Name { get; set; }
        public string Adress { get; set; }

        private readonly Boy boy;
        ...
        public string GetBoyInformationWithComeFromInformation()
        {
            return boy.GetInformation() + GetInformationComeFrom();
        }

        private string GetInformationComeFrom()
        {
            return string.Format("Information comes from: {0} Adress: {1}", Name, Adress);
        }
    }

 

场景三:函数使用多个类的数据

等了这么久,姑娘终于出场了。媒婆要看看小伙子和姑娘是否合适。

有了上面的两个场景。再来看看这个方法有没有Refactor的Sense。

public string MatchedPairResult()
        {
            //boy information
            var boyInfo = string.Format("Name: {0} Age: {1} Adress: {2}...", boy.Name, boy.Age, boy.Adress);
            //girl information
            var girlInfo = string.Format("Name: {0} Age: {1} Adress: {2}...", girl.Name, girl.Age, girl.Adress);

            return (RuleMatching(boyInfo, girlInfo) ? "To be together!" : "Improper!") + GetInformationComeFrom();
        }

这个函数用到了多个类的数据。那么我们就分别把它们提炼到独立函数中,在分别送它们想去的地方。

public class WomanMatchMaker
    {
        ...
        public string MatchedPairResult()
        {
            //boy information
            var boyInfo = boy.GetInformation();
            //girl information
            var girlInfo = girl.GetInformation();

            return (RuleMatching(boyInfo, girlInfo) ? "To be together!" : "Improper!") + GetInformationComeFrom();
        }
        ...
    }

 

经过一番重构之后,他们终于幸福的在一起了。

总结:

1、函数全部数据来自另外一个类

      做法:将数据提炼到一个独立函数中  Move method。

2、函数部分数据来自另外一个类

      做法:将“部分数据”提炼到一个函数中 Move method。

3、函数的数据来自不同类

      做法:将数据分类,分别提炼各自的独立的函数,在将这些函数移到各自属于的类中。

转载于:https://www.cnblogs.com/lassie/archive/2012/09/03/2667689.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值