Композиция объектов способствует повторному использованию кода. (T / F, почему) - PullRequest
5 голосов
/ 02 августа 2011

Я готовлюсь к экзамену и пытаюсь выяснить этот вопрос.Конкретный вопрос: «Наследование и состав объектов способствуют повторному использованию кода. (T / F)», но я полагаю, что понимаю часть вопроса о наследовании.помещены в абстрактный базовый класс, так что подобные методы не должны быть одинаково реализованы в нескольких дочерних классах.Например, если у вас есть три вида фигур, и метод каждой фигуры «getName» просто возвращает элемент данных «_name», то зачем повторно реализовывать этот метод в каждом из дочерних классов, если его можно реализовать один раз в абстрактной базеclass "shape".

Однако мое лучшее понимание композиции объектов - это отношения "has-a" между объектами / классами.Например, у ученика есть школа, а в школе есть несколько учеников.Это можно рассматривать как композицию объектов, поскольку они не могут существовать друг без друга (школа без учеников не совсем школа, не так ли?).Но я не вижу способа, чтобы эти два объекта, «имеющие» друг друга в качестве члена данных, способствовали бы повторному использованию кода.

Любая помощь?Спасибо!

Ответы [ 5 ]

5 голосов
/ 02 августа 2011

Композиция объектов может способствовать повторному использованию кода, поскольку вы можете делегировать реализацию другому классу и включить этот класс в качестве члена.

Вместо того, чтобы помещать весь ваш код в методы ваших самых внешних классов, вы можете создавать меньшие классы с меньшими областями действия и меньшими методами и повторно использовать эти классы / методы в своем коде.

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;
};

Как вы упомянули в своем вопросе, это один из двух самых основных принципов объектно-ориентированного программирования, который называется "имеет отношение". Наследование - это другое отношение, и оно называется «это отношение».

Вы также можете комбинировать наследование и композицию весьма полезными способами, которые часто увеличивают потенциал повторного использования вашего кода (и дизайна). Любое реальное и хорошо спроектированное приложение будет постоянно сочетать обе эти концепции, чтобы получить как можно больше повторного использования. Вы узнаете об этом, когда узнаете о шаблонах проектирования.

Edit:

По просьбе Майка в комментариях, менее абстрактный пример:

// 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, и вам просто пришлось использовать ее повторно.

3 голосов
/ 02 августа 2011

Я должен согласиться с @Karl Knechtel - это довольно плохой вопрос.По его словам, трудно объяснить почему, но я попробую.

Первая проблема заключается в том, что он использует термин, не определяя его, а «повторное использование кода» означает много разных вещей.для разных людей.Для некоторых людей вырезание и вставка квалифицируются как повторное использование кода.Как бы мне это ни нравилось, я должен с ними согласиться, по крайней мере, до некоторой степени.Другие люди определяют повторное использование трески способами, исключающими повторное использование и вставку как повторное использование кода (классификация другой копии того же кода в качестве отдельного кода, без повторного использования того же кода).Я тоже вижу эту точку зрения, хотя склоняюсь к тому, что их определение больше предназначено для достижения конкретной цели, чем для того, чтобы быть действительно значимым (т. Е. «Повторное использование кода» -> хорошо, «вырезать-вставить» -> плохо, поэтому »cut-n-paste "! =" повторное использование кода ").К сожалению, то, что мы смотрим здесь, находится прямо на границе, где вам нужно очень точное определение того, что означает повторное использование кода, прежде чем вы сможете ответить на вопрос.

Определение, используемое вашим профессором: вероятно, будет сильно зависеть от степени его энтузиазма по отношению к ООП - особенно в 90-е годы (или около того), когда ООП только становился мейнстримом, многие люди решили определять его таким образом, чтобы он включал только классную новую ООП "вещи».Чтобы достичь нирваны повторного использования кода, вы должны были не только подписаться на их ООП-религию, но и действительно поверить в нее !Нечто столь же обыденное, как композиция, не может быть квалифицировано - независимо от того, как странно они должны были искажать язык, чтобы это было правдой.

В качестве второго важного момента, после десятилетий использования ООП, несколько человекпровели довольно тщательные исследования того, какой код был повторно использован, а какой нет.Большинство из того, что я видел, пришли к довольно простому выводу: довольно сложно (т. Е. Практически невозможно) соотнести стиль кодирования с повторным использованием.Почти любое правило, которое вы пытаетесь сформулировать относительно того, что приведет или не приведет к повторному использованию кода, может и будет нарушаться на регулярной основе.

В-третьих, и то, что я подозреваю, имеет тенденцию быть главным в умах многих людей, так этотот факт, что если задавать вопрос вообще, звучит так, как будто это то, что может / повлияет на типичного кодера - что вы можете выбрать между композицией и наследованием (например), основываясь на том, что больше «способствует повторному использованию кода», иличто-то в этом порядке.Реальность такова, что (только для примера) вам следует выбирать между составом и наследованием , в первую очередь , основываясь на том, какие модели более точно моделируют проблему, которую вы пытаетесь решить, и на том, что поможет вам решить эту проблему.

Хотя у меня нет серьезных исследований, подтверждающих это утверждение, я бы сказал, что вероятность повторного использования этого кода будет сильно зависеть от пары факторов, которые редко даже учитываются в большинстве исследований: 1) насколько похожипроблемы, которую должен решить кто-то другой, и 2) считают ли они, что легче будет адаптировать ваш код к своей проблеме, чем писать новый код.

