美文网首页
面向对象的思想和基于接口的思想

面向对象的思想和基于接口的思想

作者: FakeCSer爱去网吧 | 来源:发表于2020-09-16 20:58 被阅读0次

(李林老师linux环境高级编程课后笔记)


架构的核心就是做到代码封闭性,即来了新的需求不用改老代码,只用增加新代码
核心要素:来一个变化点就新建一个体系结构
---李林老师


背景是实现一个加法器,对象中有一个数据成员作被加数,一个成员函数函数传入加数,返回和。
此加法器类实现起来很简单,如下代码

#include <iostream>
using namespace std;
class CLAdder
{
public:
    explicit CLAdder(int iAugend)
    {
    m_iAugend = iAugend;
    }

    int Add(int iAddend)
    {
    return m_iAugend + iAddend;
    }

private:
    int m_iAugend;
};

int main()
{
    CLAdder adder(2);
    cout << adder.Add(4) << endl;
   
    return 0;
}

现在来了一个变化点(新的需求):需要实现带权重的加法器的功能。
即输出 被加数*权重+加数

此时用 来一个变化点就新建一个继承体系 的思想,用c++面向对象思想来实现。

  • 面向对象的思想(继承+多态)


#include <iostream>
using namespace std;
class CLAdder
{
    public:
        explicit CLAdder(int iAugend)
        {
            m_iAugend = iAugend;
        }

        virtual ~CLAdder()
        {
        }

        virtual int Add(int iAddend)
        {
            return m_iAugend + iAddend;
        }

    protected:
        int m_iAugend;
};

class CLWeightingAdder : public CLAdder
{
    public:
        CLWeightingAdder(int iAugend, int iWeight) : CLAdder(iAugend)
    {
        m_iWeight = iWeight;
    }

        virtual ~CLWeightingAdder()
        {
        }

        virtual int Add(int iAddend)
        {
            return m_iAugend * m_iWeight + iAddend;
        }

    protected:
        int m_iWeight;
};

int main()
{
    //基类对象(不带权重的加法器)
    CLAdder adder(2);
    //基类指针指向基类对象
    CLAdder * p = &adder;
    cout << "CLAdder:" << p->Add(4) << endl;
  
    //派生类对象(带权重的加法器)
    CLWeightingAdder wadder(3, 4);
    
  //基类指针指向派生类对象
    p = &wadder;
    cout << "CLWeightAdder:" << p->Add(4) << endl;
    return 0;
}

c++中的多态思想,核心就是 基类指针指向派生类对象 ,c++的这个多态性质是虚函数机制支撑的。具体可以看另一个笔记:虚函数和虚表初步

  • 这种程序设计思想在架构中的好处

    在测试代码中,用户都是对基类指针进行操作,来了变化点也是对p进行操作,在复杂的业务环境中如
fun(CLAdder * p)
{
  ...
}

中,对fun的使用,即使来了变化点(加了权重),也不用对原本的fun函数进行修改,照样可以用,只要传进去的是派生类对象就可以,即做到了代码的封闭性,只加新代码不改老代码。

但是,这种设计方法也有不足的情况和更好的方案及基于接口的思想


此时又来了一个变化点,若基本的加法器是只能由两个无符号整数相加,这时实现一个有符号整数的、带权重的加法器。诚然,依据来一个变化点就加一个继承体系的思想,可以再接着设计一个派生类,加一个有符号数的数据成员,和自己的加法函数。但是,这样的话,派生类就继承了不必要的数据成员,产生了很多不必要的浪费。这样的设计却是犯了过度设计的缺点,并不是所有的变化点都是需求,此时有更好的方案。即基于接口的思想

  • 基于接口的思想


#include <iostream>
using namespace std;
class ILAdder
{
public:
    ILAdder()
    {
    }

    virtual ~ILAdder()
    {
    }

    virtual int Add(int iAddend) = 0;
};

class CLAdder : public ILAdder
{
public:
    explicit CLAdder(unsigned int iAugend)
    {
    m_iAugend = iAugend;
    }

    virtual ~CLAdder()
    {
    }

    virtual int Add(int iAddend)
    {
    return m_iAugend + iAddend;
    }

private:
    unsigned int m_iAugend;
};

