Как провести рефакторинг этого кода, чтобы он соответствовал принципу Open-Close? - PullRequest
0 голосов
/ 09 февраля 2012

Вопрос фактически получен по этой ссылке.

Предположим, у меня такая проблема:


Книжный магазин покупает и продает книги двух типов: (1) Нетехнический {Название, Автор, Цена} (2) Технический {Название, Автор, Цена, CD}

Кроме того, клиент получает компакт-диск, когда он покупает Техническую книгу. CD-объект определяется как CD {Title, Price}.

Цена нетехнической книги будет равна только цене книги. Цена технической книги будет равна сумме цены книги и компакт-диска.

Создайте программу на C # для отображения следующей информации:

Total number of book Bought & Price: XXX & XXX.XX
Total number of book Sold & Price: XXX & XXX.XX
Total Technical Book Sold & Price: XXX & XXX.XX
Total Non-technical Book sold & Price: XXX & XXX.XX

abstract class Publication
{
    public virtual string Title { get; set; }
    public virtual double Price { get; set; }
}

class CD : Publication
{
}

abstract class Book : Publication
{
    public virtual string Author { get; set; }
}

class TechnicalBook : Book
{
    public CD Cd { get; set; }
    public override double Price
    {
        get
        {
            return (base.Price + Cd.Price);
        }
    }
}

class NonTechnicalbook : Book
{
}

class Shop
{
    private IDictionary<string, Book> boughtDictionary;
    private IDictionary<string, Book> soldDictionary;

    public Shop()
    {
        boughtDictionary = new Dictionary<string, Book>();
        soldDictionary = new Dictionary<string, Book>();
    }

    public virtual void Buy(Book item)
    {
        boughtDictionary.Add(item.Title, item);
    }

    public virtual void Sell(string title)
    {
        Book book = boughtDictionary[title];
        boughtDictionary.Remove(book.Title);
        soldDictionary.Add(book.Title, book);
    }

    public virtual int GetBoughtBookCount()
    {
        return boughtDictionary.Count;
    }

    public virtual double GetBoughtBookPrice()
    {
        double price = 0.0;

        foreach (string title in boughtDictionary.Keys)
        {
            price = price + boughtDictionary[title].Price;
        }
    }

    public virtual int GetSoldBookCount()
    {
        return boughtDictionary.Count;
    }

    public virtual double GetSoldBookPrice()
    {
        double price = 0.0;

        foreach (string title in soldDictionary.Keys)
        {
            price = price + soldDictionary[title].Price;
        }
    }

    public virtual double GetTotalBookCount()
    {
        return this.GetBoughtBookCount() + this.GetSoldBookCount();
    }

    public virtual double GetTotalBookPrice()
    {
        return this.GetBoughtBookPrice() + this.GetSoldBookPrice();
    }

    public virtual void Show()
    {
        Console.WriteLine("Total number of books Bought & Price: ", this.GetTotalBookCount() + " & " + this.GetTotalBookPrice());
        Console.WriteLine("Total number of books Sold & Price: ", this.GetSoldBookCount() + " & " + this.GetSoldBookPrice());
    }
}

Как показать цены на технические и нетехнические книги при сохранении принципа открытого закрытого пространства?

Деривация Shop-class не имеет никакого смысла.

Если я напишу следующее:

 if(book is TechnicalBook) {
    // ...
 } else if(book is NonTechnicalBook) {
    // ...
 }

Я не думаю, что это держит OCP.

Тогда что делать?

1 Ответ

0 голосов
/ 09 февраля 2012

у вас может быть метод

getTotal(Option op)

, где Option - это delagte, который берет книгу и возвращает true, если он соответствует вашим критериям в вашем случае, если книга - TechnicalBook или NonTechnicalBook.1006 * метод getTotal прошел бы по всем книгам, суммируя только те, которые делегат Option возвращает true.и возвращая сумму.

надеюсь, что это то, что вы имели в виду.

...