如何重构此代码以使其符合Open-Close原则?

时间:2012-02-09 15:27:49

标签: c# open-closed-principle

The question is actually derived from this link.

假设我遇到这样的问题:


书店购买和销售两种类型的书籍: (1)非技术性{Title,Author,Price} (2)技术{Title,Author,Price,CD}

此外,客户在购买技术书籍时会获得CD。 CD对象定义为CD {Title,Price}。

非技术书籍的价格只是本书的价格。技术书籍的价格将是书籍和CD价格的总和。

创建一个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 :(得分:0)

你可以有一个方法

getTotal(Option op)

其中Option是一个delagte,如果书籍符合您的标准,如果本书是TechnicalBook或NonTechnicalBook,则需要一本书并返回true。

getTotal方法会覆盖所有书籍,只汇总那些Option委托返回true的书籍。 并返还总和。

希望这就是你的意思。