当前位置 博文首页 > 文章内容

    第11章 处理概括关系

    作者: 栏目:未分类 时间:2020-08-28 15:01:23

    本站于2023年9月4日。收到“大连君*****咨询有限公司”通知
    说我们IIS7站长博客,有一篇博文用了他们的图片。
    要求我们给他们一张图片6000元。要不然法院告我们

    为避免不必要的麻烦,IIS7站长博客,全站内容图片下架、并积极应诉
    博文内容全部不再显示,请需要相关资讯的站长朋友到必应搜索。谢谢!

    另祝:版权碰瓷诈骗团伙,早日弃暗投明。

    相关新闻:借版权之名、行诈骗之实,周某因犯诈骗罪被判处有期徒刑十一年六个月

    叹!百花齐放的时代,渐行渐远!



    《重构 改善既有代码的设计》 第十一章 --处理概括关系

    字段上移(Pull Up Field)

    1.概念:两个子类拥有相同的字段,将字段移至超类。

    2.动机:子类如果是分别开发的,可能具有重复的特性,特别是字段容易重复,如果确认了字段的使用方式很相似,就可以把它们归到超类去。

     

    函数上移(Pull Up Method)

    1.概念:有些函数,在各个子类中产生完全相同的结果,则将函数移至超类。

    2.动机:一种情况是类似字段上移的动机,还有一种情况是子类的函数覆写了超类的函数,却仍然做着相同的工作,此时也需要将函数上移。

    3.做法:注意因为子类中的函数并不相同,我们必须在超类中声明它们的抽象函数。

     

    构造函数本体上移(Pull Up Constructor Body)

    1.概念:你在各个子类中拥有一些构造函数,它们的本体几乎完全一致。则在超类中新建一个构造函数,并在子类构造函数中调用它。

    2.动机:如果你看见各个子类中的函数有共同的行为,首先应该想到将它们的共同行为提炼到一个独立函数中,然后将这个类提升为超类。对于构造函数来说,子类共同的行为就是“对象的构建”。

    3.做法:

    (1)在超类中定义一个构造函数。

    (2)将子类构造函数中的共同代码搬移到超类构造函数中。

    (3)将子类构造函数共同代码删掉,改而调用新建的超类构造函数。

    (4)编译,测试。

    //超类
    class
    Emploee { protected Employee(String name, String id) { this.name = name; this.id = id; } }
    //子类中调用
    public Manager(String name, String id, int grade) {
        super(name, id);
        this.grade = grade;
    }

     

    函数下移(Push Down Method)

    1.概念:超类中的某个函数只与部分(而非全部)子类有关,则将这个函数移到相关的那些子类中去。

     

    字段下移(Push Down Field)

    1.概念:超类中的某个字段只被部分(而非全部)子类用到,则将这个字段移到需要它的那些子类去。

     

    提炼子类(Extract Subclass)

    1.概念:类中的某些特性只被某些(而非全部)实例用到,则新建一个子类,将上面说的那一部分特性移到子类中。

    提炼超类(Extract Superclass)

    1.概念:

    两个类有相似的特性,则为这两个类建立一个超类,将相同特性移至超类。

     

    提炼接口(Extract Interface)

    1.概念:

    若干客户使用类接口中的同一子集,或者两个类的接口有部分相同,则将相同的子集提炼到一个独立接口中。

    2.动机;

    类彼此之间有很多种互用的方式,“使用一个类”通常意味着用到该类的所有责任区。但如果一组客户只使用到类责任区中的一个特定子集,或者这个类需要与所有协助处理某些特定请求的类合作,面对这两种情况,将这部分用到的职责分离出来就很有意义。这样使用法更清晰,责任划分更清晰。

     

    折叠继承体系(Collapse Hierarchy)

    1.概念:

    超类和子类之间无太大区别,则将它们合为一体。

     

    塑造模板函数(Form TemPlate Method)

    1.你有一些子类,其中相应的某些函数以相同顺序执行类似的操作,但各个操作的细节上有所不同。则将这些操作分别放进独立函数中,并保持他们都有相同的签名,于是原函数也就变得相同了,然后将原函数上移至超类。

    (略,待细看)

     

    以委托取代继承(Replace Inheritance with Delegation)

    1.概念:

    某个子类只使用超类接口中的一部分,或是根本不需要继承而来的数据,则在子类中新建一个字段用以保存超类,然后调整子类函数,令它改而委托超类,最后去掉两者之间的继承关系。

    (委托:在A类中实例化B类对象,并在A类方法中通过实例出的B类对象返回B类的东西)

    2.动机:

    继承虽好,但并不一定是你想要的。当一开始继承了一个类,然后发现超类中很多操作并不真正适用于子类,则改用委托取代继承。

    3.做法:

    滥用继承的一个典型的范例就是让stack类继承Vector类,其中客户端Stack只需要做4件事,push(), pop(), 还有从vector继承来的size(), isEmpty():

    //原式
    class
    MyStack extends Vector { public void push(Object element) { insertElement(element, 0); } public Object pop() { Object result = firstElement(); removeElementAt(0); return result; } }

    (1)在子类中新建一个字段,使其引用超类的一个实例,并将它们初始化为this。

    (2)修改子类内的所有函数,让它们不再使用超类,转而使用上述的受托字段,每次修改后,编译并测试。

    class Mystack extends Vector {
        private Vector vector = this;
    
        public void push(Object element) {
            vector.insertElementAt(element, 0);
        }
    
        public Object pop() {
            Object result = vector.firstElement();
            vector.removeElementAt(0);
            return result;
        }
    }

    (3)去除两个类之间的继承关系,新建一个受托类的对象赋给受托字段。

    (4)针对客户端所用的每一个超类函数,为它添加一个简单的委托函数。

    class Mystack {
        private Vector vector = new Vector();
    
        //添加委托函数
        public int size() {
            return vector.size();
        }
    
        public boolean isEmpty() {
            return vector.isEmpty();
        }
    }

     

    以继承取代委托(Replace Delegation with Inheritance)

    1.概念:

    你在两个类之间使用委托关系,并经常为整个接口编写许多极简单的委托函数,则让委托函数继承受托类。

    2.动机:

    与“以委托取代继承”相反,如果你发现自己需要使用受托类中所有函数,并花了很大力气编写所有极简的委托函数时,用此重构。