I see 99% of Design Patterns examples (Strategy, Factories, Decorator, etc..) with hard-coded information, each product in different classes, etc.. but, in most real life applications, mainly with database usage, we know that is impracticable to create a class for each product, or work with hard-coded information.
I know they are all examples, but I think that is painful after you learn from a book:
Create classes for CheesePizza, VeggiePizza..and classes for stores NYStore, ChicagoStore
for Factory Pattern.. and in real life all these pizzas and stores are just rows in database.
So, what's the best approach to work with database and design patterns in this case?
I understand the importance of Design Patterns with payment business for eg. (Cash, Credit Card, Bitcoin..) where each one payment type have unique specializations and the business isn't fully in database (credit card needs to print receipt, bitcoin to access webservice, etc).
But what I'm questioning is: in a real Pizza Restaurant where prices, ingredients, toppings, all according with different places (Chicago, NY..) are located in database, the usage of Design Patterns is really necessary? The usage of Design Patterns naturally decreases when a lot of business are located at database?
...and in real life all these pizzas and stores are just rows in database.
Does database check for invariants, business specifications or some other custom rules provided by your classes (in oop term)? No. Databases are simply a storage for most applications.
Those rows are the result of a smart and reliable computation from your domain model and business logics.
Design patterns may help you to build a flexible code that could cover all those business rules.
we know that is impracticable to create a class for each product
Design patterns merely bring some abstraction on behavior specializations and don't care about strict nature of data.
Indeed, if a ChicagoPizza
class is created, this is to specify some unique specialization, not for simply marking: "this pizza is a Chicago one".
I don't know many applications that deal with more than dozens objects related to the same theme, all having some strong and distinct specializations.
In case of creational patterns (as you mentioned), I'd say that if you have so many "objects" that differ only by their "nature", you should just end up with a simple kind of type
attribute (on the base class) mapped in database rather than using extra subclasses in this case.
I don't find a gap at all between what is mentioned on programming books and the software reality.
Your domain model (hard-coded by definition) should almost always be favored over database thinking.
In conclusion:
I know they are all examples, but I think that is painful after you learn from a book
If "example" means distinct from reality, then they are not examples at all.
They are just a mini portion of a real software that could be made.
I think you are taking the Design Pattern examples a bit too literally. Obviously, the CheesePizza and VeggiePizza example is NOT suggesting that everytime you have a software application that deals with Pizzas you have to use a specific Design Pattern. Design Patterns suggest how you could design your system architecture for better scalability and maintainability by breaking unnecessary dependencies and then it is up to you to decide what design pattern would best suit your application.
The Factory Pattern has no direct relation to databases, it simply specifies a factory object in a similar way to the Facade Pattern, where instantiating an object is not desired and usually/ideally consuming code will never know what's the concrete object it is working with, because the factory object will be serving interfaces, base classes or abstract classes.
Whatever Design Pattern(s) you choose your system should ALWAYS be database-agnostic, and design patterns will help you achieve this by breaking dependencies and avoiding unnecessary object and layer coupling. So, basically you will have a data access layer that will abstract your application away from the underlying data layer and your application doesn't need to know whether the database is being stored on a MS SQL Database, XML file, File System or a physical warehouse.
If pizzas and stores are in database, don't need to use Design Patterns.
That's the wrong interpretation of design patterns. Pizzas should be stored in a Pizza table and Stores should be stored in a Store table. You should have a data access layer that manages this data and translate them to POCO data entities. You can do this manually or by using a popular ORM tool such as NHibernate or Entity Framework
Use design patterns, but instead creating a class per Pizza or Store, just create a single class implementation that read data from database (eg. DatabasePizza and DatabaseStore!).
Something like that, you should have DatabasePizza (you name it) that implements an interface and reads data from the database and exposes some methods, then you will have a PizzaEntity that is just a POCO object with properties such as Id, Name, Price, etc...then you factory object will "serve" construct this DatabasePizza object...here's a minimalistic example...
public static DataFactory
{
public static IDatabasePizza DatabasePizza
{
get{ return new DatabasePizza;}
}
}
then client apps, or repositories, or services, or business layer can call this factory object like this...
IList<PizzaEntity> favouritePizzas = DataFactory.DatabasePizza.GetMyFavouritePizzas();
Hope you get the idea behind Design Patterns. I'd suggest you to read the GoF's book on Design Patterns it's a good source on info and it comes with a few projects where you can go through the source code
Any example about design patterns out there is just a simple example or illustration. They usually use hard-coded value to keep the scope small (instead of querying to database). Many cases used for example seems like not correct or not very suitable to real life need though.
Taking example your CheesePizza
and VeggiePizza
. Both are 2 master records on Pizza
table in database. That is correct and no design pattern needed so far, and only one Pizza
class entity is needed.
Now as the business grows, you will need another kind of Pizza
rather than the original one. Let's say that the new class is PizzaWithAdditionalTopping
. Starting from now, the decorator or strategy or factory design pattern will start to shine, because the new class -- IAdditionalToppingAble
(PizzaWithAdditionalTopping
) will now have additional property IEnumerable<Topping> Toppings
in which need to be handled specifically and different with Pizza
.
Let's say that the business grows again and now you have a IStuffedCrustAble
(StuffedCrustedPizza
) pizza. Now that StuffedCrustedPizza
class will have another property string StuffedCrustType
(or use enum). Again with those design patterns, hopefully they can add the behavior without modifying the existing code.
You can do other designs as well, even as far as adding the Toppings
to your original Pizza
class, or using if-else, DataTable
or whatever without design pattern, but from experience the maintainability is reduced.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With