所谓工厂,生产商品的基地也。同样软件设计中的工厂模式,也是创造“对象”的地方。使用工厂模式有以下几点优势:
1:将对象创建统一管理,便于维护和扩展。
2:使用方无需关心对象的生产过程,实现“使用方”和“生产方”的解耦。
3、易于阅读,便于复用扩展。工厂模式将对象生产和使用分离,生产部分可复用。
如果你还没有使用过工厂模式,那么一定要看完本文,然后在代码中切实使用一下,提升代码的质量,加深对工厂模式的理解。
下面以最近做的一个弹窗项目为例,构建一个弹窗的工厂类,结构图如下:
项目中需要按照配置展示不同的弹窗形态。对于相似类型需要创建多种对象时,往往都适合采用工厂模式。首先分别创建OneButtonDialog,TwoButtonDialog,EmotionalDialog弹窗,伪代码如下
public class EmotionalDialog extends Dialog {}
public class OneButtonDialog extends Dialog {}
public class TwoButtonDialog extends Dialog {}
然后创建工厂类DialogFactory,统一生产具体的dialog,伪代码如下
public class DialogFactory {
public static final String TYPE1 = "type_1";
public static final String TYPE2 = "type_2";
public static final String TYPE3 = "type_3";
public static Dialog createDialog(Activity activity, String msg, String abInfo) {
if (TYPE1.equals(abInfo)) {
return createOneButtonDialog(activity, msg);
} else if (TYPE2.equals(abInfo)) {
return createTwoButtonDialog(activity, msg);
}
return createEmotionalDialog(activity, msg);
}
private static Dialog createOneButtonDialog(Activity activity, String msg) {
Dialog dialog = new OneButtonDialog(activity, R.style.psdk_Theme_dialog, msg);
return dialog;
}
private static Dialog createTwoButtonDialog(Activity activity, String msg) {
Dialog dialog = new TwoButtonDialog(activity, R.style.psdk_Theme_dialog, msg);
return dialog;
}
private static Dialog createEmotionalDialog(Activity activity, String msg) {
Dialog dialog = new EmotionalDialog(activity, R.style.psdk_Theme_dialog, msg);
return dialog;
}
}
最后使用时,只需要传入云控下发的abInfo信息,便可以动态展示不同的弹窗样式。业务方无需关注弹窗内部的实现,实现生产和使用的解耦。以后如果需要扩展一种弹窗,只需厂房(“DialogFactory”)再生产一种弹窗样式即可。
Dialog dialog = DialogFactory.createDialog(activity, msg, abInfo);
dialog.setOnDismissListener(dialog1 -> {
if (closeActivityWhenDismiss) {
activity.finish();
}
});
dialog.show();
至此你已经掌握了简单工厂的实现原理。是不是很简单。其实只需要三步即可:
1、构建抽象类或者接口,我们编程主要是面向抽象类或者接口编程,如上例中的dialog(由android系统提供)
2、构建不同的实现类(上述的各种弹窗),并实现1中的接口。
3、创建工厂类,工厂类统一生产2中的对象,暴露接口给业务方使用。
你是不是觉着工厂模式已经结束了?当然没有,我们再延伸一下
工厂是用来统一构建对象的地方,那么构建工厂呢?是不是也可以统一构建?
当然可以,接着上文的案例,我们升级一下需求。如果A app需要上述三种弹窗,但是B app需要另外三种弹窗呢?于是拆解一下任务:
A app的弹窗和B app的弹窗是互相隔离的,所以A pp的工厂 和B app的工厂也是互相独立的。那么便可以创建多个工厂,分别用于生产不同app的弹窗,结构图如下:
重构上述的工厂类DialogFactory代码,将其创建成一抽象类,并具体实现两个工厂ADialogFactory和BDialogFactory。具体的工厂类和上文的工厂代码相似,此处便以伪码代替。
public abstract class DialogFactory {
public abstract Dialog createDialog(Activity activity, String msg, String abInfo);
}
public class ADialogFactory extends DialogFactory {
@Override
public Dialog createDialog(Activity activity, String msg, String abInfo) {
return ...;
}
}
public class BDialogFactory extends DialogFactory {
@Override
public Dialog createDialog(Activity activity, String msg, String abInfo) {
return ...;
}
}
有了工厂类,便可以使用不同的工厂创建弹窗了
public static Dialog createDialogByFactory(DialogFactory factory, Activity activity, String msg, String ab) {
return factory.createDialog(activity, msg, ab);
}
最后,使用弹窗时便可以按照指定工厂生成对应的弹窗,伪代码如下:
Dialog dialog = createDialogByFactory(new ADialogFactory(),activity, msg, abInfo);
dialog.setOnDismissListener(dialog1 -> {
if (closeActivityWhenDismiss) {
activity.finish();
}
});
dialog.show();
上文中的案例中创建了抽象厂类:DialogFactory,弹窗使用了系统提供的底层弹窗类(Dialog),至此引入设计模式另一重要的原则:
依赖抽象,不可依赖具体的实现类。