Я должен добавить это в некотором Из исследований, которые я видел, было обнаружено факторов , которые, по-видимому, влияли на повторное использование кода.Насколько я помню, тот, кто выделялся как самый важный / говорящий, был вовсе не сам код, а доступная документация для этого кода.Будучи способным использовать код без по сути реинжиниринга, он вносит большой вклад в его повторное использование.Вторым моментом было просто качество кода - ряд исследований проводился в местах / ситуациях, где они пытались способствовать повторному использованию кода.В большинстве случаев люди пытались повторно использовать немного больше кода, чем на самом деле, но им пришлось отказаться от него просто потому, что код был недостаточно хорош - от ошибок до неуклюжихинтерфейсы из-за плохой переносимости препятствуют повторному использованию.

Резюме: я официально заявлю, что повторное использование кода, вероятно, было самым преувеличенным, недооцененным обещанием в разработке программного обеспечения за последние пару десятилетий.Даже в лучшем случае повторное использование кода остается довольно труднодостижимой целью.Попытка упростить его до такой степени, чтобы рассматривать его как истинный / ложный вопрос, основанный на двух факторах, упрощает вопрос до такой степени, что он не только бессмысленный, но и совершенно нелепый.Похоже, это упрощает и унижает почти всю практику разработки программного обеспечения.

3 голосов
/ 02 августа 2011

1) Учащийся знает о школе, но на самом деле это не отношения HAS-A; хотя вы хотите отслеживать, какую школу посещает ученик, было бы нелогично описывать школу как часть ученика.

2) В школе больше людей, чем просто учеников. Вот тут-то и возникает повторное использование. Вам не нужно переопределять то, что составляет школу, каждый раз, когда вы описываете новый тип школьника.

2 голосов
/ 02 августа 2011

Композиция объектов способствует повторному использованию кода. Без составления объекта, если я правильно понимаю ваше определение, каждый класс мог бы иметь только примитивные члены-данные, что было бы ужасно.

Рассмотрим классы

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 элементов данных. Это отвечает на ваш вопрос?

2 голосов
/ 02 августа 2011

У меня есть объект Автомобиль и объект Двигатель:

class Engine {
     int horsepower;
}

class Car {
     string make;
     Engine cars_engine;
}

Автомобиль имеет двигатель; это композиция. Однако мне не нужно переопределять Engine, чтобы поместить двигатель в автомобиль - я просто говорю, что у автомобиля есть двигатель. Таким образом, композиция действительно способствует повторному использованию кода.

...