定义
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
结构图
image.png
使用场景
-
易于交换产品系列,由于具体工厂类在一个应用中只需要在初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,它只需要改变具体工厂即可使用不同的产品配置。
-
它让具体的创建实例过程与客户端分离,客户端是通过它们的抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户代码中。
-
所有在用简单工厂的地方,都可以考虑用反射技术来去除switch或if,解除分支判断带来的耦合。
数据库的例子
- 结构图
image.png
- 数据结构;
/**
* 数据结构,Model类,用户
*/
class User {
public Integer id;
public String name;
public User(Integer id, String name) {
this.id = id;
this.name = name;
}
}
/**
* 数据结构;Model类;部门
*/
class Department {
public Integer id;
public String name;
public Department(Integer id, String name) {
this.id = id;
this.name = name;
}
}
- IUser,IDepartment;产品接口;AbstractProductA;AbstractProductB
/**
* 读写数据结构User的接口; 产品接口;AbstractProductA
*/
interface IUser {
// 往数据库插入User结构;由于展示log信息,这里返回String,正常情况这里是void
public String insert(User user);
// 从数据库读取User结构;由于展示log信息,这里返回String,正常情况这里是User
public String getUser(Integer id);
}
/**
* 读写数据结构User的接口; 产品接口;AbstractProductB
*/
interface IDepartment {
// 往数据库插入Department结构;由于展示log信息,这里返回String,正常情况这里是void
public String insert(Department department);
// 从数据库读取User结构;由于展示log信息,这里返回String,正常情况这里是Department
public String getDepartment(Integer id);
}
- 具体的产品;ProductA1,ProductA2
/**
* 具体的产品;SqlServer数据库读写User表的方法;ProductA1
*/
class SqlServerUser implements IUser {
@Override
public String insert(User user) {
return "在SQLServer中给User表增加一条记录:" + user.name;
}
@Override
public String getUser(Integer id) {
return "在SQLServer中根据id得到User表一条记录";
}
}
/**
* 具体的产品;Access数据库读写User表的方法;ProductA2
*/
class AccessUser implements IUser {
@Override
public String insert(User user) {
return "在Access中给User表增加一条记录:" + user.name;
}
@Override
public String getUser(Integer id) {
return "在Access中根据id得到User表一条记录";
}
}
- 具体的产品;ProductB1,ProductB2
/**
* 具体的产品;SqlServer数据库读写Department表的方法;ProductB1
*/
class SqlServerDepartment implements IDepartment {
@Override
public String insert(Department department) {
return "在SQLServer中给Department表增加一条记录:" + department.name;
}
@Override
public String getDepartment(Integer id) {
return "在SQLServer中根据id得到Department表一条记录";
}
}
/**
* 具体的产品;Access数据库读写Department表的方法;ProductB2
*/
class AccessDepartment implements IDepartment {
@Override
public String insert(Department department) {
return "在Access中给Department表增加一条记录:" + department.name;
}
@Override
public String getDepartment(Integer id) {
return "在Access中根据id得到Department表一条记录";
}
}
- 工厂类,集中实现,减少具体工厂类的个数;DataAccess
/**
* 工厂方法集中的类;可以是简单工厂;也可以用反射,通过字符串创建所需要的类
*/
class DataAccess {
// "SqlServer"; 和 "Access"
public static String db = "SqlServer";
// 简单工厂的方法:离不开switch或者if
public static IUser createUser() {
IUser result = null;
switch (db) {
case "SqlServer":
result = new SqlServerUser();
break;
case "Access":
result = new AccessUser();
break;
}
return result;
}
public static IDepartment createDepartment() {
IDepartment result = null;
switch (db) {
case "SqlServer":
result = new SqlServerDepartment();
break;
case "Access":
result = new AccessDepartment();
break;
}
return result;
}
// 反射的方法,暂时不写
}
- 测试界面
image.png
- 客户端程序
public class AbstractFactoryActivity extends AppCompatActivity {
public static void launch(Context context) {
if (null != context) {
Intent intent = new Intent();
intent.setClass(context, AbstractFactoryActivity.class);
if (!(context instanceof Activity)) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
context.startActivity(intent);
}
}
RadioGroup radioGroupDatabase;
TextView textViewDatabase;
User user;
Department department;
IUser iUser;
IDepartment iDepartment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_abstract_factory);
setTitle("抽象工厂模式");
radioGroupDatabase = findViewById(R.id.radioGroupDataBase);
textViewDatabase = findViewById(R.id.textViewDatabase);
user = new User(1, "小菜");
department = new Department(2, "研发部");
}
public void onInsertClick(View view) {
changeDatabase();
String message = "";
message += iUser.insert(user) + "\n";
message += iDepartment.insert(department);
textViewDatabase.setText(message);
}
public void onReadClick(View view) {
changeDatabase();
String message = "";
message += iUser.getUser(1) + "\n";
message += iDepartment.getDepartment(2);
textViewDatabase.setText(message);
}
// 根据用户选择切换数据库
private void changeDatabase() {
// 根据用户选择切换数据库
switch (radioGroupDatabase.getCheckedRadioButtonId()) {
case R.id.radioButtonSqlServer:
DataAccess.db = "SqlServer";
break;
case R.id.radioButtonAccess:
DataAccess.db = "Access";
break;
default:
// 什么也不做
break;
}
// 创建方法
iUser = DataAccess.createUser();
iDepartment = DataAccess.createDepartment();
}
}
Demo地址
https://gitee.com/zhangxusong888/Android/tree/master/design_pattern











网友评论