Can't I change the db in the 15th chapter? -Abstract Factory mode

Source: Internet
Author: User
Tags case statement one table reflection switch case

Since abstract factories are often used and common in our programming, all of this article compares the 15 chapters of the Big talk design model in detail. A DAO layer can replace an example of accessing any database to learn the abstract factory pattern. For example, the DAO layer can access the SQL Server database or Access database, and when the program adds access to the Oracle database, it does not need to modify existing code, just add access to the Oracle-related classes to implement the open/closed principle. In the example of this article, we have the user and Department tables on each database, and the DAO layer queries and inserts the two tables.

Most basic database access

is the code to access the SQL Server database.

public class User {private int id;private String name;public int getId () {return ID;} public void setId (int id) {this.id = ID;} Public String GetName () {return name;} public void SetName (String name) {this.name = name;}}
public class Sqlserveruser{public void Insert (user user) {System.out.println ("sqlserveruser insert User");} public void GetUser (int id) {System.out.println ("Sqlserveruser get User");}}
public class Clienttest {public static void main (String [] args) {sqlserveruser su = new Sqlserveruser (); Su.getuser (1); su.i Nsert (New User ());}}

In the code above, if we were to replace the Access database now, that would be a catastrophic change. Mainly because new SQL Server () is hard-coded, the class SQL Server that accesses the database user table is dead on the SU variable, which means that the client relies on the specific Sqlserveruser class. If it's a bit more flexible, it's polymorphic, deciding whether to use Sqlserveruser or accessuser when it's actually running. Here we use the factory method to solve this problem and let the factory method pattern encapsulate the changes caused by the new SQL Server ().

Database access Program with factory method mode we can see the class that accesses the user table as an abstract product, so that the client relies on abstraction rather than relying on a specific user table to access the class. The Sqlserveruser class that accesses the SQL Server database user table and the Accessuser class that accesses the Access database user table are considered specific products. There is an abstract factory and a production Sqlserveruser specific products, one for the production of Accessuser specific products. UML diagram
The code implements the Iuser interface, the abstract product, for the client and the specific database access decoupling.
public interface Iuser {void Insert (user user); void getUser (int id);}

Sqlserveruser implements the specific product of the Iuser interface. The class that accesses the SQL Server database user table.
public class Sqlserveruser implements Iuser {@Overridepublic void Insert (user user) {System.out.println ("Sqlserveruser Insert User ");} @Overridepublic void getUser (int id) {System.out.println ("Sqlserveruser get User");}}

Accessuser implements the specific product of the Iuser interface. A class that accesses the user table of an Access database.
public class Accessuser implements Iuser {@Overridepublic void Insert (user user) {System.out.println ("Accessuser insert U Ser ");} @Overridepublic void getUser (int id) {System.out.println ("Accessuser get User");}}

Ifactory interface, abstract factory, defines an abstract factory interface that creates access to user table objects.
Public interface Ifactory {Iuser createUser ();}

Sqlserveruser implements a specific factory for the Ifactory interface for the production of related classes that access SQL Server database tables.
public class Sqlserverfacotry implements Ifactory {@Overridepublic Iuser createUser () {//TODO auto-generated method Stubr Eturn new Sqlserveruser ();}}

Access implements a specific product for the Ifactory interface, which is used to produce related classes that Access database tables in Access.
public class Accessfactory implements Ifactory {@Overridepublic Iuser createUser () {//TODO auto-generated method Stubretu RN new Accessuser ();}}

Client
public class Clienttest {public static void main (String [] args) {Ifactory factory = new Sqlserverfacotry ();//ifactory fact Ory = new Accessfactory () iuser IU = Factory.createuser (); Iu.insert (new User ()); Iu.getuser (1);}}

Now with the factory method, if we switch from accessing the SQL Server database to the Access database, we just need to replace the new Sqlserverfactory () with new Accessfactory (), because of the polymorphic relationship Iuser IU implementations simply do not know that a particular database is being accessed, only to be known at runtime, which is the decoupling of the so-called business logic from database access. In the case of access to database changes, we implemented this change with relatively minor changes. Database accessors using abstract Factory mode We ask a question: SQL Server and Access databases are not likely to have only user one table, there may be other tables, such as the addition of the Department table (Department), so what should we do?
UML diagram
We see that we need to change the place as follows: 1, add the Creatdepartment () method to the Ifacotry interface, Sqlserverfactory and accessfactory implement the Createdepartemnt () method respectively. 2, increase the abstraction of the Operating department table, idepartment interface. 3, add sqlserverdepparment and Accessdepartment class, implement Idepartment interface respectively. If you are adding an access to an Oracle database, change the following: 1, add the Oraclefactory class to produce classes that manipulate Oracle tables, and implement all the methods in Ifactory. 2, add the Oracleuser class, for manipulating the user table and implementing all the methods in Iuser. 3, add oracledepartment, to operate the department table, implement all the methods in Idepartment. In fact, we reconstruct the abstract factory pattern through the constant evolution of demand. Only one Iuser abstract product and Iuser specific product, is only need factory method mode. But now it's clear that there are many tables in the database, and that SQL Server and access are two different classifications, all involving multiple product lines, a specialized factory model called Abstract Factory. We can understand that a factory that only creates a single product is called a factory method, and a factory that can create multiple product lines is called an abstract factory. For example: Foxconn and technology are the iphone's foundry, can produce IPhone6, Foxconn and technology are specific factories, Foxconn's IPhone6 and technology IPhone6 are specific super, this time is the factory method mode. iphone production made Apple very satisfied, the iphone6s of the foundry to Foxconn and can win, this time is the abstract factory model. Foxconn and IPhone6 are not only able to produce the products, but also to produce iphone6s.
The advantages and disadvantages of the abstract factory Model 1, the biggest advantage is the easy exchange of products, then in this example, I can easily switch the database connection. 2, so that the specific creation process and client separation, the client through the abstraction to manipulate their instances. There is no specific product class in the client code, only the abstract product interface appears.
Disadvantage 1, if our client has 100 places called ifactory factory = new Sqlserverfactory (), you need to change 100 places when switching to an Access database. This does not implement the purpose of changing the database switch only one place. 2, we need to add a table, but also need to modify the Sqlserverfactory, Accessfactory and Ifactory class, contrary to the open and closed principle. Use simple factory to improve abstract factory solve disadvantage 1 remove ifactory, sqlserverfactory, accessfactory, instead of simple factory AccessData class. Only the code for AccessData and Clienttest is given in the code example, and the product-related code does not change. As follows:
public class DataAccess {private static String DB = "SQL Server";p ublic static Iuser CreateUser () {Iuser user = Null;switch (DB) {case "SQL Server": User = new Sqlserveruser (); Break;case "Access": User = new Accessuser (); break;} return user;} public static Idepartment Createdepartment () {idepartment dep = Null;switch (DB) {case "SQL Server":d EP = new Sqlserverdepar Tment (); Break;case "Access":d EP = new Accessdepartment (); return DEP;}}
public class DataAccess {private static String DB = "SQL Server";p ublic static Iuser CreateUser () {Iuser user = Null;switch (DB) {case "SQL Server": User = new Sqlserveruser (); Break;case "Access": User = new Accessuser (); break;} return user;} public static Idepartment Createdepartment () {idepartment dep = Null;switch (DB) {case "SQL Server":d EP = new Sqlserverdepar Tment (); Break;case "Access":d EP = new Accessdepartment (); return DEP;}}
Simple factory-side improvements in this way allow the client to no longer rely on new sqlserverfactory () or new accessfactory (), but rather rely solely on the Accesdata simple factory class to decouple the client from the specific factory class. The database that needs to be accessed is declared in AccessData as a member variable, modifying the value of the variable to achieve the purpose of switching database access without requiring the client to pass the method in the simple factory. This solves the disadvantage of the abstract factory pattern 1. Although the Ifactory, Sqlserverfactory and Accessfactory classes were abandoned. But when we add a table, we always add the corresponding method to the AccessData class. Adding a new database requires the case "Oracle" statement to be added to each method. There is still no solution to the abstract factory model of disadvantage 2.
Reflective Technology + abstract factory to improve disadvantage 2 our current AccessData class does this: Use the switch case to interpret, if it is SQL Server, create and return SQL Server database related classes, if it is an Access database, The classes related to the Access database are created and returned. It would be nice if we could find the database-related classes based on the variable value of string type. The implementation is as follows: This is the package structure of the program.


Code implementation:
Package Fly.zxy.dhms.chapter15_8.factory;import Fly.zxy.dhms.chapter15_8.IDB. Idepartment;import Fly.zxy.dhms.chapter15_8.IDB. Iuser;public class DataAccess {private static string DB = "SQL Server";p rivate static string packagebasepath = "Fly.zxy.dhm  S.chapter15_8 ";p ublic static Iuser CreateUser () {String name =" User "; iuser iu =null;iu = (iuser) ref (Getpackagepath (name) ); return IU;} public static Idepartment Createdepartment () {String name = "Department"; idepartment dep = NULL;DEP = (idepartment) ref (GE Tpackagepath (name)); return DEP;} private static string Getpackagepath (String className) {//fly.zxy.dhms.chapter15_8.sqlserverdb// Fly.zxy.dhms.chapter15_8.accessDBclassName = db.substring (0,1). toUpperCase () + db.substring (1, Db.length ()) + ClassName; String path = packagebasepath+ "." +db+ "DB" + "." +classname;return path;} private static Object ref (String className) {Object obj = null;try {class<? extends object> cls = Class.forName (Class Name); obj = Cls.newinstance ();} catch (ClassnotfoundexcePtion e) {//Todo auto-generated catch Blocke.printstacktrace ();} catch (Instantiationexception e) {//Todo auto-generated Catch Blocke.printstacktrace ();} catch (Illegalaccessexception e) {//TODO auto-generated catch Blocke.printstacktrace ();} return obj;}}
Because of the use of reflection technology, we only need to add the corresponding method in the AccessData class when we add the table, but there is not a bunch of switch case branch judgment in the method. Added access to one database without changing each method to increase the case statement. Resolves the disadvantage of abstract Factory mode two. In fact, from a certain point of view, it is possible to consider using reflection to remove a switch or if in a place where a simple factory is used. We found that there was a slight flaw, and we needed to change the value class of the DB variable to implement the database switchover, so that the code needed to be changed and recompiled. This small flaw can be done with a configuration file, that is, the value of the DB variable is read from the XML file or the properties file.












Can't I change the db in the 15th chapter? -Abstract Factory mode

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.