I recently talked with some friends about some things about the factory model. I think it is necessary to write an article to clarify the application methods of the abstract factory. In the abstract factory chapter, GoF does not spend much space on how to apply abstract factories. Fortunately, ADO. NET provides us with an example of a very standard Abstract Factory, and it is also a very practical interface-DbProviderFactory
I want to use an example of using DbProviderFactory to reconstruct a website to answer two frequently asked questions about the Abstract Factory:
- Why use abstract factory?
- How to Use Abstract Factory
First, let's take a look at the previous website reconstruction. This is a very representative example I wrote in an hour. It is a database table, and four pages are added, deleted, modified, and queried, the query page uses a control. We don't need to worry about it. For demonstration, I didn't use FormView for addition, deletion, and modification. Such websites can be seen everywhere. Of course, this is not a good example. There is no exception handling or encapsulation. It is just an example for everyone to understand.
This is a website that relies on SqlSever Client. We cannot deploy it on other types of databases. Now let's refactor it to support multiple databases.
Before using the abstract factory, we must first make the Code conform to one of the basic principles of OO and the dependency reversal principle. So we replace all the namespaces System. Data. SqlClient with System. Data. Common, and the corresponding classes with interfaces starting with Db. Unfortunately, after the replacement, we will find a syntax error:
There is no way to create an interface instance for these annoying new ones, so new cannot depend on specific classes. In this way, we have to add the original namespace back, and we cannot implement programming for multiple databases. By now, you can probably guess that the solution is related to the factory. This is why we use the factory: constructors cannot be polymorphism.
Next we will go back to the specific problem. Since we can solve the problem through factory reconstruction, how can we do it? Of course, the abstract factory class provided by the. net class library is preferred: DbProviderFactory. Now that we have a class, the specific problem we face is: When to create a factory? Where can I save the factory variables?
Let's take a look at the scope of the factory: This is a very simple Web application, we only need a database, so the factory that decides to use the database type should be global, it is created when the web application is started. This location should obviously be a static attribute of the Global class.
Here we will introduce how to create the Global class, right-click our website root, and select Global Application class as shown in add new Item.
Then we will get the Global. asax file, which contains the Global class. Then we add DbProvider to the Global class and create the specific type in Application_Start.
Comments: A friend suggested that creating Application_Start may cause problems. See #20 th floor.
With DbProvider, we can reconstruct the original code into the form of creating database-related objects relying on DbProvider. Here we still post the Update example:
At this time, the Update. aspx. cs does not need to contain namespaces related to specific database types such as System. Data. SqlClient. Instead, it becomes a class completely independent of specific database types.
Use the same method to reconstruct delete. aspx. cs and insert. aspx. after cs, our entire system is decoupled from the database. create a correct factory in asax and write the connection string in the configuration file to work in any database.
Finally, see the code after the complete reconstruction.
That's all. Thank you for watching.