工厂系列设计模式
工厂系列设计模式包含由简单工厂、工厂方法和抽象工厂三种。开头我们先简单说一下这三种设计模式的区别:
-
简单工厂:对于某一个产品,通常存在一个具体工厂用于生成产品类 -
工厂方法:对于某一个产品,通常定义一个工厂接口,通过不同的具体工厂实现该接口,然后不同的具体工厂生成不同的具体产品 -
抽象工厂:对于一系列产品,通常定义一个工厂接口,包含所有产品的构建方法,然后定义不同系列的具体工厂实现该接口,每个系列具体工厂生成可以生成该系列的所有产品
简单工厂
场景1:现在有一个User表的操作类接口IUser,数据库使用MySQL和Oracle,要求创建对应数据库的操作类。
如果利用简单工厂模式,伪代码以及UML类图如下:
![UML](https://img-blog.csdnimg.cn/img_convert/3dcdf9e78ce95cbd8d327f5732981450.png)
// 定义产品通用接口
interface IUser{
public void insert();
public User select(int id); // UML类图忘记写入参了 这里就不改了
}
// 定义不同数据库的实现
class MySQLIUser{
public void insert(){
// 对应MySQL的操作
}
public User select(int id){
// 对应MySQL的操作
}
}
class OracleIUser{
public void insert(){
// 对应Oracle的操作
}
public User select(int id){
// 对应Oracle的操作
}
}
// 定义工厂类
class IUserFactory{
public IUser createIUser(String dataBase){
switch (dataBase){
case "MySQL" ...
case "Oracle" ...
}
...
}
}
在客户端调用时,如下:
class Client(){
psvm(String[] args){
String dataBase = "MysQL";
IUserFactory mysqlIF = new IUserFactory(dataBase);
mysqlIF.insert();
String dataBase = "Oracle";
IUserFactory oracleIF = new IUserFactory(dataBase);
oracleIF.select();
}
}
工厂方法
场景1:现在有一个User表的操作类接口IUser,数据库使用MySQL和Oracle,要求创建对应数据库的操作类
还是同样的场景,上述简单工厂存在的问题:如果增加数据库类型,那么需要改动工厂类以及客户端代码,耦合性较高,如果使用工厂方法解决该场景,UML类图和伪代码如下:
![UML类图](https://img-blog.csdnimg.cn/img_convert/07e31c8f04b005e200887959863e4a2c.png)
// 定义产品通用接口
...
// 定义不同数据库的实现
...
// 定义工厂接口
interface IUserFactory{
public IUser createIUser();
}
// 定义具体工厂
public IUser MySQLIUserFactory implement IUserFactory{
public IUser createIUser(){
return new MysQLIUser();
}
}
public IUser OracleIUserFactory implement IUserFactory{
public IUser createIUser(){
return new OracleIUser();
}
}
客户端调用时,如下:
class Client{
psvm(String[] args){
//MySQL
IUserFactory MySQLIF = new MySQLIUserFactory();
MySQLIF.select();
//Oracle
IUserFactory OracleIF = new OracleIUserFactory();
OracleIF.select();
}
}
抽象工厂
场景2:现在有个User表和Department表的操作类接口IUser和IDepartment,数据库使用MySQL和Oracle,要求创建对应数据库的操作类
这个场景下如果还使用工厂方法,那么需要在定义一个IDepartmentFactory工厂接口以及不同数据库的实现,如果表的数量不多,那么可以结束,如果很多的话,那么接口的数量就太多了。此时在遇到这种一系列的产品
创建时,我们可以使用抽象工厂解决。伪代码和UML类图如下:
![抽象工厂UML](https://img-blog.csdnimg.cn/img_convert/23ba413d42e749afdbfe56442fdc31f6.png)
// 定义产品A的接口
public interface IUer{
publi void insert();
public User select(User user);
}
// A的实现
class MySQLIUser implement IUser{
...
}
class OracleIUser implement IUser{
...
}
// 定义产品B的接口
...
// 定义工厂接口
public interface IFactory{
public IUser createIUser();
public IDepartment createIDepartment();
}
// 工厂接口实现
class MySQLFactory implement IFactory{
public IUser createIUser(){
return new MySQLIUser();
}
public IDepartment createIDepartment(){
return new MySQLIDepartment();
}
}
class OracleFactory implement IFactory{
...
}
访客端代码:
class Client{
psvm(String[] args){
MySQLFactory mf = new MySQLFactory();
MySQLIUser miu = mf.createMySQLIUser();
miu.insert();
OracleFactory of = new OracleFactory();
OracleIDepartment oid = of.OracleIDepartment();
Department department = oid.select(id);
}
}