编程知识 购物 网址 新闻 笑话 | 软件 日历 阅读 图书馆 China 头条阅读 学淘股 China Travel
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
vbs/VBScript DOS/BAT hta htc python perl 游戏相关 VBA 远程脚本 ColdFusion ruby专题 autoit seraphzone PowerShell linux shell Lua Golang Erlang 其它教程 CSS/HTML/Xhtml html5 CSS XML/XSLT Dreamweaver教程 经验交流
站长资讯 .NET新手 ASP.NET C# WinForm Silverlight WCF CLR WPF XNA VisualStudio ASP.NET-MVC .NET控件开发 EntityFramework WinRT-Metro Java C++ PHP Delphi Python Ruby C语言 Erlang Go Swift Scala R语言 Verilog 其它语言 架构设计 面向对象 设计模式 领域驱动 Html-Css JavaScript jQuery HTML5 SharePoint GIS技术 SAP OracleERP DynamicsCRM K2 BPM 信息安全 企业信息 Android开发 iOS开发 WindowsPhone WindowsMobile 其他手机 敏捷开发 项目管理 软件工程 SQLServer Oracle MySQL NoSQL 其它数据库 Windows7 WindowsServer Linux
   -> C# -> 重构手法之处理概括关系【3】 -> 正文阅读

[C#]重构手法之处理概括关系【3】

返回总目录
本小节目录
Extract BaseClass(提炼基类) Extract Interface(提炼接口) Collapse Hierarchy(折叠继承体系) 7Extract BaseClass(提炼基类) 概要
两个类有相似特性。为这两个类建立一个基类,将相同特性移至基类。
动机
重复代码是系统中最糟糕的东西之一。如果你在不同地方做同一件事情,一旦需要修改那些动作,你就得平白做更多的修改。
重复代码的某种形式就是:两个类以相同的方式做类似的事情,或者以不同的方式做类似的事情。对象提供了一种简化这种情况的机制,那就是继承。但是,在建立这些具有共通性的类之前,你往往无法发现这样的共通性,因此常常会在具有共通性的类出现之后,再开始建立其间的继承结构。
范例
Dog类中的EatFood和Groom有可能被其他类用到,因为他们都是动物的一些公有性质,所以这个时候我们就会考虑对它进行提炼。

public class Dog
{
    public void EatFood()
    {
        // eat some food
    }


    public void Groom()
    {
        // perform grooming
    }
}

代码如下所示,提取了Animal方法来封装公用的EatFood和Groom类,从而使其他继承了Animal类的子类都可以使用这两个方法了。

public class Animal
{
    public void EatFood()
    {
        // eat some food
    }

    public void Groom()
    {
        // perform grooming
    }
}

public class Dog : Animal
{
}

小结
这个重构是典型的继承用法,很多程序员都会选择这样做,但是要注意正确的使用,不要造成过度使用了继承,如果过度使用了,请考虑用接口、组合和聚合来实现。
这个手法也经常用到,比如做的MVC项目中的BaseController。
8Extract Interface(提炼接口) 概要
若干客户使用类接口中的同一子集,或者两个类的接口有部分相同。将相同的子集提炼到一个独立接口中。
动机
如果某个类在不同环境下扮演截然不同的角色,使用接口就是个好主意。你可以针对每个角色以Extract Interface提炼出相应接口。另一种可以用Extract Interface的情况是:你想要描述一个类的外部依赖接口(outbound interface,即这个类要求服务提供方提供的操作)。如果你打算将来加入其它种类的服务对象。只需要求它们实现这个接口即可。
范例
TimeSheet类表示员工为客户工作的时间表,从中可以计算客户应该支付的费用。为了计算这些费用,TimeSheet需要知道员工级别,以及该员工是否具有特殊技能:

class TimeSheet
{
    public double Charge(Employee emp, int days)
    {
        int baseCharge = emp.GetRate() * days;
        if (emp.HasSpecialSkill())
        {
            return baseCharge * 1.05;
        }
        return baseCharge;
    }
}

class Employee
{
    public int GetRate()
    {
        return 2;
    }

    public bool HasSpecialSkill()
    {
        return true;
    }
}

除了提供员工的级别和特殊技能信息之外,Employee还有很多其他方面的功能,但本应用程序只需这两项功能。可以针对这两项功能定义一个接口,从而强调“我只需要这部分功能”的事实:

public interface IBillable
{
    int GetRate();
    bool HasSpecialSkill();
}

然后,声明让Employee实现这个接口:

class Employee : IBillable
{
    public int GetRate()
    {
        return 2;
    }

    public bool HasSpecialSkill()
    {
        return true;
    }
}

完成以后,修改TimeSheet类中Charge()函数声明,强调该函数只使用Employee的这一部分行为:

class TimeSheet
{
    public double Charge(IBillable emp, int days)
    {
        int baseCharge = emp.GetRate() * days;
        if (emp.HasSpecialSkill())
        {
            return baseCharge * 1.05;
        }
        return baseCharge;
    }
}

到目前为止,我们只不过是在文档化方面有一点收获。但就这一个函数而言,这样的收获并没有太大的价值;但如有若干个类都使用IBillable接口,它就会很有用。如果我还想计算电脑租金,巨大的收获就显露出来了;要想计算客户租用电脑的费用,只需让Computer类实现IBillable接口,然后就可以把租用电脑的时间也填到时间表上了。
小结
这个重构策略也是一个常见的运用,很多设计模式也会在其中运用此思想。
9Collapse Hierarchy(折叠继承体系) 概要
基类和子类之间无太大区别。将它们合为一体。
动机
如果你曾经编写过继承体系,就会知道,继承体系很容易变得过分复杂。所谓重构继承体系,往往是将函数和字段在体系中上下移到。完成这些动作后,你很可能发现某个子类并未带来该有的价值,因此需要把基类和子类合并起来。
范例
如下代码所示,StudentWebSite子类除了有一个属性用来说明网站是否是活动的外没有别的责任,在这种情形下我们意识到IsActive属性可以应用到所有的网站,所以我们可以将IsActive属性上移到基类中,并去掉StudentWebSite类。

public class Website
{
    public string Title { get; set; }
    public string Description { get; set; }
    public IEnumerable<Webpage> Pages { get; set; }
}

public class StudentWebsite : Website
{
    public bool IsActive { get; set; }
}

public class Webpage
{
}

重构后的代码如下:

public class Website
{
    public string Title { get; set; }
    public string Description { get; set; }
    public IEnumerable<Webpage> Pages { get; set; }
    public bool IsActive { get; set; }
}
public class Webpage
{
}

小结
这项重构和前几篇最主要论述了子类和父类的继承关系以及如何判断什么时候需要使用继承,一般我们都能处理好这些关系,所以相对比较简单。
To Be Continued……
  C# 最新文章
字符串阵列分别输出元素的索引,原值和长度
格式化你的字符串
C#宣告一个变量
C#中级
拆分一个字符串并把每个字符单独输出
通过手机号定位归属地
C# DBNULL与NULL之间的区别【转】
Xamarin
List,DataTable实现行转列的通用方案
C# 语音识别
上一篇文章      下一篇文章      查看所有文章
加:2017-12-08 23:22:03  更:2017-12-08 23:22:24 
 
360图书馆 软件开发资料 购物精选 新闻资讯 Chinese Culture 三丰软件 开发 中国文化 阅读网 头条阅读 学淘股 China Travel 日历 万年历 2020年7日历
2020-7-13 23:35:13
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  编程知识