I’m building a book library app, I have a abstract book Class, two types of derived books and two Enums that will save the genre of the book.
Each Book can be related to one genre or more.
abstract public class Book
{
public int Price { get; set; }
...
}
public enum ReadingBooksGenre
{
Fiction,
NonFiction
}
public enum TextBooksGenre
{
Math,
Science
}
abstract public class ReadingBook : Book
{
public List<ReadingBooksGenre> Genres { get; set; }
}
abstract public class TextBook : Book
{
public List<TextBooksGenre> Genres { get; set; }
}
Now i want to save the discounts based on the book genres (no double discounts, only the highest discount is calculated), so i’m thinking about making two dictionaries that will save all the discounts for each genre, like this:
Dictionary<ReadingBooksGenre, int> _readingBooksDiscounts;
Dictionary<TextBooksGenre, int> _textBooksDiscounts;
So now i need to check the genre of each book in order to find the highest discount, is there any better way to do it than:
private int GetDiscount(Book b)
{
int maxDiscount = 0;
if (b is ReadingBook)
{
foreach (var genre in (b as ReadingBook).Genres)
{
// checking if the genre is in discount, and if its bigger than other discounts.
if (_readingBooksDiscounts.ContainsKey(genre) && _readingBooksDiscounts[genere]>maxDiscount)
{
maxDiscount = _readingBooksDiscounts[genere];
}
}
}
else if (b is TextBook)
{
foreach (var genre in (b as TextBook).Genres)
{
if (_textBooksDiscounts.ContainsKey(genre) && _textBooksDiscounts[genere]>maxDiscount)
{
maxDiscount = _textBooksDiscounts[genere];
}
}
}
return maxDiscount;
}
is there a way to select the correct dictionary without checking for the type?
or maybe even a way to do it without the dictionaries, or using one?
maybe somehow connect book type with the Enum?
will be glad to hear any suggestions for improvement.
(there are a lot of more discounts based on books name, date and author. Even some more book types that is why this way doesn’t seem right to me)
Thank you.
Your
GetDiscountmethod is classic example of Open/Closed principle violation. When you add new book type you have to add newifblock toGetDiscount.Better way is to use some existing techinques which allow you to add new functionality without necessity to modify existing code. For example, Composite pattern. I’ll write some draft implementation of composite discount evaluator. You can add new discount evaluators based on any book proerties (date, price, etc.) easily.
Also, I’ll use interfaces instead of inheritance. Inheritance is a very strong link between two entities and in this case it is excessive.
Listing is 167 lines long, so here is more comfort pastebin copy