Моделировать ли автомобильный объект (и его части, такие как двигатель) с has-a (состав) или is-a (наследование)? - PullRequest
4 голосов
/ 16 декабря 2009

Я занимаюсь разработкой библиотеки классов, которая будет включать объект Car.

Дилемма заключается в том, что автомобиль будет классом с такими полями, как регистрационный номер и другая общая информация об автомобиле.

Но у автомобиля есть двигатель, ходовая часть и т. Д. Эти объекты тоже нужно моделировать. Должны ли они быть классами, встроенными в Car? Если нет, каков сценарий использования встроенного класса?

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

Куда мне идти?

РЕДАКТИРОВАТЬ: Я в настоящее время на домашнее задание, поэтому отсутствие ответа от меня. Библиотека классов предназначена для веб-приложений, основанных на автомобилях. Я профессиональный разработчик (я работаю в .NET для жизни, но для юниоров), так что это не домашнее задание.

Спасибо

Ответы [ 7 ]

4 голосов
/ 16 декабря 2009

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

Да, у машины будет "иметь" двигатель, но я бы предложил использовать интерфейс для этого и аналогичных отношений "имеет". Опять же, в зависимости от профессора, вы можете получить бонусные баллы за то, что фабрика создала разные машины (уместно, нет?):

public class Car
{
    private Engine engine;
    public Car(Engine engine)
    {
        this.engine = engine;
    }

    public void accelerate()
    {
        this.engine.goFaster();
    }

    public void decelerate()
    {
        this.engine.goSlower();
    }

}

public interface Engine
{
    public void goFaster();
    public void goSlower();
}


public class ReallyFastEngine implements Engine
{
    public void goFaster()
    {
    // some code that goes really fast
    }
    public void goSlower()
    {
    // some code that goes slower
    }    
}

public class NotAsFastEngine implements Engine
{
    public void goFaster()
    {
    // some code that goes not as fast
    }
    public void goSlower()
    {
    // some code that goes slower
    }    
}

public class CarFactory()
{
    public static Car createFastCar()
    {
         return new Car(new ReallyFastEngine());
    }

    public static Car createNotAsFastCar()
    {
         return new Car(new NotAsFastEngine());
    }
}
4 голосов
/ 16 декабря 2009

Это действительно зависит от вашего приложения.

Например, вы могли бы реализовать колеса как отдельные классы, содержащие информацию о том, какая шина на нем, как она изношена и т. Д., Но если ваше приложение даже не заботится о колесах, тогда весь класс - пустая трата кода.

Я вижу три варианта использования для композиции:

  • Класс владения стал слишком сложным и должен быть разбит.
  • Класс-владелец имеет несколько копий набора свойств, которые могут быть сопоставлены с классом. Это позволяет связать все эти свойства вместе.
  • Содержащийся объект может нуждаться в осмотре или рассмотрении отдельно от объекта, которому он принадлежит (например, вы можете переместить объект Engine на другой автомобиль) или может быть заменен как единое целое.

В итоге: Использование композиции в качестве инструмента для инкапсуляции сложности или устранения повторений. Если он не служит ни одной из этих целей, вероятно, не стоит создавать новый класс.

2 голосов
/ 17 декабря 2009

Разбивайте модель автомобиля только на части, которые будут видны как отдельные объекты за пределами автомобиля. Еще один способ думать об этом - ты действительно понимаешь, как заводится твой автомобиль, когда ты поворачиваешь ключ? Что касается типичного водителя, то все под капотом - это один большой (и шумный) черный ящик. Автоинженеры знают общие детали, которые требуют обслуживания со стороны владельца автомобиля, и специально разработали их для различного уровня взаимодействия с пользователем, например, заправочный стержень масляного щупа или крышка для заправки бачка охлаждающей жидкости.

Можете ли вы смоделировать каждую часть автомобиля? Конечно. Полезно ли моделировать отдельные свечи зажигания? Возможно нет.

Вам нужны машины с разными атрибутами, такими как цвет или размер? Вам нужны автомобили с различными возможностями, такими как пассажирский или буксирный? Одно место, которое отличается, если вам нужны машины с другим поведением. Здесь вам действительно нужно подумать о моделировании объекта Driver, который имеет атрибуты, от простых, таких как время реакции, до сложных, таких как агрессивность.

Моделирование транспортных средств в качестве примеров ориентации или наследования объектов проблематично, потому что примеры на самом деле не объясняют истинных различий между существенными атрибутами, которые определяют класс. Это не новость в StackOverflow, но этот вопрос также не является дубликатом, см. Эту ветку SO . У меня была такая же дискуссия с моим другом, и я разместил запись в своем блоге . Читайте о различных типах воздушных судов, которые FAA признает, и о том, как подразделяются правила для каждого типа. Есть много разных типов самолетов, самое большое разделение между двигателями и без двигателя.

Проверьте определения , используемые FAA :

Самолет означает устройство, которое используется или предназначен для использования для полета в воздух.

Самолет означает двигатель с приводом самолеты тяжелее воздуха, что поддерживается в полете динамическая реакция воздуха против его крылья.

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

Есть также легче воздуха и тяжелее воздуха. Воздушный шар не имеет силы и легче воздуха. Дирижабль работает и легче воздуха. Планер не имеет сил и тяжелее воздуха. Boeing 757 оснащен двигателем и тяжелее воздуха, но добавляет еще одну категорию «неподвижных крыльев», которая не похожа на вертолет, который также имеет мощность и тяжелее воздуха, но имеет «вращающиеся крылья».

Вот первые четыре в виде таблицы:

                 |  Powered   |    Unpowered
---------------------------------------------------
Lighter-than-air |  Blimp     |    Hot-air balloon 
Heavier-than-air |  737       |    Glider

Вы получите изображение.

Нельзя просто сказать, что вы будете моделировать двигатель отдельно от автомобиля, потому что автомобиль без двигателя может быть совершенно другим животным. Автомобиль без двигателя - не что иное, как трейлер, у которого также нет двигателя, но и никогда не будет. В этих случаях ни «is-a», ни «has-a» не соответствуют конкретному способу создания объектов. Вы не объявляете дирижабль самолетом, который легче воздуха, как воздушный шар. Тот факт, что они оба легче воздуха, никак не связывает их, кроме физики, которой они пользуются. Различие важно, потому что применяемые правила и положения различны. С другой стороны, мы не описываем дирижабль как воздушный шар, у которого есть двигатель. Самолеты физически не связаны, отношения должны быть такими, какими они должны быть.

Если вам не нужно определять ваши объекты с таким уровнем детализации, вам может не потребоваться моделировать их с таким уровнем детализации.

2 голосов
/ 16 декабря 2009

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

"Определили ли они класс двигателя"

"Есть ли у него разумные методы, такие как Start ()"

"Отметьте их за то, что они смешали все в одном большом классе, который на самом деле проще, потому что они явно не понимают композицию"

Или что-то еще, а не те стандарты, которые более прагматичные люди в этой теме применяют к своим собственным проектам.

0 голосов
/ 17 декабря 2009

Это зависит от того, что вы пытаетесь сделать. Попытка разработать класс «Автомобиль» (или любой другой класс в этом отношении) без представления вариантов использования - бесполезное упражнение.

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

0 голосов
/ 16 декабря 2009

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

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

Например, скажем, если вы создали переменную экземпляра, которая ссылается на
Объект Engine и эта переменная инициализируются в конструкторе Car.And
у вашего класса Engine есть несколько методов, которые нужно протестировать. Тогда как можно
Вы добавляете модульные тесты для проверки кода в классе Engine? Вероятно, вы бы
есть некоторые методы в классе Car, которые показывают поведение или класс Engine, позволяющий
вам написать модульные тесты. Тогда возникает вопрос, есть ли необходимость выставить
поведение класса Engine не лучше, чем класс Engine
стоит самостоятельно?

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

0 голосов
/ 16 декабря 2009

Автомобиль будет объектом высшей иерархии. Включая простые поля, такие как номер, идентификатор или описание. И будет иметь сложные поля, такие как Engine, который сам по себе является объектом.

Так машина будет выглядеть примерно так:

class Car{
     String ID;
     Engine engine;
}

Это отношение имеет отношение.

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