Получение моей головы вокруг объектно-ориентированного программирования

Я - начальный уровень разработчик .NET и использование его для разработки веб-сайтов. Я запустил с классического asp и в прошлом году вскочил на поставку с короткой книгой C#. Когда я разработал, я узнал больше и начал видеть, что, происходя от классического asp я всегда использовал C# как язык сценариев. Например, в моем последнем проекте я должен был закодировать видео на веб-сервере и написал код как

public class Encoder
{
    Public static bool Encode(string videopath) {

        ...snip...

        return true;
    }
}

При поиске образцов, связанных с моим проектом, я видел, что люди делают это

public class Encoder
{
    Public static Encode(string videopath) {
        EncodedVideo encoded = new EncodedVideo();

        ...snip...

        encoded.EncodedVideoPath = outputFile;
        encoded.Success = true;

        ...snip...
    }
}

public class EncodedVideo
{
    public string EncodedVideoPath { get; set; }
    public bool Success { get; set; }
}

Поскольку я понимаю, что второй пример более объектно-ориентирован, но я не вижу точку использования объекта EncodedVideo.

Я делаю что-то не так? Он действительно необходимый для использования этого вида кода в веб-приложении?

11
задан Ned Batchelder 16 July 2010 в 19:31
поделиться

10 ответов

кто-то однажды объяснил мне OO как банку с газировкой.

Банка газировки - это объект, у объекта много свойств. И много способов. Например ..

SodaCan.Drink ();

SodaCan.Crush ();

SocaCan.PourSomeForMyHomies ();

и т.д ...

Теоретически цель объектно-ориентированного дизайна - написать строку кода один раз и иметь абстракцию между объектами.

Это означает, что Coder.Consume (SodaCan.contents); относится к вашему вопросу.

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

Как и я, употребление банки с газировкой не означает, что я - банка с газировкой.

6
ответ дан 3 December 2019 в 11:03
поделиться

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

Объектно-ориентированный дизайн является лучшим, когда он позволяет вам либо:

1) Хранить связанную информацию и/или функции вместе (вместо использования параллельных массивов и т.п.).

Или

2) Использовать преимущества наследования и реализации интерфейсов.

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

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

1
ответ дан 3 December 2019 в 11:03
поделиться

В основе объектно-ориентированного программирования лежит организация. Вы можете программировать объектно-ориентированным способом даже без языка объектно-ориентированного программирования, такого как C #. Группируя связанные функции и данные вместе, легче справляться со все более сложными проектами.

0
ответ дан 3 December 2019 в 11:03
поделиться

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

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

0
ответ дан 3 December 2019 в 11:03
поделиться

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

Помните: 1. философия ОО может быть довольно субъективной, и нет единственно правильного ответа, 2. вы всегда можете рефакторить позже :p

.
0
ответ дан 3 December 2019 в 11:03
поделиться

Необходимо ли ООП? Нет.

Является ли ООП хорошей идеей? Да.

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

ООП, в целом, способствует модульности, расширяемости и простоте обслуживания. Это относится и к веб-приложениям.

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

Например, данные, хранящиеся в EncodedVideo, используются только в методе Encode()? Тогда, возможно, не имеет смысла использовать отдельный объект.

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

0
ответ дан 3 December 2019 в 11:03
поделиться

То, как вы структурируете ОО-программу - какие объекты вы используете и как их располагаете - действительно зависит от многих факторов: возраста проекта, общего размера проекта, сложности проблемы, и немного от личного вкуса.

Лучший совет, который я могу придумать и который объединит все причины для ОО в один быстрый урок, - это то, что я почерпнул, изучая паттерны проектирования: "Инкапсулируйте части, которые меняются". Ценность ОО заключается в повторном использовании элементов, которые будут повторяться без написания дополнительного кода. Но очевидно, что "упаковывать" код в объекты нужно только в том случае, если он действительно будет повторно использоваться или изменяться в будущем, поэтому вам следует выяснить, что может измениться, и создать из этого объекты.

В вашем примере причина использования второго варианта может заключаться в том, что вы можете повторно использовать объект EncodedVideo в других местах программы. Каждый раз, когда вам нужно иметь дело с EncodedVideo, вы не думаете о том, "как мне кодировать и использовать видео", вы просто используете имеющийся у вас объект и доверяете ему логику. Также может быть полезно инкапсулировать логику кодирования, если она сложна и может меняться. Тогда вы изолируете изменения только в одном месте кода, а не во многих потенциальных местах, где вы могли бы использовать объект.

(Небольшое отступление: Приведенный вами пример не является корректным кодом на C#. Во втором примере статический метод не имеет возвращаемого типа, хотя я предполагаю, что вы хотели, чтобы он возвращал объект EncodedVideo.)

.
0
ответ дан 3 December 2019 в 11:03
поделиться

Это вопрос дизайна, поэтому ответ зависит от того, что вам нужно, то есть нет правильного или неправильного ответа. Первый метод более простой, но во втором случае вы инкапсулируете логику кодирования в классе EncodedVideo и можете легко изменить логику (например, на основе типа входящего видео) в своем классе Encoder . .

0
ответ дан 3 December 2019 в 11:03
поделиться

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

public class Encoder
{
    private string videoPath; 

    public Encoder(string videoPath) {
        this.videoPath = videoPath;
    }

    public bool Encode() {

        ...snip...

        return true;
    }
}
0
ответ дан 3 December 2019 в 11:03
поделиться

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

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

0
ответ дан 3 December 2019 в 11:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: