美文网首页
大话设计模式-抽象工厂模式-2020-11-04

大话设计模式-抽象工厂模式-2020-11-04

作者: 松哥888 | 来源:发表于2020-11-09 11:49 被阅读0次

定义

提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

结构图

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

相关文章

网友评论

      本文标题:大话设计模式-抽象工厂模式-2020-11-04

      本文链接:https://www.haomeiwen.com/subject/weowvktx.html