Понимание отношений между Лисковым и OCP - PullRequest
2 голосов
/ 08 октября 2011

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

У меня есть следующие классы.Как видите, B является производным от A и переопределяет функцию DisplayMessage для изменения поведения.

public class A
{
    private readonly string _message;

    public A(string message)
    {
        _message = message;
    }

    public virtual void DisplayMessage()
    {
        Console.WriteLine(_message);
    }
}

public class B : A
{
    public B(string message) : base(message){}

    public override void DisplayMessage()
    {
        Console.WriteLine("I'm overwriting the expected behavior of A::DisplayMessage() and violating LSP >:-D");
    }
}

Теперь в моей программе начальной загрузки ShowClassTypeis ожидаетобъект типа A, который должен помочь выписать, что это за класс Type.Однако B нарушает LSP, поэтому, когда вызывается его функция DisplayMessage, он печатает совершенно неожиданное сообщение и по существу мешает достижению цели ShowClassType.

class Program
{
    static void Main(string[] args)
    {
        A a = new A("I am A");
        B b = new B("I am B");

        DoStuff(b);

        Console.ReadLine();
    }

    private static void ShowClassType(A model)
    {
        Console.WriteLine("What Class are you??");
        model.DisplayMessage();
    }
}

Так что мой вопрос:Право сделать вывод, что ShowClassType теперь нарушает принцип Open Close, потому что теперь, когда тип B может войти и изменить ожидаемую функцию этого метода, он больше не закрыт для модификации (т. е. чтобы гарантировать, что он поддерживает ожидаемое поведение, вынужно изменить его, чтобы он сначала проверял, чтобы убедиться, что мы работаем только с оригинальным объектом A)?

Или, наоборот, это просто хороший пример, показывающий, что ShowClassType закрыт для модификации и что, передав производный тип (хотя и нарушающий LSP), мы расширили то, что он должен делать?

Наконец, является ли плохой практикой создание виртуальных функций на базовых классах, если базовый класс не является абстрактным?Таким образом, разве мы не просто приглашаем производные классы нарушать принцип подстановки Лискова?

Cheers

Ответы [ 2 ]

0 голосов
/ 10 мая 2012

Я думаю, что это не нарушать не LSP и не OCP в этом контексте использования.

По моему мнению, ShowClassType не является нарушением OCP: 1. Функция не может нарушать OCP, это может сделать только классовая архитектура.2. Вы можете добавить новое поведение к производным классам из A, чтобы оно не нарушало OCP

А как насчет LSP?Ваша причина - пользователь не ожидал получить это сообщение?Но он получил какое-то сообщение!Если переопределение функции возвращает какое-то сообщение, я думаю, что это нормально в этом контексте вашего кода.Если функция, добавляющая два числа, переопределяет, и 1 + 1 возвращает 678, это для меня неприемлемо и плохо.НО, если для ученого-физика с планеты Марс это может быть хороший ответ.

НЕ АНАЛИЗИРУЙТЕ ПРОБЛЕМУ БЕЗ ВСЕГО КОНТЕКСТА !!!Вы должны получить полную картину проблемы.И, конечно же,

0 голосов
/ 08 октября 2011

Я бы сказал, что не ShowClassType нарушает принцип Open / Closed.Только класс В нарушает принцип замещения Лискова.A открыт для расширения, но закрыт для модификации.Из Википедии ,

сущность может разрешить изменение своего поведения без изменения исходного кода.

Очевидно, что исходный код Aне изменяетсяТакже не используются частные члены A (что также является нарушением принципа Open / Closed в моей книге).B строго использует открытый интерфейс A, поэтому, хотя принцип Open / Closed соблюдается, принцип подстановки Liskov нарушается.

Последний вопрос заслуживает отдельного обсуждения.Связанный вопрос о SO находится здесь.

...