Создание пространства имен -> Класс -> Вложенный класс? или же - PullRequest
0 голосов
/ 06 сентября 2011

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

Я приведу вам (почти) пример из реальной жизни:

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

Теперь, скажем, завод производит автомобили, лодки и самолеты.Поэтому я добавлю три класса в мое Factory пространство имен с этими именами.

Вот где моя проблема с пониманием других методов:

У меня есть некоторые общие черты между тремя типамитранспортные средства.Например, у них у всех есть двигатель (могут быть разные HP или формы, которые, как я понимаю, являются свойствами двигателя, но все же у них у всех есть двигатель).Кроме того, у автомобилей и самолетов есть двери (иногда лодки тоже).С другой стороны, у них также есть некоторые уникальные вещи (например, у самолетов есть пропеллеры, которые могут быть разных размеров или форм).

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

Ответы [ 6 ]

7 голосов
/ 06 сентября 2011

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

Какова цель пространства имен?

Основная цель пространства имен состоит в организуйте объявления типов в иерархию, чтобы пользователи могли легко их найти.

Вторичной целью пространства имен является обеспечение механизма устранения неоднозначности коллизий имен.То есть, если XYZ Corp имеет тип Vehicle, а ABC Inc имеет тип Vehicle, и PQR Ltd хочет использовать код из XYZ и ABC одновременно, программистам PQR нужен способ сообщить компилятору, какой тип «Vehicle» на самом делеотносится к.

Вы предлагаете назвать свое пространство имен "Фабрика".Это, вероятно, плохая идея.Фабрика - это, вероятно, класс, а не пространство имен.Фабрика - это не вещь, а способ организации вещей.Я был бы склонен назвать свое пространство имен "Dementic.Manufacturing" и включить его в класс Factory.Теперь все организовано двумя способами: во-первых, компанией Dementic Incorporated, которая производит код, и тем, с чем связан код, а именно с производством.И вряд ли кто-то из ваших конкурентов также создаст пространство имен под названием Dementic.Manufacturing.

Когда мне следует создавать вложенный тип в отличие от типа верхнего уровня?

Создать вложенный тип, если вложенный тип представляет собой подробность реализации внешнего типа.Обычно считается плохой практикой делать открытый вложенный тип, хотя иногда это делается.

Типичным примером является класс перечислителя;обычно это частная реализация реализации перечислимой коллекции.

2 голосов
/ 06 сентября 2011

Вы неправильно поняли, что такое пространства имен. Пространства имен не имеют к этому никакого отношения.

Я думаю, вы также путаете наследование и фабрики. Опять же, это очень отдельные идеи.

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

Тогда вы можете беспокоиться о создании одной или нескольких фабрик для создания экземпляров этих объектов.

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

2 голосов
/ 06 сентября 2011

Если вы хотите быть настолько универсальным, насколько это возможно, вы можете подойти к нему примерно так:

namespace Factory
{
    public interface IDoor { }
    public interface IEngine { }
    public interface IPropeller { }

    public abstract class Vehicle
    {
        public ICollection<IDoor> Doors { get; protected set; }
        public ICollection<IEngine> Engines { get; protected set; }
    }

    public class Airplane : Vehicle
    {
        public ICollection<IPropeller> Propellers { get; protected set; }
    }
}

Затем попросите конкретные конкретные типы предоставить соответствующие коллекции свойствам супертипа.

Это что-то вроде хака, но моделирование любых реальных объектов в виде классов на языке программирования рано или поздно сломается.

Обратите внимание, что я тоже сделал свойство engine коллекцией.Например, для поддержки класса Prius, который будет иметь два двигателя.

Альтернативный подход заключается в определении транспортных средств в терминах интерфейсов, примерно так:

namespace Factory
{
    public interface IDoor { }
    public interface IEngine { }
    public interface IPropeller { }

    public interface IDoorProvider
    {
        ICollection<IDoor> Doors { get; }
    }

    public interface IEngineProvider
    {
        ICollection<IEngine> Engines { get; }
    }

    public interface IPropellerProvider
    {
        ICollection<IPropeller> Propellers { get; }
    }

    public abstract class Vehicle { }

    public class Car : Vehicle, IDoorProvider, IEngineProvider
    {
        public ICollection<IDoor> Doors { get; protected set; }
        public ICollection<IEngine> Engines { get; protected set; }
    }

    // And so on...
}

Преимущество этого подхода заключается в том, что вам не нужно много определять само по себе Vehicle, но это также означает, что вы не можете легко делиться определениями этих членов среди всех классов.Однако это не позволяет определять элементы базового типа, которые не относятся к конкретным типам.

2 голосов
/ 06 сентября 2011

Вы можете вставить все это в ваше пространство имен Factory.

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

public class Engine
{
   public int HorsePower {get;set;}
}

public class Vehicle
{
    public Vehicle() { }

    public Engine Engine;
    public int Doors;
}

public class Airplane : Vehicle
{
    public Airplane () { }

    public string PropellerModel;
}

public class Boat : Vehicle
{
    public Boat () { }

    public string RudderModel;
}
1 голос
/ 06 сентября 2011

Поскольку человек, задающий вопрос, может на самом деле извлечь из него какую-то ценность, вот мое мнение:

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

Например, это система управления заказами ?В этом случае может быть более уместно, что некоторые заказываемые товары имеют другие заказываемые товары, непосредственно связанные с ним.Для лодки вы можете заказать определенные детали, двигатели и т. Д. То есть, возможно, более важно выразить взаимосвязь между заказываемыми предметами, а не предоставлять их в виде конкретных типов.

Например, это инструмент для рисования новых лодок, самолетов, винтов и т. д.?Тогда более актуальным базовым классом может быть форма.Это больше о расчете мощности двигателя или КПД винта ?Тогда вам может понадобиться некоторое понятие о математических телах, и необходимо определить дополнительные физические отношения и характеристики между различными объектами.

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

0 голосов
/ 06 сентября 2011

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

...