简单工厂模式:
简单工厂.png简单工厂:产品基类有一个,可延伸多个具体的产品,比如:男产品,女产品。工厂类控制生成具体的产品对象。
// 产品基类
abstract class BaseProduct{
abstract fun makePrd();
}
// 男产品
class MaleProduct:BaseProduct(){
override fun makePrd() {
println("male product make a prd")
}
}
// 女产品
class FemaleProduct:BaseProduct(){
override fun makePrd() {
println("female product make a prd")
}
}
// 工厂类
class Factory {
/**
* 根据不同类型,生成不同的产品对象
*/
fun createProduct(type: String): BaseProduct {
return when (type) {
"male" -> MaleProduct()
"female" -> FemaleProduct()
else -> MaleProduct()
}
}
}
// 调用和输出
fun main(args: Array<String>) {
Factory().createProduct("male").makePrd()
Factory().createProduct("female").makePrd()
//输出:
//male product make a prd
//female product make a prd
}
优势:想拿到具体的对象不需要再手动new
,也就是说你具体对象如何改变,只需要改变工厂类的new
方法,不需要再调用处修改。
劣势:具体产品类的类名修改,那么就需要修改工厂类的when
方法,没有达到理想状态。
工厂模式
工厂.png工厂模式:产品模块和简单工厂一致,但是工厂的实现改变了,不再通过type
来判断生成什么产品类,而是通过反射机制来生成。
// 工厂基类
abstract class BaseFactory {
abstract fun <T : BaseProduct> createProduct(clazz: Class<T>): T
}
// 工厂类,继承工厂基类,通过clazz: Class<T>实现反射来生成具体的产品类
object Factory : BaseFactory() {
override fun <T : BaseProduct> createProduct(clazz: Class<T>): T {
val baseProduct: BaseProduct?
val className = clazz.name
baseProduct = Class.forName(className).newInstance() as BaseProduct
return baseProduct as T
}
}
// 调用和输出
fun main(args: Array<String>) {
Factory.createProduct(MaleProduct::class.java).makePrd()
Factory.createProduct(FemaleProduct::class.java).makePrd()
}
// male product make a prd
// female product make a prd
总结:工厂模式在改变产品具体类的时候,是不需要修改工厂类的,不再需要增加标志位,这样就把工厂和产品分开了。
利用简单工厂和工厂模式封装支付模块
支付.png在下面的demo中只封装了两种支付方式:支付宝和微信
注意:demo是用Java代码完成的,可对照上面Kotlin代码理解两种语言的写法
基础产品类:只有一个动作:支付
import android.app.Activity;
/**
* Author: taonce
* Date: 2018/11/2
* Project:
* Desc: 支付基类
*/
public abstract class BasePay {
public abstract void pay(Activity activity, String orderString, OnPayCallBack callBack);
}
回调接口:目前之封装了成功和失败,可拓展
/**
* Author: taonce
* Date: 2018/11/2
* Project:
* Desc: 支付成功或失败的回调
*/
public interface OnPayCallBack {
void onPaySuccess(String orderId);
void onPayFailed();
}
具体支付类:
- 支付宝支付:支付宝支付是通过
Handler
完成的,直接在pay
方法里实现就行了,不依赖其他类
/**
* Author: taonce
* Date: 2018/11/2
* Project:
* Desc: 支付宝支付
*/
public class AliPay extends BasePay {
private Activity mActivity;
private OnPayCallBack mCallBack;
@Override
public void pay(Activity activity, final String orderString, OnPayCallBack onPayCallBack) {
this.mActivity = activity;
mCallBack = onPayCallBack;
Runnable payRunnable = new Runnable() {
@Override
public void run() {
PayTask payTask = new PayTask(mActivity);
Map<String, String> result = payTask.payV2(orderString, true);
LogUtil.showLog("taonce", "result = " + result);
Message msg = new Message();
msg.what = 1;
msg.obj = result;
mHandler.sendMessage(msg);
}
};
Thread payThread = new Thread(payRunnable);
payThread.start();
}
@SuppressLint("HandlerLeak")
private Handler mHandler = new Handler() {
@SuppressWarnings("unused")
public void handleMessage(Message msg) {
switch (msg.what) {
case 1: {
@SuppressWarnings("unchecked")
PayResult payResult = new PayResult((Map<String, String>) msg.obj);
/**
对于支付结果,请商户依赖服务端的异步通知结果。同步通知结果,仅作为支付结束的通知。
*/
String resultInfo = payResult.getResult();// 同步返回需要验证的信息
String resultStatus = payResult.getResultStatus();
LogUtil.showLog("aulton", "result = " + resultInfo);
// 判断resultStatus 为9000则代表支付成功
if (TextUtils.equals(resultStatus, "9000")) {
// 该笔订单是否真实支付成功,需要依赖服务端的异步通知。
PayinfoBean payInfoBean;
Gson gson = new Gson();
payInfoBean = gson.fromJson(resultInfo, PayinfoBean.class);
String order_id = payInfoBean.alipay_trade_app_pay_response.out_trade_no;
mCallBack.onPaySuccess(order_id);
} else {
// 该笔订单真实的支付结果,需要依赖服务端的异步通知。
mCallBack.onPayFailed();
}
break;
}
default:
break;
}
}
};
}
-
微信支付:
微信支付需要使用单例,因为微信依赖其他类,也就是指定的
WXPayEntryActivity
,支付完回调现在这个类中得知的,我们需要在这个类中判断回调的成功与否。先看具体实现类:
/**
* Author: taonce
* Date: 2018/11/2
* Project:
* Desc: 微信支付
*/
public class WxPay extends BasePay {
private String mPrePayId;
private OnPayCallBack mCallBack;
private Activity mActivity;
private static WxPay mWxPay;
public static WxPay getInstance() {
if (mWxPay == null) {
mWxPay = new WxPay();
}
return mWxPay;
}
/**
* 实现支付请求
* @param activity 当前的activity
* @param orderString 订单字符串
* @param callBack 回调
*/
@Override
public void pay(Activity activity, String orderString, OnPayCallBack callBack) {
this.mActivity = activity;
mCallBack = callBack;
Gson gson = new Gson();
WeiXinBean weiXinBean = gson.fromJson(orderString, WeiXinBean.class);
if (!CommonUtils.isWeinXinExist(mActivity)) {
ToastUitl.showShort("未安装微信");
return;
}
if (weiXinBean == null) {
ToastUitl.showShort("参数为空");
return;
}
IWXAPI api;
api = WXAPIFactory.createWXAPI(mActivity, null);
PayReq request = new PayReq();
request.appId = weiXinBean.appid;
request.nonceStr = weiXinBean.noncestr;
request.partnerId = String.valueOf(weiXinBean.partnerid);
request.prepayId = weiXinBean.prepayid;
mPrePayId = weiXinBean.prepayid;
request.packageValue = weiXinBean.packageValue;
request.sign = weiXinBean.sign;
request.timeStamp = weiXinBean.timestamp;
api.sendReq(request);
}
/**
* 根据错误码判断支付成功与否
* @param errCode 错误码
*/
public void dealResult(int errCode) {
if (errCode == 0) {
// 该笔订单是否真实支付成功,需要依赖服务端的异步通知。
// 调用服务端接口来获取准确的支付成功信息
mCallBack.onPaySuccess(mPrePayId);
} else {
// 该笔订单真实的支付结果,需要依赖服务端的异步通知。
mCallBack.onPayFailed();
}
}
}
接着看微信指定类:WXPayEntryActivity
在onResp
方法中判断结果,把errCode
错误码传给WxPay
,在WxPay
中的dealResult
方法中去处理具体的回调。
public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler {
private static final String TAG = "WXPayEntryActivity";
private IWXAPI api;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.pay_result);
api = WXAPIFactory.createWXAPI(this, null);
api.handleIntent(getIntent(), this);
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
api.handleIntent(intent, this);
}
@Override
public void onReq(BaseReq req) {
}
@Override
public void onResp(BaseResp resp) {
LogUtil.showLog("weixinpay", "transaction =" + resp.transaction);
if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {
WxPay.getInstance().dealResult(resp.errCode);
finish();
}
}
}
简单工厂类:
根据不同的支付方式,创建不同的产品
/**
* Author: taonce
* Date: 2018/11/2
* Project:
* Desc: 支付的工厂类
*/
public class PayFactory {
public static BasePay createPay(String type) {
BasePay basePay;
switch (type) {
case "ali":
basePay = new AliPay();
break;
case "wx":
basePay = WxPay.getInstance();
break;
default:
basePay = WxPay.getInstance();
break;
}
return basePay;
}
}
工厂类:通过反射来获得具体的支付类对象
工厂基类:
public abstract class BaseFactory {
public abstract <T extends BasePay> T createPay(Class<T> tClass);
}
具体工厂类:
public class PayFactory extends BaseFactory {
@Override
public <T extends BasePay> T createPay(Class<T> tClass) {
BasePay basePay = null;
String className = tClass.getName();
try {
basePay = (BasePay) Class.forName(className).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return (T) basePay;
}
}
调用:
简单工厂模式调用:
只需要传入不同的工厂类型就行了,以后如果要添加第三种第四种,只需在工厂类中加入一种类型就行。
PayFactory.createPay("ali").pay(this, paramStr, new OnPayCallBack() {
@Override
public void onPaySuccess(String orderId) {
LogUtil.showLog("pay success");
}
@Override
public void onPayFailed() {
}
});
工厂模式调用:
工厂模式的调用同样也是很简单的,传参传入类名.class就行了。
PayFactory payFactory = new PayFactory();
payFactory.createPay(AliPay.class).pay(this, paramStr, new OnPayCallBack() {
@Override
public void onPaySuccess(String orderId) {
}
@Override
public void onPayFailed() {
}
});
如果大家对支付有兴趣或者有业务需要去了解,那么这里告诫大家一定要把官方支付流程图看懂,尤其是支付宝的流程,在不懂的情况下去写支付,那么接下来肯定会有很多的坑等着你的。
写在最后
每个人不是天生就强大,你若不努力,如何证明自己,加油!
Thank You!
--Taonce
如果你觉得这篇文章对你有所帮助,那么就动动小手指,长按下方的二维码,关注一波吧~~非常期待大家的加入
专注Kotlin知识的公众号
网友评论