对象组合促进代码重用。 (T / F,为什么)

时间:2011-08-02 01:28:18

标签: c++ oop object-composition

我正在读考试,我正试图解决这个问题。具体问题是“继承和对象组合都促进了代码重用。(T / F)”,但我相信我理解了问题的继承部分。

我相信继承促进了代码重用,因为类似的方法可以放在抽象基类中,这样类似的方法就不必在多个子类中相同地实现。例如,如果你有三种形状,并且每个形状的方法“getName”只返回一个数据成员'_name',那么为什么在每个子类中重新实现这个方法时,它可以在抽象基础中实现一次阶级“形状”。

但是,我对对象组合的最好理解是对象/类之间的“有一个”关系。例如,学生有学校,学校有很多学生。这可以看作是对象组成,因为它们之间没有真正存在(没有任何学生的学校不完全是学校,是吗?等等)。但我认为这两个对象作为数据成员彼此“拥有”不会促进代码重用。

有任何帮助吗?谢谢!

5 个答案:

答案 0 :(得分:5)

对象组合可以促进代码重用,因为您可以将实现委托给不同的类,并将该类包含为成员。

您可以使用较小的范围和较小的方法创建较小的类,并在整个代码中重用这些类/方法,而不是将所有代码放在最外层的方法中。

class Inner
{
public:
    void DoSomething();
};

class Outer1
{
public:
    void DoSomethingBig()
    {
        // We delegate part of the call to inner, allowing us to reuse its code
        inner.DoSomething();
        // Todo: Do something else interesting here
    }

private:
    Inner inner;
};

class Outer2
{
public:
    void DoSomethingElseThatIsBig()
    {
        // We used the implementation twice in different classes,
        // without copying and pasting the code.

        // This is the most basic possible case of reuse

        inner.DoSomething();

        // Todo: Do something else interesting here
    }


private:
    Inner inner;
};

正如您在问题中提到的,这是两个最基本的面向对象编程主体之一,称为“has-a relationship”。继承是另一种关系,被称为“is-a replationship”。

您还可以以非常有用的方式组合继承和组合,这通常会使您的代码(和设计)重用潜力倍增。任何真实世界和架构良好的应用程序都将不断地将这两个概念结合起来,以获得尽可能多的重用。当您了解设计模式时,您会发现这一点。

修改

Per Mike在评论中的要求,一个不那么抽象的例子:

// Assume the person class exists

#include<list>

class Bus
{
public:
    void Board(Person newOccupant);
    std::list<Person>& GetOccupants();

private:
    std::list<Person> occupants;
};

在此示例中,您已将其委派给列表类,而不是重新实现链接列表结构。每次使用该列表类时,都会重新使用实现列表的代码。

事实上,由于列表语义如此常见,C ++标准库为您提供了std::list,您只需重用它。

答案 1 :(得分:3)

1)学生知道学校,但这不是一个HAS-A关系;虽然你想要跟踪学生所在的学校,但将学校描述为学生的一部分是不合逻辑的。

2)与学生相比,更多人占用学校。这就是重复使用的地方。每次你描述一种新型的学校参与者时,你不必重新定义组成学校的东西。

答案 2 :(得分:3)

我必须同意@Karl Knechtel - 这是一个非常糟糕的问题。正如他所说,很难解释原因,但我会试一试。

第一个问题是它使用了一个术语而没有定义它 - 而“代码重用”对不同的人来说意味着很多不同的东西。对某些人来说,剪切和粘贴符合代码重用的要求。尽管我喜欢它,但我必须至少在某种程度上同意它们。其他人定义鳕鱼重用的方式排除切割和粘贴为代码重用(将相同代码的另一个副本分类为单独的代码,而不是重用相同的代码)。我也可以看到这个观点,尽管我倾向于认为他们的定义更倾向于服务于特定的结束而不是真正有意义的结果(即“代码重用” - &gt; good,“cut-n-paste” - &gt; bad,因此“cut-n-paste”!=“代码重用”)。不幸的是,我们在这里看到的就是边界,在你回答这个问题之前,你需要一个非常具体的代码重用定义。

你的教授使用的定义很可能在很大程度上取决于他对OOP的热情程度 - 尤其是在OOP刚刚成为主流的90年代(左右),很多人选择以仅包含酷炫的新OOP“东西”的方式来定义它。要实现代码重用的必杀技,你不仅要注册他们的OOP宗教信仰,而且要真正相信!像作品一样平凡的东西不可能有资格 - 无论多么奇怪,他们必须扭曲语言才能成为真实。

作为第二个重点,经过几十年的OOP使用,一些人已经对哪些代码被重用以及什么没有重复进行了一些相当仔细的研究。我见过的大多数都得出了一个相当简单的结论:将编码风格与重用相关联是非常困难的(即,基本上不可能)。您尝试对将要或不会导致代码重用的内容做出的几乎任何规则都会定期违反。

第三,我怀疑在许多人看来最重要的事实是,提出这个问题听起来好像这可能会影响一个典型的程序员 - 你可能想要选择组合和继承之间(例如)基于“促进代码重用”更多,或在该顺序上的东西。现实情况是(仅举例)你应该在构图和继承主要之间进行选择,根据这些更准确地模拟你试图解决的问题,以及哪些更能帮助你解决这个问题。 / p>

虽然我没有任何认真的研究来支持这一论点,但我认为该代码被重用的可能性很大程度上取决于大多数研究中很少考虑的几个因素:1)其他人需要解决的问题,以及2)他们是否认为使代码适应问题比编写新代码更容易。

我应该在我已经看到的一些中添加 因素,这些因素似乎会影响代码重用。在我的记忆中,最重要的一点就是代码本身,但是文档可用代表代码。能够在没有基本逆向工程的情况下使用代码,它为重用它做出了巨大贡献。第二点只是代码的质量 - 许多研究是在他们试图促进代码重用的地方/情况下完成的。在相当多的情况下,人们尝试重用比实际更多的代码,但不得不放弃它只是因为代码不够好 - 从bug到笨拙的可移植性接口阻止了重用。

总结:我会记录在案的说法,至少在过去的几十年中,代码重用可能是软件工程中最过分,最不充分的承诺。即使充其量,代码重用仍然是一个相当难以实现的目标。试图将其简化到基于两个因素将其视为真/假问题的观点是过分简化问题,以至于它不仅毫无意义,而且完全荒谬。它几乎琐碎并贬低了软件工程的整个实践。

答案 3 :(得分:2)

我有一个对象Car和一个对象引擎:

class Engine {
     int horsepower;
}

class Car {
     string make;
     Engine cars_engine;
}

汽车有引​​擎;这是作文。但是,我不需要重新定义引擎以将引擎放入汽车 - 我只是说汽车有引擎。因此,组合确实促进了代码重用。

答案 4 :(得分:2)

对象组合确实促进了代码的重用。如果没有对象组合,如果我理解你对它的定义,每个类只能有原始的数据成员,这将是非常糟糕的。

考虑课程

class Vector3
{
    double x, y, z;
    double vectorNorm;
}

class Object
{

    Vector3 position;
    Vector3 velocity;
    Vector3 acceleration;
 }

如果没有对象组合,您将被迫拥有类似

的内容
class Object
{

    double positionX, positionY, positionZ, positionVectorNorm;
    double velocityX, velocityY, velocityZ, velocityVectorNorm;
    double accelerationX, accelerationY, accelerationZ, accelerationVectorNorm;
 }

这只是一个非常简单的例子,但我希望你能看到最基本的对象组合如何促进代码重用。现在想想如果Vector3包含30个数据成员会发生什么。这是否回答了你的问题?