什么是工厂模式
我们创建实例对象一般都是用new
进行的,但是工厂模式将new
的过程封装了起来,负责将大量实现了共同接口的类实例化。
工厂模式又分为
- 简单工厂模式:在具体工厂类里面创建抽象的产品。
- 工厂方法模式:在抽象工厂类里面创建抽象的产品。
- 抽象工厂模式:在抽象工厂类里面创建某个族的抽象的产品。
简单工厂模式
违背了开闭原则,不利于扩展
创建抽象产品IUser
,以及两个具体产品MySQLUser
、SQLServerUser
。
通过SQLFactory
工厂类创建具体产品。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| public class Main{ public static void main(String[] args){ IUser db = UserFactory.createUserDB(UserFactory.DB_MYSQL); db.insertUser(new User()); } }
public interface IUser { void insertUser(User user); }
public class MySQLUser implements IUser{ public void insertUser(User user) { System.out.println("MySQL插入一条用户数据"); } } public class SQLServerUser implements IUser{ public void insertUser(User user) { System.out.println("SQLServer插入一条用户数据"); } }
public class SQLFactory { public static final String DB_MYSQL="MySQL"; public static final String DB_SQLSERVER="SQLServer"; public static IUser createUserDB(String name){ IUser db = null; switch(key){ case DB_MYSQL:db = new MySQLUser();break; case DB_SQLSERVER:db = new SQLServerUser();break; } return db; } }
|
如果需要新增子类,比如Oracle
的用户类,那么就继承IUser
类写一个子类,并在工厂中添加一个case
分支。
但是缺点也在这里,每写一个子类,都要去修改已有的UserFactory
工厂类,去新增case
分支,这不符合开闭原则。
工厂方法模式
优化了简单工厂模式,但是大大增加了类的数量
创建抽象产品IUser
,以及两个具体产品MySQLUser
、SQLServerUser
。
创建抽象工厂SQLFactory
,以及两个具体工厂MySQLFactory
、SQLServerFactory
。
使用多态的特性,创建具体工厂,用来生产具体产品。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| public class Main{ public static void main(String[] args){ SQLfactory factory = new MySQLFactory(); IUser userDB = factory.createUserDB(); userDB.insertUser(new User()); }
public interface IUser { void insertUser(User user); }
public class MySQLUser implements IUser{ public void insertUser(User user) { System.out.println("MySQL插入一条用户数据"); } } public class SQLServerUser implements IUser{ public void insertUser(User user) { System.out.println("SQLServer插入一条用户数据"); } }
public interface SQLFactory { public IUser createUserDB(); }
public class MySQLFactory implements SQLFactory{ public IUser createUserDB() { return new MySQLUser(); } } public class SQLServerFactory implements SQLFactory{ public IUser createUserDB() { return new SQLServerUser(); } }
|
在简单工厂模式的基础上,把工厂抽象出来,给每一个数据库添加一个工厂。
当需要添加新的数据库功能的时候,只要添加工厂或操作类即可。不用再去关注工厂中的判断分支(实际上已经没有判断分支了)。
缺点也在这,每添加一个子类功能的时候,都要创建两个类,工厂和操作类,增加了代码量。
抽象工厂模式
代码冗余,过度设计
创建抽象产品IUser
,以及两个具体产品MySQLUser
、SQLServerUser
。
创建抽象产品IAuth
,以及两个具体产品MySQLAuth
、SQLServerAuth
。
创建抽象工厂SQLFactory
,以及两个具体工厂MySQLFactory
、SQLServerFactory
。
使用多态的特性,创建具体工厂,用来生产具体产品。
和工厂方法模式类似,只是增加了不同的产品。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| public class Main{ public static void main(String[] args){ SQLfactory factory = new MySQLFactory(); IUser userDB = factory.createUserDB(); userDB.insertUser(new User()); IAuth authDB = factory.createAuthDB(); authDB.insertAuth(new Auth()); }
public interface IUser { void insertUser(User user); }
public class MySQLUser implements IUser{ public void insertUser(User user) { System.out.println("MySQL插入一条用户数据"); } } public class SQLServerUser implements IUser{ public void insertUser(User user) { System.out.println("SQLServer插入一条用户数据"); } }
public interface IAuth { void insertAuth(Auth auth); }
public class MySQLAuth implements IAuth{ public void insertAuth(Auth auth) { System.out.println("MySQL插入一条权限数据"); } } public class SQLServerAuth implements IAuth{ public void insertAuth(Auth auth) { System.out.println("SQLServer插入一条权限数据"); } }
public interface SQLFactory { public IUser createUserDB(); public IAuth createAuthDB(); }
public class MySQLFactory implements SQLFactory{ public IUser createUserDB() { return new MySQLUser(); } public IAuth createAuthDB() { return new MySQLAuth(); } } public class SQLServerFactory implements SQLFactory{ public IUser createUserDB() { return new SQLServerUser(); } public IAuth createAuthDB() { return new SQLServerAuth(); } }
|
用简单工厂+反射+配置文件优化抽象工厂
删除SQLFactory
、MySQLFactory
、SQLServerFactory
三个工厂。
融合成一个SQLFactory类
,再通过properties
配置文件加载类。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
| public class Main{ public static void main(String[] args){ IUser userDB = SQLFactory.createUserDB(); userDB.insertUser(new User()); IAuth authDB = SQLFactory.createAuthDB(); authDB.insertAuth(new Auth()); }
public interface IUser { void insertUser(User user); }
public class MySQLUser implements IUser{ public void insertUser(User user) { System.out.println("MySQL插入一条用户数据"); } } public class SQLServerUser implements IUser{ public void insertUser(User user) { System.out.println("SQLServer插入一条用户数据"); } }
public interface IAuth { void insertAuth(Auth auth); }
public class MySQLAuth implements IAuth{ public void insertAuth(Auth auth) { System.out.println("MySQL插入一条权限数据"); } } public class SQLServerAuth implements IAuth{ public void insertAuth(Auth auth) { System.out.println("SQLServer插入一条权限数据"); } }
public class SQLFactory { private static String dbName; static { try(InputStream in = SQLFactory.class.getResourceAsStream("/db.properties");) { Properties prop = new Properties(); prop.load(in); for (Object key : prop.keySet()) { if(key.equals("dbName")){ dbName = prop.getProperty((String) key); } } } catch (IOException e) { e.printStackTrace(); }
}
public static IUser createUserDB(){ try { Class clazz = Class.forName(dbName+"User"); return (IUser) clazz.getConstructor().newInstance();; } catch (Exception e) { e.printStackTrace(); } return null; } public static IAuth createAuthDB(){ try { Class clazz = Class.forName(dbName+"Auth"); return (IAuth) clazz.getConstructor().newInstance();; } catch (Exception e) { e.printStackTrace(); } return null; } }
|