patterncsharpMinor
Bookstore classes design
Viewed 0 times
bookstoredesignclasses
Problem
This is not homework. I am trying to learn OOD principles and design patterns myself.
Suppose I have a problem like this:
A book-shop buys and sells two types of books:
Also, customer gets a CD when he buys a Technical book. A CD object is
defined as, CD {Title, Price}.
A Non-technical book's price will be only the price of the book. A
Technical book's price will be the sum of the price of the book and
the CD.
Create a C# program to show the following info:
I have designed the program like this:
```
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
{
}
abstract class Shop
{
private IDictionary boughtDictionary;
private IDictionary soldDictionary;
public Shop()
{
boughtDictionary = new Dictionary();
soldDictionary = new Dictionary();
}
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
Suppose I have a problem like this:
A book-shop buys and sells two types of books:
- Non-technical {Title, Author, Price}
- Technical {Title, Author, Price, CD}
Also, customer gets a CD when he buys a Technical book. A CD object is
defined as, CD {Title, Price}.
A Non-technical book's price will be only the price of the book. A
Technical book's price will be the sum of the price of the book and
the CD.
Create a C# program to show the following info:
- 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
I have designed the program like this:
```
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
{
}
abstract class Shop
{
private IDictionary boughtDictionary;
private IDictionary soldDictionary;
public Shop()
{
boughtDictionary = new Dictionary();
soldDictionary = new Dictionary();
}
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
Solution
Overriding the
What you could do is employ the template method pattern:
This makes
(Naming and structure in my example could probably be improved, but it serves the purpose)
The behavior is still possible to modify, though, so an even better solution would be to have some collection or set of rules you can add to, so you don't accidentaly override
Price property in TechnicalBook modifies the behavior of Publication. Which means you've broken the OCP. Besides, what do you expect TechnicalBook.Price to be if you have just set it to 10.0? (Does it even compile when you only override get?)What you could do is employ the template method pattern:
abstract class Publication
{
// ...
public decimal IndividualPrice { get; set; }
public decimal Price {
get { return CalculatePrice(); }
}
protected decimal CalculatePrice() {
decimal price = IndividualPrice;
price += GetAdditionalPrices();
return price;
}
protected virtual decimal GetAdditionalPrices() {
return 0;
}
}
public class TechnicalBook : Publication
{
// ...
protected override decimal GetAdditionalPrices() {
return Cd.Price;
}
}This makes
Publication closed for modification (cannot change price / individual price), but open for extension (can add to price).(Naming and structure in my example could probably be improved, but it serves the purpose)
The behavior is still possible to modify, though, so an even better solution would be to have some collection or set of rules you can add to, so you don't accidentaly override
GetAdditionalPrices without calling base.GetAdditionalPrices().Code Snippets
abstract class Publication
{
// ...
public decimal IndividualPrice { get; set; }
public decimal Price {
get { return CalculatePrice(); }
}
protected decimal CalculatePrice() {
decimal price = IndividualPrice;
price += GetAdditionalPrices();
return price;
}
protected virtual decimal GetAdditionalPrices() {
return 0;
}
}
public class TechnicalBook : Publication
{
// ...
protected override decimal GetAdditionalPrices() {
return Cd.Price;
}
}Context
StackExchange Code Review Q#8797, answer score: 4
Revisions (0)
No revisions yet.