class CLWeightingAdder : public ILAdder
{
public:
    CLWeightingAdder(int iAugend, int iWeight)
    {
    m_iWeight = iWeight;
    m_iAugend = iAugend;
    }

    virtual ~CLWeightingAdder()
    {
    }

    virtual int Add(int iAddend)
    {
    return m_iAugend * m_iWeight + iAddend;
    }

private:
    int m_iAugend;
    int m_iWeight;
};

void f(ILAdder *pAdder)
{
    cout << pAdder->Add(4) << endl;
}

int main()
{
    CLAdder adder(2);
    f(&adder);

    CLWeightingAdder wadder(3, 4);
    f(&wadder);
   
    return 0;
}

在此思想中用到了c++中的另一个机制,虚基类和纯虚函数。虚基类的实现为空,成员函数都为纯虚函数,就是要给子类重写用的。

  • 这种设计思想的好处



    在测试代码和原来的程序中,f()函数的参数类型是虚基类即接口的指针,根据传入的对象类型不同,调用的是不同的加法器的函数。并没有在来了需求后改老的代码( f() ),也做到了代码的封闭性。


对比和收获

  • 本质上都是多态的思想,面向对象的思想我理解其实是继承的思想,基于接口的思想是把原来的父子关系变成了兄弟关系。
  • 面向对象的思想是拿着基类指针来干活,基于接口的思想是拿着虚基类即接口的指针来干活。
  • 继承的思想是一种强耦合关系,无论需不需要,子类都完全继承了基类的数据成员,基类变了,所有的派生类都要变,耦合与接口(函数),耦合与实现(数据成员)。所以能少用继承就少用继承。
  • 想起以前设计类的时候,只会用继承关系,当时就觉得基类有些数据成员和函数其实派生类并不需要,但是又觉得派生类确实是要跟基类有联系的,就无脑用了继承,现在觉得耦合度确实太强了,并且会造成不必要的资源消耗。以后可以考虑接口的思想。

架构本质上就是解耦的过程,但是会增加很多的中间结构,可能会降低性能,需要在设计的时候来权衡。

相关文章

  • 面向对象的思想和基于接口的思想

    (李林老师linux环境高级编程课后笔记) 架构的核心就是做到代码封闭性,即来了新的需求不用改老代码,只用增加新代...

  • JavaScript进阶知识点--JS面向对象

    面向对象 对代码的一种抽象,对外同一提供调用接口的编程思想 基于原型的面向对象 基于原型的面向对象方式中,对象(o...

  • 何为面向接口编程

    面向接口编程不与面向对象编程同级,而是附属于面向对象编程思想,是面向对象编程思想的精髓之一。 定义 在系统分析和架...

  • 25天成为java大神之——对象-类(class)

    java学习贵在坚持 1:面向对象思想(理解) (1)面向对象是基于面向过程的一种编程思想 (2)思想特点: A:...

  • 面向对象

    面向对象思想面向对象基本概述面向对象是基于面向过程的编程思想。面向对象:强调的是每一个功能的步骤面向对象:强调的是...

  • 从事Android以来的相关总结1-JAVA技能

    ☆JAVA技能 «有良好的JAVA基础,熟练掌握面向对象思想: 理解面向对象: 面向对象是一种思想,是基于面向过程...

  • 面向对象(成员变量,成员方法)

    面向对象思想 概述:面向对象是基于面向过程的编程思想。面向过程:强调的是每一个功能的步骤面向对象:强调的是对象,然...

  • Java面向对象概述

    1.面向对象思想 面向对象是基于面向过程的编程思想 面向过程:强调的是每一个功能的步骤 面向对象:强调的是对象,然...

  • Java面向对象

    1.面向对象思想: 面向对象是基于面向过程的编程思想。 面向过程:强调的是每一个功能的步骤。 面向对象:强调的是对...

  • JS之面向对象

    什么是面向对象? 面向对象是一种编程思想,是在面向过程编程(结构化编程)之后出现的,面向对象的思想基于抽象数据类型...

网友评论

      本文标题:面向对象的思想和基于接口的思想

      本文链接:https://www.haomeiwen.com/subject/wfvhyktx.html