Разработка программного обеспечения Java: состав против агрегации - PullRequest
1 голос
/ 08 ноября 2019

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

public class Engine {

    public Engine() {

    }
}

public class Car1 {

    public final Engine engine;

    public Car1() {
        engine = new Engine();

    }

}

class Car2{

    public Engine engine;

    public Car2(Engine engine) {
        this.engine = engine;
    }
}

class Car3{

    public final Engine engine;

    public Car3(Engine engine) {
        this.engine = engine;
    }
}

class Car4{

       Engine engine;

       public Car4(){

        this.engine = new Engine();

       }

}


class Main{

    public static void main(String[] args) {

        Engine engine = new Engine(); 
        Car1 car1 = new Car1(); 

        Car2 car2_1 = new Car2(new Engine());
        Car2 car2_2 = new Car2(engine);

        Car3 car3_1 = new Car3(new Engine());
        Car3 car3_2 = new Car3(engine);

        Car4 car4_1 = new Car4();

    }
}

По моему мнению, car1, car2_1, car3_1 следуют логике составления. Но я читал много мест, где car3_2 также является композицией. Почему? Если мы уничтожим car3_2, экземпляр двигателя все равно будет существовать, так что это должно быть Aggregation.

Ответы [ 3 ]

0 голосов
/ 08 ноября 2019

Я полагаю, что в Java различия трудно увидеть, так как для любого объекта вы можете хранить только ссылки на какое-то место в куче, тогда как в других языках программирования, таких как C ++, вы можете выбрать, будет ли один объект содержать ссылку на другой объект против одного объекта. встроенная копия этого объекта.

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

Я бы предпочел, чтобы у car4 не было пакета (по умолчанию), нодаже частный доступ. Это означало бы, что никто не должен иметь доступ к этой ссылке на движок (если это не просочилось в другое место), и вы могли бы говорить о композиции.

Редактировать: перечитывая ваш вопрос и пример кода до конца, я думаю, что вопрос заключается в том, какони построены. Car1 и car4_1 поставляются с собственными двигателями, созданными неявно, и, поскольку никто не берет ссылку, автомобили и двигатели собирают мусор одновременно. Я бы назвал эту композицию.

Car2_1 и car3_1 ведут себя одинаково, хотя двигатель был сконструирован явно. Они будут собирать мусор вместе с соответствующими двигателями. Это ведет себя аналогично, но также позволяет следующий шаблон. Я предполагаю, что это было введено как приманка.

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

0 голосов
/ 09 ноября 2019
  • Агрегация подразумевает отношения, в которых ребенок может существовать независимо от родителя. Пример: класс (родитель) и ученик (ребенок). Удалите класс, и ученики все еще существуют.
  • Композиция подразумевает отношения, в которых ребенок не может существовать независимо от родителя. Пример: Дом (родитель) и Комната (ребенок). Комнаты не существуют отдельно от Дома.

Таким образом, по самой своей природе, не может быть Композицией для любого объекта, который:

  • может быть владельцем более чем одним другим объектом
  • может быть неизвестным (после завершения инициализации)
  • может сменить владельца

car3_2 не может быть Composition, поскольку он разделяет движок с car2_2.

Все остальные Composition? Говоря логически, в Real Life вы можете снять двигатель с автомобиля и установить его в другой автомобиль, так что отношение автомобиля к двигателю - Агрегирование.

Программно, ключевое слово finalпредотвращает удаление Engine из Car, но не препятствует тому, чтобы тот же двигатель был добавлен к другому автомобилю, и это не препятствует тому, чтобы автомобиль был "удален" и двигатель сменил владельца, поэтому *Сам по себе 1042 * не гарантирует отношения Composition.

Когда конструктор принимает в качестве параметра механизм, класс Car не может гарантировать, что механизм не является общим, поэтому не гарантирует отношение Composition.

Только когда Engine создан конструктором Car и поле имеет значение final (или эффективно-окончательное, по существу private без метода установки), гарантируется, что определениеКомпозиция соблюдается.

Не означает, что другие, которые принимают Engine в качестве параметра, не могут эффективно быть композицией. Это зависит от того, как оно используется. Например, если Car создан классом Factory, фабрика может применять правила композиции.

0 голосов
/ 08 ноября 2019

Да, двигатель все еще существует вне экземпляра car3_2, так что это должно быть Aggregation.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...