简体   繁体   中英

Design Patterns with database usage

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?

  1. If pizzas and stores are in database, don't need to use Design Patterns.
  2. 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!).

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 pizzas and stores are in database, don't need to use Design Patterns.

Your use of design patterns should not be influenced by how you store/persist your data. Design patterns help you solve common problems with known and refined solutions. Where/how you store your data has no bearing on what patterns you use.

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!)

Design your model so that it solves your business problem. Don't design a storage model. That's not OO. Let an ORM, or your own persistence technology, handle the dirty business of getting the data on and off the disk.

If an NyPizza that decorates a Pizza that is a composite of Ingredient is the right model for the business problem then do it that way. Don't let persistence influence your model. There are times when some trade-offs must be made: certain ORMs have certain quirks. However, the model, and any design patterns it uses, should be independent and agnostic of persistence.

I've not studied pattern, but i'm doing that: i deal with differenti machine, so i've implement a class with generic code (id, tag, link between machines) then there is also a map; in db a table called as the subclass is created, added the basic row AND the map (using the key as column name. Obviusly map key should almost never change insite the subclass, because it will be have to be handled with an alter table,and would be dangerous. That way i have a table for every kind of machine. Data is load that way; you give the name of the class, witch is also the table name, the maps are loaded in a list, then who require that info pass the map in the constructor of the specific class.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM