面向接口的开发到面向对象的编程

  估计看到这个博文名字会有很些人懵逼,其实懵逼是正常的,因为刚听到这个名字我也是出于懵逼状态,也是看过类似的博文之后才有了那么点点的了解。

  一、面向接口的编程

    面向接口的编程目的是为了更好的代码扩展,因为对于java语言而言允许向上转型。

  二、面向对象的开发

    对于java世界而言,所有现实中的和非现实的事物一切都是可以抽象化的,万物皆对象。

  如何抽象化接口为java中的对象?

  接口包含了接口和抽象类,那么这里最终我们最关心的其实还是抽象方法。那么我们是否可以把方法看到一个对象?姑且可以,那么我们方法自身存在的那些属性?

    属性:方法名, 形参,返回值。

    行为:

      1、根据调用的方法执行某些行为(无形参,无返回值)

      2、根据调用的方法执行某些行为(有形参,无返回值)

      3、根据调用的方法执行某些行为(无形参,有返回值)

      3、根据调用的方法执行某些行为(有形参,有返回值)

  定义方法的抽象类(也可以接口)

 1 /**
 2  * 作者:liemng on 2017/11/15
 3  * 邮箱:[email protected]
 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  * 邮箱:[email protected]
 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  * 邮箱:[email protected]
 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  * 邮箱:[email protected]
 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  * 邮箱:[email protected]
 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
 * 邮箱:[email protected]
 */

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();
            }
        }
    }
}
时间: 2024-07-29 18:08:16

面向接口的开发到面向对象的编程的相关文章

面向接口设计和编程——(面向对象、面向接口、面向过程、面向实现) --转载

引言--面向接口所处的设计模式中的位置. 其实,我认为Java/C#比C++高级的其中一个原因是,它对面向接口编程的支持.不要误解,并不是说C++不支持面向接口编程,而是说C++的语法中没有这种天然的机制. 面向对象之于面向过程,面向接口之于面向实现.但基本上,面向接口和面向实现都基于面向对象的模式,也就是说面向接口并不能称为比面向对象的更高的一种编程模式.而是在面向对象中大的背景下的一种更加合理的软件设计模式,它增强了类与类之间,模块与模块的之间的低耦合性,是软件系统更容易维护.扩展. 不管是

PHP面向对象(OOP)编程完全教程

转自:http://blog.snsgou.com/post-41.html 面向对象编程(OOP)是我们编程的一项基本技能,PHP5对OOP提供了良好的支持.如何使用OOP的思想来进行PHP的高级编程,对于提高PHP编程能力和规划好Web开发构架都是非常有意义的.下面我们就通过实例来说明使用PHP的OOP进行编程的实际意义和应用方法. 我们通常在做一个有数据库后台的网站的时候,都会考虑到程序需要适用于不同的应用环境.和其他编程语言有所不同的是,在PHP中,操作数据库的是一系列的具体功能函数(如

PHP面向对象(OOP)编程入门教程链接

PHP官方学习OOP: http://php.net/manual/zh/oop5.intro.php 以下链接来源: http://blog.snsgou.com/post-41.html PHP面向对象(OOP)编程完全教程:1.什么是面向对象? PHP面向对象(OOP)编程完全教程:2.什么是类,什么是对象,类和对象这间的关系 PHP面向对象(OOP)编程完全教程:3.什么是面向对象编程呢? PHP面向对象(OOP)编程完全教程:4.如何抽象出一个类? PHP面向对象(OOP)编程完全教程

那些年搞不懂的高深术语——依赖倒置?控制反转?依赖注入?面向接口编程

那些年,空气中仿佛还能闻到汉唐盛世的余韵,因此你决不允许自己的脸上有油光,时刻保持活力.然而,你一定曾为这些“高深术语”感到过困扰.也许时至今日,你仍对它们一知半解.不过就在今天,这一切都将彻底改变!我将带领你以一种全新的高清视角进入奇妙的编程世界,领略涵泳在这些“高深术语”中的活泼泼的地气,以及翩跹于青萍之末的云水禅心. ·内聚 内聚,通俗的来讲,就是自己的东西自己保管,自己的事情自己做. 经典理论告诉我们,程序的两大要素:一个是数据(data),一个是操作(opration).而 PASCA

面向对象的编程和面向过程的编程有什么区别

C语言是面向过程的编程,它的最重要特点是函数,通过主函数来调用一个个子函数.程序运行的顺序都是程序员决定好了的.它是我学的第一种程序语言. C++是面向对象的编程,类是它的主要特点,程序执行过程中,先由主函数进入,定义一些类,根据需要,执行类的成员函数,过程的概念被淡化了(实际上过程还是有的,就是主函数的那些语句),类就是对象,所以我们称之为面向对象程序设计. 不同点:1.编程模型 所有计算机均由两种元素组成:代码和数据.精确的说,有些程序是围绕着"什么正在发生"而编写,有些则是围绕&

面向“接口”编程和面向“实现”编程

来自http://www.vaikan.com/program-to-an-interface-fool/ 面向'接口'编程,而不是面向'实现'. 这是什么意思? 首先我们需要理解什么是'接口',什么是'实现'.简言之,一个接口就是我们要调用的一系列方法的集合,有对象将会响应这些方法调用. 一个实现就是为接口存放代码和逻辑的地方. 本质上讲,这个原则倡导的是,当我们写一个函数或一个方法时,我们应该引用相应的接口,而不是具体的实现类. 面向'实现'编程 首先我们看看,如果不遵循这个原则会发生什么.

java中面向接口编程

面向接口编程详解(一)——思想基础 我想,对于各位使用面向对象编程语言的程序员来说,“接口”这个名词一定不陌生,但是不知各位有没有这样的疑惑:接口有什么用途?它和抽象类有什么区别?能不能用抽象类代替接口呢?而且,作为程序员,一定经常听到“面向接口编程”这个短语,那么它是什么意思?有什么思想内涵?和面向对象编程是什么关系?本文将一一解答这些疑问. 1.面向接口编程和面向对象编程是什么关系 首先,面向接口编程和面向对象编程并不是平级的,它并不是比面向对象编程更先进的一种独立的编程思想,而是附属于面向

大话依赖倒置?控制反转?依赖注入?面向接口编程

那些年,空气中仿佛还能闻到汉唐盛世的余韵,因此你决不允许自己的脸上有油光,时刻保持活力.然而,你一定曾为这些“高深术语”感到过困扰——依赖倒置•控制反转•依赖注入•面向接口编程.也许时至今日,你仍对它们一知半解.不过就在今天,这一切都将彻底改变!我将带领你以一种全新的高清视角进入奇妙的编程世界,领略涵泳在这些“高深术语”中的活泼泼的地气,以及翩跹于青萍之末的云水禅心. ·内聚 内聚,通俗的来讲,就是自己的东西自己保管,自己的事情自己做. 经典理论告诉我们,程序的两大要素:一个是数据(data),

面向接口编程

系列——MEF实现设计上的“松耦合”(终结篇:面向接口编程) 序:忙碌多事的八月带着些许的倦意早已步入尾声,金秋九月承载着抗战胜利70周年的喜庆扑面而来.没来得及任何准备,似乎也不需要任何准备,因为生活不需要太多将来时.每天忙着上班.加班.白加班,忘了去愤,忘了去算计所谓的价值.天津爆炸事故时刻警示着我们生命的无常,逝者安息,活着的人生活还得继续,珍惜生命,远离伤害.武汉,这座炙热的城市,虽值金秋,却依然经受着“秋老虎”的烘烤,马路上蒸腾的热气迎面袭来,全身毛孔张开,汗流不止,在这般高温下,似乎