估計看到這個博文名字會有很些人懵逼,其實懵逼是正常的,由於剛聽到這個名字我也是出於懵逼狀態,也是看過相似的博文以後纔有了那麼點點的瞭解。java
1、面向接口的編程
編程
面向接口的編程目的是爲了更好的代碼擴展,由於對於java語言而言容許向上轉型。安全
2、面向對象的開發多線程
對於java世界而言,全部現實中的和非現實的事物一切都是能夠抽象化的,萬物皆對象。函數
如何抽象化接口爲java中的對象?this
接口包含了接口和抽象類,那麼這裏最終咱們最關心的其實仍是抽象方法。那麼咱們是否能夠把方法看到一個對象?姑且能夠,那麼咱們方法自身存在的那些屬性?
spa
屬性:方法名, 形參,返回值。線程
行爲:code
一、根據調用的方法執行某些行爲(無形參,無返回值)
對象
二、根據調用的方法執行某些行爲(有形參,無返回值)
三、根據調用的方法執行某些行爲(無形參,有返回值)
三、根據調用的方法執行某些行爲(有形參,有返回值)
定義方法的抽象類(也能夠接口)
1 /** 2 * 做者:liemng on 2017/11/15 3 * 郵箱:859686819@qq.com 4 */ 5 6 public abstract class Function { 7 8 public String mFunctionName; 9 10 public Function(String functionName){ 11 this.mFunctionName = functionName; 12 } 13 }
這裏定義抽象類Function,而且定義一個傳入方法名字的構造函數。
接下來我們按照上班的行爲順序定義以下Function的子類.
FunctionNoParamsNoResult 無形參無返回值類,而且定義抽象方法invoke()
1 /**
2 * 做者:liemng on 2017/11/15 3 * 郵箱:859686819@qq.com 4 */
5
6 public abstract class FunctionNoParamsNoResult extends Function { 7 public FunctionNoParamsNoResult(String functionName) { 8 super(functionName); 9 } 10
11 public abstract void invoke(); 12 }
FunctionWithParamsOnly 有形參無返回值類,而且定義抽象方法invoke(params) 因爲參數類型是未知故而採用了泛型
1 /** 2 * 做者:liemng on 2017/11/15 3 * 郵箱:859686819@qq.com 4 */ 5 6 public abstract class FunctionWithParamsOnly extends Function { 7 public FunctionWithParamsOnly(String functionName) { 8 super(functionName); 9 } 10 11 public abstract <Params> void invoke(Params params); 12 }
FunctionWithResultOnly 無形參有返回值類,而且定義了抽象方法invoke()
1 /** 2 * 做者:liemng on 2017/11/15 3 * 郵箱:859686819@qq.com 4 */ 5 6 public abstract class FunctionWithResultOnly extends Function { 7 8 public FunctionWithResultOnly(String functionName) { 9 super(functionName); 10 } 11 12 public abstract <Result> Result invoke(); 13 }
FunctionWithParamsAndResult 有形參有返回值類,而且定義了抽象方法invoke(params) 因爲參數類型是未知故而採用了泛型
1 /** 2 * 做者:liemng on 2017/11/15 3 * 郵箱:859686819@qq.com 4 */ 5 6 public abstract class FunctionWithParamsAndResult extends Function { 7 public FunctionWithParamsAndResult(String functionName) { 8 super(functionName); 9 } 10 11 public abstract <Result, Params> Result invoke(Params params); 12 }
到這裏進步完成了對象的行爲和屬性的定義,對於屬性因爲是是未知的,故而直接使用了泛型。
那麼接下來就是如何去使用定義的方法類。這裏咱們添加以下管理類FunctionManager。
根據上述的定義咱們知道這裏對於方法的行爲咱們這裏定義了四種行爲,那麼咱們這裏簡單的經過註解添加個約束。見代碼
1 public static final int TYPE_WITH_RESULT_ONLY = 0; 2 public static final int TYPE_WITH_PARAMS_ONLY = 1; 3 public static final int TYPE_NO_PARAMS_NO_RESULT = 2; 4 public static final int TYPE_WITH_PARAMS_AND_RESULT = 3; 5 6 7 /*因爲方法行爲僅僅存在四種,故而這裏僅僅容許添加四種Action*/ 8 @IntDef({TYPE_WITH_RESULT_ONLY, TYPE_WITH_PARAMS_ONLY, TYPE_NO_PARAMS_NO_RESULT, TYPE_WITH_PARAMS_AND_RESULT}) 9 @Target(ElementType.PARAMETER) 10 @Retention(RetentionPolicy.SOURCE) 11 public @interface Type { 12 }
這裏咱們看到註解類Type被註解@IntDef註解,這裏說下@IntDef這裏是約束警告元註解。這裏拿方法的形參來簡單講解下該註解,該註解接受整形數據做爲參數,而且被該元註解註解的註解用在方法的整形的形參上以後,這個形參對應的值必須是元註解中傳入的任意一個值,不然就提示警告錯誤。這裏咱們用來約束方法的行爲。
根據對應的方法行爲來存儲對應的方法對象。
1 private Map<Integer, List<? super Function>> mFuncMap; 2 3 /** 4 * 根據特定的Type添加對應的Function 5 * @param type 6 * @param funcName 7 * @param function 8 */ 9 public void addFunc(@Type int type, @NonNull String funcName, @NonNull Function function) { 10 if (TextUtils.isEmpty(funcName) || null == function) { 11 return; 12 } 13 List<? super Function> funcWithResult = mFuncMap.get(type); 14 if (funcWithResult.contains(function)) 15 return; 16 funcWithResult.add(function); 17 }
第九行咱們看到咱們的註解Type約束了對應的形參,這裏也就是咱們的約束。mFuncMap是用於存儲對應的行爲的方法對象。
這個方法最重要的目的是完成對應的方法對象的添加。
接下是添加的方法如何被一一有效的調用執行。那麼這裏咱們僅僅簡單的看下對應的調用無形參無返回值的方法調用,其餘的都基本相似,咱們直接忽略。
調用無形參無返回值。那麼能夠根據對應的方法名找到對應的方法對象,調用對應的invoke方法。以下見代碼:
1 /** 2 * 調用無形參 無返回值的方法 3 * @param funcName 方法名 4 * @return 5 */ 6 public void invokeFuncWithParamsAndResult(@NonNull String funcName) { 7 /*filter invalid tag*/ 8 if (TextUtils.isEmpty(funcName)) 9 return; 10 List<? super Function> funcList = mFuncMap.get(TYPE_NO_PARAMS_NO_RESULT); 11 12 /*inner filter invalid tag*/ 13 if (null == funcList || funcList.size() <= 0) 14 return; 15 16 FunctionNoParamsNoResult func; 17 for (Object obj : funcList) { 18 func = ((FunctionNoParamsNoResult) obj); 19 if (funcName.equals(func.mFunctionName)) { 20 func.invoke(); 21 } 22 } 23 }
FunctionManager的完整代碼以下:
/** * 做者:liemng on 2017/11/15 * 郵箱:859686819@qq.com */ public class FunctionManager { public static final String TAG = Function.class.getSimpleName(); public static final int TYPE_WITH_RESULT_ONLY = 0; public static final int TYPE_WITH_PARAMS_ONLY = 1; public static final int TYPE_NO_PARAMS_NO_RESULT = 2; public static final int TYPE_WITH_PARAMS_AND_RESULT = 3; /*因爲方法行爲僅僅存在四種,故而這裏僅僅容許添加四種Action*/ @IntDef({TYPE_WITH_RESULT_ONLY, TYPE_WITH_PARAMS_ONLY, TYPE_NO_PARAMS_NO_RESULT, TYPE_WITH_PARAMS_AND_RESULT}) @Target(ElementType.PARAMETER) @Retention(RetentionPolicy.SOURCE) public @interface Type { } private FunctionManager() { /*存儲 須要返回值的Function*/ List<? super Function> funcWithResult = new ArrayList<>(); /*存儲 僅僅包含形參*/ List<? super Function> funcWithParams = new ArrayList<>(); /*存儲 無形參和返回值*/ List<? super Function> funcNoParamsNoResult = new ArrayList<>(); /*存儲 擁有返回值和形參*/ List<? super Function> funcWithParamsAndResult = new ArrayList<>(); mFuncMap = new HashMap<>(); mFuncMap.put(TYPE_WITH_PARAMS_ONLY, funcWithParams); mFuncMap.put(TYPE_WITH_RESULT_ONLY, funcWithResult); mFuncMap.put(TYPE_NO_PARAMS_NO_RESULT, funcNoParamsNoResult); mFuncMap.put(TYPE_WITH_PARAMS_AND_RESULT, funcWithParamsAndResult); } private static FunctionManager mFunctionManager; /** * 多線程安全單例 * * @return FunctionManager */ public static FunctionManager getInstance() { if (null == mFunctionManager) { synchronized (FunctionManager.class) { if (null == mFunctionManager) { mFunctionManager = new FunctionManager(); } } } return mFunctionManager; } private Map<Integer, List<? super Function>> mFuncMap; /** * 根據特定的Type添加對應的Function * @param type * @param funcName * @param function */ public void addFunc(@Type int type, @NonNull String funcName, @NonNull Function function) { if (TextUtils.isEmpty(funcName) || null == function) { return; } List<? super Function> funcWithResult = mFuncMap.get(type); if (funcWithResult.contains(function)) return; funcWithResult.add(function); } /** * 根據特定的Type移除對應的Function * 返回1:移除成功 0:失敗 -1:無效 * @param type * @param function */ public int removeFunc(@Type int type, @NonNull Function function){ List<? super Function> funcWithResult = mFuncMap.get(type); if (funcWithResult.contains(function)) return -1; return funcWithResult.remove(function) ? 1 : 0; } /** * 調用無形參 有返回值的方法 * @param funcName 方法名 * @param <Result> 返回值類型 * @return */ public <Result> Result invokeFuncWithResult(@NonNull String funcName) { /*filter invalid tag*/ if (TextUtils.isEmpty(funcName)) return null; List<? super Function> funcList = mFuncMap.get(TYPE_WITH_RESULT_ONLY); /*inner filter invalid tag*/ if (null == funcList || funcList.size() <= 0) return null; FunctionWithResultOnly func; for (Object obj : funcList) { func = ((FunctionWithResultOnly) obj); if (funcName.equals(func.mFunctionName)) { return (Result)func.invoke(); } } return null; } /** * 調用有形參 有返回值的方法 * @param funcName 方法名 * @return */ public <Params, Result> Result invokeFuncWithParamsAndResult(@NonNull String funcName, Params params) { /*filter invalid tag*/ if (TextUtils.isEmpty(funcName)) return null; List<? super Function> funcList = mFuncMap.get(TYPE_WITH_PARAMS_AND_RESULT); /*inner filter invalid tag*/ if (null == funcList || funcList.size() <= 0) return null; FunctionWithParamsAndResult func; for (Object obj : funcList) { func = ((FunctionWithParamsAndResult) obj); if (funcName.equals(func.mFunctionName)) { return (Result) func.invoke(params); } } return null; } /** * 調用有形參 無返回值的方法 * @param funcName 方法名 * @return */ public <Params> void invokeFuncWithParams(@NonNull String funcName, Params params) { /*filter invalid tag*/ if (TextUtils.isEmpty(funcName)) return; List<? super Function> funcList = mFuncMap.get(TYPE_WITH_PARAMS_ONLY); /*inner filter invalid tag*/ if (null == funcList || funcList.size() <= 0) return; FunctionWithParamsOnly func; for (Object obj : funcList) { func = ((FunctionWithParamsOnly) obj); if (funcName.equals(func.mFunctionName)) { func.invoke(params); } } } /** * 調用無形參 無返回值的方法 * @param funcName 方法名 * @return */ public void invokeFuncWithParamsAndResult(@NonNull String funcName) { /*filter invalid tag*/ if (TextUtils.isEmpty(funcName)) return; List<? super Function> funcList = mFuncMap.get(TYPE_NO_PARAMS_NO_RESULT); /*inner filter invalid tag*/ if (null == funcList || funcList.size() <= 0) return; FunctionNoParamsNoResult func; for (Object obj : funcList) { func = ((FunctionNoParamsNoResult) obj); if (funcName.equals(func.mFunctionName)) { func.invoke(); } } } }