1、策略模式:
我们的业务是国外铁路预定业务,包括了英法德意西韩日等多条铁路,他们数据契约来自不同的供应商,由于预定规则等等不同,客户端拿到的最终的数据格式,每条铁路都是不同的。但是支付业务是由支付团队提供的,他们是一套完全相同的api暴露给我们接入,如果需要传入金额orderAmount,订单号orderNumber,出发地departLocation,到达地arriveLocation等。 如果不用设计模式,代码会是这样的。
分别在英法德意西支付页面调用:
final Map<String, Object> map = new HashMap<>();
map.put("params", getPaymentJsonObj().toString());
PaySDK.startPay(map, new CallBack() {
@Override
public void onResult(Object o) {
String result = (String) o;
}
});
private static JSONObject getPaymentJsonObj() {
JSONObject jsonObject = new JSONObject();
jsonObject.put("orderNumber", orderNumber);
jsonObject.put("orderAmount", orderAmount);
jsonObject.put("departLocation", departLocation);
jsonObject.put("arriveLocation", arriveLocation);
return jsonObject;
}
问题来了,以后要新增一个参数,则需要调用处全部修改,改动较大,可能影响其他逻辑。
用了策略模式我们的代码是这么组织的:
public interface IPay {
String getOrderNumber();
String getOrderAmount();
String getDepartLocation();
String getArriveLocation();
}
public class UKModel implements IPay{
@Override
public String getOrderNumber() {
return "123";
}
@Override
public String getOrderAmount() {
return "12";
}
@Override
public String getDepartLocation() {
return "London";
}
@Override
public String getArriveLocation() {
return "Manchester";
}
}
//其他铁路model也是相同处理
public class PayUtil {
public static void pay(IPay testPay) {
final Map<String, Object> map = new HashMap<>();
map.put("params", getPaymentJsonObj(testPay).toString());
PaySDK.startPay(map, new CallBack() {
@Override
public void onResult(Object o) {
String result = (String) o;
}
});
}
private static JSONObject getPaymentJsonObj(IPay pay) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("orderNumber", pay.getOrderNumber());
jsonObject.put("orderAmount", pay.getOrderAmount());
jsonObject.put("departLocation", pay.getDepartLocation());
jsonObject.put("arriveLocation", pay.getArriveLocation());
return jsonObject;
}
}
发起支付的地方: PayUtil.pay(model);
2、工厂模式:
同样地背景,由于是多条铁路业务,拿首页来说,每个国家铁路展示的模块可能不太一样,包括
- 有的铁路有,有些没有;比如返程时间选择框,乘客选择框,优惠卡选择框
- 所有铁路都有,但是具体表现形式不同;比如取票指南,优势话术,公告展示
- 所有铁路都有,表现形式也是一样的;比如出发时间
我们抽象了一个mainPresenter,英铁和韩铁分别继承它实现ukMainPresenter,krMainPresenter;如上所述,mainPresenter中默认实现共有的功能,如3,提供一个抽象方法供子类实现,且必须实现,如2,子类中完成自己特有的功能,如1;
在进入首页的时候,会根据bizType,获取到匹配自己的presenter,这里就是通过工厂模式:
public class PresenterFactory {
@NonNull
public static IMainContract.IMainPresenter produce(String bizType) {
switch (bizType) {
case SouthKorea:
return new KrMainKrPresenter(bizType);
case UK:
return new UKMainPresenter(bizType);
case TW:
return new TWMainPresenter(bizType);
case JP:
return new JpMainPresenter(bizType);
}
return new KrMainKrPresenter(bizType);
}
}
3、单例模式
无需赘述,sharePreference的管理类,所有的manager类基本都是单例实现的。
4、观察者模式
在列表页做了筛选,首页数据跟着改变,需要有一个listener,在首页register,在列表页筛选完成以后使用notify通知首页进行数据改变。manager类中做的操作就是register的时候将listener添加到一个数据,unRegister的时候从数组中移除,notify的时候遍历数组进行接口调用。
import java.util.*
object FollowManager {
private val followStatusListenerList: MutableList<IFollowStatusListener>?
private val lock = ByteArray(0)
fun registerFollowStatusListener(followStatusListener: IFollowStatusListener?) {
if (followStatusListener == null) {
return
}
synchronized(lock) {
if (!followStatusListenerList!!.contains(followStatusListener)) {
followStatusListenerList.add(followStatusListener)
}
}
}
fun unRegisterFollowStatusListener(followStatusListener: IFollowStatusListener?) {
if (followStatusListener == null) {
return
}
synchronized(lock) {
if (followStatusListenerList!!.contains(followStatusListener)) {
followStatusListenerList.remove(followStatusListener)
}
}
}
fun notifyFollowStatusChangeEvent(followStatus: Int, userId: String?) {
synchronized(lock) {
for (iFollowStatusListener in followStatusListenerList!!) {
iFollowStatusListener.onFollowStatusChange(followStatus, userId)
}
}
}
fun clearListener() {
followStatusListenerList?.clear()
}
init {
followStatusListenerList = ArrayList<IFollowStatusListener>()
}
}
interface IFollowStatusListener {
fun onFollowStatusChange(followStatus: Int?, userId: String?)
}
5、建造者模式
定制的dialog,时间格式format,浮层View
public class TrainDialog {
@NonNull
private Context context;
@NonNull
private IBUDialogConfig config;
private TrainDialog(@NonNull Context context) {
this.context = context;
config = new IBUDialogConfig();
//默认是横向底部按钮
config.type = IBUDialogType.TEXT_BOTTOM_HORIZONTAL_TYPE;
config.textPositive = TrainI18nUtil.getString(R.string.key_done);
config.textNegative = TrainI18nUtil.getString(R.string.key_cancel);
config.canceledOnTouchOutside = false;
config.cancelable = false;
}
public static TrainDialog newInstance(@NonNull Context context) {
return new TrainDialog(context);
}
@NonNull
public TrainDialog setTitle(@Nullable String title) {
config.title = title;
return this;
}
@NonNull
public TrainDialog setCanceledOnTouchOutside(boolean canceledOnTouchOutside) {
config.canceledOnTouchOutside = canceledOnTouchOutside;
return this;
}
@NonNull
public TrainDialog setCancelable(boolean cancelable) {
config.cancelable = cancelable;
return this;
}
@NonNull
public TrainDialog setTitleResID(@StringRes int resID) {
if (resID == 0)
return this;
config.title = TrainI18nUtil.getString(resID);
return this;
}
@NonNull
public TrainDialog setMessageResID(int resID) {
if (resID == 0)
return this;
config.message = TrainI18nUtil.getString(resID);
return this;
}
@NonNull
public TrainDialog setSelectNagtiveDialogListener(@Nullable IBUDialogInterface.SelectNegativeOnClickListener selectNegativeDialogOnClickListener) {
config.selectNegativeOnClickListener = selectNegativeDialogOnClickListener;
return this;
}
@NonNull
public TrainDialog setSelectPositiveDialogListener(@Nullable IBUDialogInterface.SelectPositiveOnClickListener selectPositiveDialogOnClickListener) {
config.selectPositiveOnClickListener = selectPositiveDialogOnClickListener;
return this;
}
@NonNull
public TrainDialog setType(@IBUDialogType String type) {
config.type = type;
return this;
}
@NonNull
public TrainDialog setMessage(@Nullable String message) {
config.message = message;
return this;
}
@NonNull
public TrainDialog setListener(@Nullable final OnMessageDialogListener listener) {
config.textPositiveListener = new IBUDialogInterface.TextOnClickListener() {
@Override
public void onClick() {
if (listener != null) {
listener.onClickPositive();
}
}
};
config.textNegativeListener = new IBUDialogInterface.TextOnClickListener() {
@Override
public void onClick() {
if (listener != null) {
listener.onClickNegative();
}
}
};
return this;
}
@NonNull
public TrainDialog setNegativeText(@Nullable String text) {
config.textNegative = text;
return this;
}
@NonNull
public TrainDialog setNegativeText(@StringRes int resID) {
if (resID == 0) {
return this;
}
config.textNegative = TrainI18nUtil.getString(resID);
return this;
}
@NonNull
public TrainDialog setPositiveText(@Nullable String text) {
config.textPositive = text;
return this;
}
@NonNull
public TrainDialog setPositiveText(@StringRes int resID) {
if (resID == 0) {
return this;
}
config.textPositive = TrainI18nUtil.getString(resID);
return this;
}
public void show() {
IBUDialogHelper.showIBUDialogwithConfig(context, config);
}
@NonNull
public TrainDialog setNegativeButtonHidden(boolean b) {
if (b) {
config.textNegative = "";
}
return this;
}
public interface OnMessageDialogListener {
boolean onClickNegative();
boolean onClickPositive();
}
}