本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/43059759
在上一篇文章中介绍了“搬移字段”。本文将介绍“提炼类”这种重构手法。
下面让我们来学习这种重构手法吧。
发现:某个类做了应该由两个类做的事。
解决:建立一个新类,将相关的字段和函数从旧类搬移到新类。
我们或多或少听过这样的教诲:一个类应该是一个清楚的抽象,处理一些明确的责任。但是,在实际工作中,类会不断成长扩展。你会在这儿加一些功能,在那儿加入一些数据。 当给类添加新责任时,就会觉得不值得为这项责任分理出一个单独的类。于是,随着责任的不断增加,这个类会变得过分复杂。很快,类就会变成一团乱麻,继而你就越发不想管理。
这样的类往往含有大量函数和数据,往往太大而不易理解。此时,就需考虑哪些部分是可以分离出去的,并将它们分离到一个单独的类中。如果某些数据和某些函数总是一起出现,某些数据经常同时变化甚至彼此相依,这就说明应该将其分离处理。一个比较有用的测试就是问问自己:如果搬移了某些字段和函数,会发生什么事情?其它字段和函数是否会变得无意义?
还有一个值得注意的地方是类的子类化方式。如果发现子类化只影响类的部分特性,或如果发现某些特性需要以一种方式来子类化,而另一些特性则需要以另一种方式子类化,则意味着需要分解原来的类。
// 提炼类 class Person { private String _name; private String _officeAreaCode; private String _officeNumber; public String get_name() { return _name; } public String getTelephoneNumber() { return ("(" + _officeAreaCode + ")" + _officeNumber); } public String get_officeAreaCode() { return _officeAreaCode; } public void set_officeAreaCode(String areaCode) { _officeAreaCode = areaCode; } public String get_officeNumber() { return _officeNumber; } public void set_officeNumber(String number) { _officeNumber = number; } }在这个例子中,可以将与电话号码相关的行为分离到一个独立类中。首先需要定义一个TelephoneNumber类来表示“电话号码”这个概念:
class TelephoneNumber { }然后建立从Person到TelephoneNumber的连接:
class Person { //... private TelephoneNumber _officeTelephone = new TelephoneNumber(); }现在,可以运用“搬移字段”手法移动一个字段:
class TelephoneNumber { private String _areaCode; public String get_AreaCode() { return _areaCode; } public void set_AreaCode(String areaCode) { _areaCode = areaCode; } } class Person { //...... private TelephoneNumber _officeTelephone = new TelephoneNumber(); public String getTelephoneNumber() { return ("(" + get_officeAreaCode() + ")" + _officeNumber); } public String get_officeAreaCode() { return _officeTelephone.get_AreaCode(); } public void set_officeAreaCode(String areaCode) { _officeTelephone.set_AreaCode(areaCode); } }然后可以移动其它的字段,并运用“搬移函数”手法将相关函数移动到TelephoneNumber类中:
class Person { //...... private TelephoneNumber _officeTelephone = new TelephoneNumber(); private String _name; public String get_name() { return _name; } public String getTelephoneNumber() { return _officeTelephone.getTelephoneNumber(); } public TelephoneNumber getOfficeTelephone() { return _officeTelephone; } } class TelephoneNumber { private String _areaCode; private String _number; public String get_AreaCode() { return _areaCode; } public String getTelephoneNumber() { return ("(" + _areaCode + ")" + _number); } public void set_AreaCode(String areaCode) { _areaCode = areaCode; } public String getNumber() { return _number; } public void setNumber(String number) { _number = number; } }下一步要决定是否对用户公开这个新类?可以将Person中与电话号码相关的函数委托至TelephoneNumber,从而完全隐藏这个新类;也可以直接将它对用户公开。也可以将它公开给部分用户(位于同一个包中的用户),而不公开给其它用户。
原文:http://blog.csdn.net/pistolove/article/details/43059759