如果你是因为上文设计模式——面向对象进阶之面向接口再抽象实现通用的接口框架(一)而过来的,可以直接往下阅读,反之就请先去阅读上文。如果采用普通的接口形式我想下面这张图在很多人的代码中都会出现过吧,尤其是Activity和Fragment的交互方面使用回调的方式来进行的话更加无可避免,看起来是不是很臃肿,不优雅而且繁琐,这套框架就是基于此设计的,这里插个题外话比较了下Activity和Fragment之间通信方式的优缺点:
这里需要扯一下设计这个管理对象的核心思想,上文我们把所有接口按照类型分别抽象成了六大对象,首先直观的你要使用接口你得先new 构造成对应的对象,而且同一接口有可能在不同地方被调用,这就考虑性能的话自然涉及到缓存、重用机制,于是设计了六组HashMap(也可以使用ArrayMap、SparesArray等Android特有的数据结构)以接口名.方法名为key分别用于存储不同的接口,其次,这个接口管理角色是用于管理接口(包括缓存、调用)的自身应该设计为单例模式节省资源,再次既然设置了缓存机制就得实现缓存,这里实现很简单再抽象接口管理对象自身构造方法被调用的时候就初始化六组HashMap,然后通过put方法把键值对存储到对应的Map中也就完成了所谓的缓存,再次就是实现调用,注意这里的调用仅仅是去传递调用逻辑,本质上就是去调用上文中抽象的接口对象中的抽象方法(至于具体的逻辑都延迟到真正生成接口的时候去实现),最后就是通过与泛型结合实现可变返回值类型和可变参数类型。
package arch;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
/**
* Auther: Crazy.Mo on 2018/4/9 17:19 Summary:用于统一管理所有抽象出的接口对象
*/
public class FunctionManager {
//定义HashMap以接口名.方法名 为键用于缓存接口对象
private HashMap mNoParamNoResultMap;
private HashMap mNoParamWithResultMap;
private HashMap mWithParamNoResultMap;
private HashMap mWithParamWithResultMap;
private HashMap mWithVariableParamsWithResultMap;
private HashMap mWithVariableParamsNoResultMap;
//在第一次调用构造方法时候初始化对应的Map
private FunctionManager() {
mNoParamNoResultMap = new HashMap<>();
mNoParamWithResultMap = new HashMap<>();
mWithParamNoResultMap = new HashMap<>();
mWithParamWithResultMap = new HashMap<>();
mWithVariableParamsNoResultMap = new HashMap<>();
mWithVariableParamsWithResultMap = new HashMap<>();
}
public static FunctionManager getInstance() {
return FunctionManager.FunctionManagerHolder.single;
}
private static class FunctionManagerHolder {
private final static FunctionManager single = new FunctionManager();
}
//把无参无返回值类型的接口缓存起来
public FunctionManager addFunciton(
FunctionNoParamNoResult pFunctionNoParamNoResult) {
if (pFunctionNoParamNoResult != null) {
mNoParamNoResultMap.put(pFunctionNoParamNoResult.getFuncName(),
pFunctionNoParamNoResult);
}
return this;
}
public FunctionManager addFunciton(
FunctionNoParamWithResult> pFunctionNoParamWithResult) {
if (pFunctionNoParamWithResult != null) {
mNoParamWithResultMap.put(pFunctionNoParamWithResult.getFuncName(),
pFunctionNoParamWithResult);
}
return this;
}
public FunctionManager addFunciton(
FunctionWithParamNoResult> pFunctionWithParamNoResult) {
if (pFunctionWithParamNoResult != null) {
mWithParamNoResultMap.put(pFunctionWithParamNoResult.getFuncName(),
pFunctionWithParamNoResult);
}
return this;
}
public FunctionManager addFunciton(
FunctionWithParamWithResult, ?> pFunctionWithParamWithResult) {
if (pFunctionWithParamWithResult != null) {
mWithParamWithResultMap.put(
pFunctionWithParamWithResult.getFuncName(),
pFunctionWithParamWithResult);
}
return this;
}
public FunctionManager addFunciton(
FunctionWithVariableParamsNoResult pFunctionWithVariableParamsNoResult) {
if (pFunctionWithVariableParamsNoResult != null) {
mWithVariableParamsNoResultMap.put(
pFunctionWithVariableParamsNoResult.getFuncName(),
pFunctionWithVariableParamsNoResult);
}
return this;
}
public FunctionManager addFunciton(
FunctionWithVariableParamsWithResult> pFunctionWithVariableParamsWithResult) {
if (pFunctionWithVariableParamsWithResult != null) {
mWithVariableParamsWithResultMap.put(
pFunctionWithVariableParamsWithResult.getFuncName(),
pFunctionWithVariableParamsWithResult);
}
return this;
}
/**
*执行接口里的方法
* @param pFunName
* 接口方法名
*/
public void invokeFunc(String pFunName) {
try {
if (TextUtil.isEmpty(pFunName)) {
throw new Exception("the function name is can't empty: ");
}
FunctionNoParamNoResult funcNoParamNoResult = mNoParamNoResultMap
.get(pFunName);
if (funcNoParamNoResult != null) {
funcNoParamNoResult.function();
} else {
throw new Exception("the function is no exited: " + pFunName);
}
} catch (Exception pE) {
pE.printStackTrace();
}
}
/**
* @param pFunName
* 接口方法名
* @param pResultClass
* Result对应的class类型
* @param
* 返回值类型
* @return
*/
public Result invokeFunc(String pFunName,
Class pResultClass) {
try {
if (TextUtil.isEmpty(pFunName)) {
throw new Exception("the function name is can't empty");
}
FunctionNoParamWithResult> funcNoParamWithResult = mNoParamWithResultMap
.get(pFunName);
if (funcNoParamWithResult != null) {
if (pResultClass != null) {
return pResultClass.cast(funcNoParamWithResult.function());// 执行安全转换
} else {
throw new Exception("the Result'class is empty ");
}
} else {
throw new Exception("the function is no exited: " + pFunName);
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* @param pFunName
* 接口方法名
* @param pParam
* 要传入的参数值
* @param pParamClass
* 要传入的参数的class类型
* @param
* 参数类型
*/
public void invokeFunc(String pFunName, Class pParamClass,
Param pParam) {
try {
if (TextUtil.isEmpty(pFunName)) {
throw new Exception("the function name is can't empty");
}
FunctionWithParamNoResult funcWithParamNoResult = mWithParamNoResultMap
.get(pFunName);
if (funcWithParamNoResult != null) {
if (pParamClass != null && pParam != null) {
funcWithParamNoResult.function(pParamClass.cast(pParam));
} else {
throw new Exception("the Param or Param'class is empty");
}
} else {
throw new Exception("the function is no exited: " + pFunName);
}
} catch (Exception pE) {
pE.printStackTrace();
}
}
/**
* @param pFunName
* 接口方法名
* @param pParam
* 要传入的参数值
* @param pParamClass
* 要传入的参数的class类型
* @param pResultClass
* @param pResultClass
* Result对应的class类型
* @param
* 返回值类型
* @return
*/
public Result invokeFunc(String pFunName,
Class pParamClass, Param pParam, Class pResultClass) {
try {
if (TextUtil.isEmpty(pFunName)) {
throw new Exception("the function name is can't empty");
}
FunctionWithParamWithResult funcWithParamWithResult = mWithParamWithResultMap
.get(pFunName);
if (funcWithParamWithResult != null) {
if (pParamClass != null && pParam != null
&& pResultClass != null) {
return pResultClass.cast(funcWithParamWithResult
.function(pParamClass.cast(pParam)));
} else {
throw new Exception("the Param or Param'class is empty");
}
} else {
throw new Exception("the function is no exited: " + pFunName);
}
} catch (Exception pE) {
pE.printStackTrace();
}
return null;
}
/**
*
* @param pFunName 接口方法名
* @param pIndefiniteParams 参数列表
* @param pResultClass 返回值的class类型
* @return
*/
@SuppressWarnings("rawtypes")
public void invokeFunc( String pFunName, ArrayList
这里需要注意此处“接口”变量中的”接口”是加了双引号的,并非我们通常所说的接口(interface),这里的是对应上文中抽象的顶层接口类AbsFunction的String类型的成员变量——mFuncName。
static final String NPNR = "CrazyMo.NPNR";// 第一步定义"接口".方法,这个字符串原则上说可以是任意字段,但最好自己约定一套规范,因为这个值是要作为key的,如果你要任性再同一套里使用相同的值,就会造成缓存Map的时候冲突失败
相当于是常规写法里implement 时Override接口方法的部分,这个步骤也是把上面声明的”接口”变量赋予实际的意义,所以需要把“接口”变量字符串 通过构造方法传递进来
// 1、相当于是常规写法里implement 时Override接口方法的部分
FunctionNoParamNoResult fNoParamNoResult = new FunctionNoParamNoResult(NPNR) {
@Override
public void function() {
System.out.println("接口里方法真正的方法体被实现(无参无返回值类型)");
}
};
// 存放到统一的FunctionManager中进行管理,相当于是注册,这样做的目的是为了在调用时方便
manager.addFunciton(fNoParamNoResult);
在这个框架是通过接口管理对象来间接调用的
FunctionManager.getInstance().invokeFunc(NPNR);
package arch.sample;
import java.util.ArrayList;
import arch.FunctionManager;
import arch.FunctionNoParamNoResult;
import arch.FunctionNoParamWithResult;
import arch.FunctionWithParamNoResult;
import arch.FunctionWithParamWithResult;
import arch.FunctionWithVariableParamsNoResult;
import arch.FunctionWithVariableParamsWithResult;
public class Client {
static final String NPNR = "CrazyMo.NPNR";// 第一步定义"接口".方法
static final String NPWR = "CrazyMo.NPWR";
static final String WPNR = "CrazyMo.WPNR";
static final String WPWR = "CrazyMo.WPWR";
static final String VPWR = "CrazyMo.VPWR";
static final String VPNR = "CrazyMo.VPNR";
public static void main(String[] args) {
implementInterface(NPNR);
implementInterface(NPWR);
implementInterface(WPNR);
implementInterface(WPWR);
implementInterface(VPWR);
implementInterface(VPNR);
involke();
}
// 第二步实现接口,
public static void implementInterface(String type) {
FunctionManager manager = FunctionManager.getInstance();
if (NPNR.equals(type)) {
// 1、相当于是常规写法里implement 时Override接口方法的部分
FunctionNoParamNoResult fNoParamNoResult = new FunctionNoParamNoResult(
NPNR) {
@Override
public void function() {
System.out.println("接口里方法真正的方法体被实现(无参无返回值类型)");
}
};
// 存放到统一的FunctionManager中进行管理,相当于是注册,这样做的目的是为了在调用时方便
manager.addFunciton(fNoParamNoResult);
} else if (NPWR.equals(type)) {
FunctionNoParamWithResult fNoParamWithResult = new FunctionNoParamWithResult(NPWR) {
@Override
public String function() {
String result = "接口里方法真正的方法体被实现(无参有返回值类型)";
System.out.println("返回值为:"+result);
return result;
}
};
manager.addFunciton(fNoParamWithResult);
} else if (WPNR.equals(type)) {
FunctionWithParamNoResult fWithParamNoResult = new FunctionWithParamNoResult(WPNR) {
@Override
public void function(String param) {
System.out.println("接口里方法真正的方法体被实现(有参无返回值类型)参数为"+param);
}
};
manager.addFunciton(fWithParamNoResult);
} else if (WPWR.equals(type)) {
FunctionWithParamWithResult fWithParamWithResult = new FunctionWithParamWithResult(WPWR) {
@Override
public String function(String pParam) {
String param=pParam;
String result = "接口里方法真正的方法体被实现(有参有返回值类型)"+"参数为:"+param;
System.out.println(result);
return result;
}
};
manager.addFunciton(fWithParamWithResult);
}else if (VPWR.equals(type)) {
FunctionWithVariableParamsWithResult fWithParamWithResult = new FunctionWithVariableParamsWithResult(VPWR) {
@Override
public String function(ArrayList pParam) {
String result="";
if(!pParam.isEmpty()){
int size=pParam.size();
for(int i=0;iif(i==2){
result+="第3个实参:"+((ArrayList>)pParam.get(i)).toArray()[1].toString()+"\t";
}else{
result+="第"+(i+1)+"个实参:"+pParam.get(i).toString()+"\t";
}
}
}
System.out.println("返回值:"+result);
return result;
}
};
manager.addFunciton(fWithParamWithResult);
}else if (VPNR.equals(type)) {
FunctionWithVariableParamsNoResult fWithVarParamNoResult = new FunctionWithVariableParamsNoResult(VPNR) {
@Override
public void function(ArrayList pParam) {
String params="";
if(!pParam.isEmpty()){
int size=pParam.size();
for(int i=0;iif(i==2){
params+="第3个实参:"+((ArrayList>)pParam.get(i)).toArray()[1].toString()+"\t";
}else{
params+="第"+(i+1)+"个实参:"+pParam.get(i).toString()+"\t";
}
}
}
System.out.println("参数列表:"+params);
}
};
manager.addFunciton(fWithVarParamNoResult);
}
}
// 使用接口方法
public static void involke() {
FunctionManager.getInstance().invokeFunc(NPNR);
FunctionManager.getInstance().invokeFunc(NPWR,String.class);
FunctionManager.getInstance().invokeFunc(WPNR,String.class,"有参无返回值的参数");
FunctionManager.getInstance().invokeFunc(WPWR,String.class,"有参有返回值的参数",String.class);
ArrayList list=new ArrayList<>();
list.add(0, 109);
list.add(1, "好的精神可嘉分红但是");
list.add(2, list);
list.add(3, true);
FunctionManager.getInstance().invokeFunc(VPWR,list,String.class);//调用不定参数的
FunctionManager.getInstance().invokeFunc(VPNR,list);
}
}
源码及jar包