zoukankan      html  css  js  c++  java
  • 第11章 处理概括关系

    字段上移(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.动机:

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

  • 相关阅读:
    用 Flask 来写个轻博客 (31) — 使用 Flask-Admin 实现 FileSystem 管理
    jenkins持续集成:jenkins+SVN
    Linux基础一:Linux的安装及相关配置
    jenkins持续集成:构建多个job同时执行
    jenkins持续集成:定时构建语法
    Nginx详解二十九:基于Nginx的中间件架构设计
    Nginx详解二十八:Nginx架构篇Nginx+Lua的安全waf防火墙
    Nginx详解二十七:Nginx架构篇之安全篇
    Nginx详解二十六:Nginx架构篇之性能优化
    Nginx详解二十五:Nginx架构篇之Nginx常见的问题
  • 原文地址:https://www.cnblogs.com/wencheng9012/p/13566462.html
Copyright © 2011-2022 走看看