JAVA面向接口编程

阅读https://my.oschina.net/xianggao/blog/610985所记笔记

1.接口的概念:java中,接口是一个特殊的抽象类,接口里面的所有方法都是抽象方法,所有属性都是常量。只定义了方法,但是没有方法的具体实现。
2.接口的思想:接口的思想是指将外部的调用和内部的实现隔离开来,也就是“封装隔离”
3.接口的好处:因为接口将外部的调用和内部的实现隔离开来,所以当改变内部的但是没有改变接口,这样就不会对外部的应用有所影响。让系统变得更加灵活。
往常,在使用接口的时候会创建一个实现类的实例,将其赋值给接口对象
Api api = new Impl();
这样与面向接口编程的思想相违背,因为用户在调用的时候,不仅知道接口是Api,而且还知道实现类是Impl。而接口的思想是“封装隔离”,用户应该是只知道接口而不知道具体的实现类。
而把new Impl()去掉的时候又无法得到接口对象,所以为了解决这个问题,我们用到了简单工厂。

简单工厂
1.简单工厂的定义:提供一个创建对象实例的功能,而无需关心其具体实现。被创建实例的类型可以是接口,抽象类,也可以是具体的类。
2.简单工厂的思路:在模块内部建造一个类,这个类专门用来创建接口,然后把创建好的接口返回给客户端,这样外部应用可以通过这个类来得到相应的接口对象。

/*
定义一个接口
*/
public interface Api{
    public void func();
}

/*
定义一个实现类
*/
public class Impl implements Api{
    public void func(){
        System.out.println("这是一个实现类");
    }
}

/*
创建一个工厂类
*/
public class Factory{
    public static Api createApi(){
        return new Impl();
    }
}

/*
客户端
*/
public class Client{
    public static void main(String[] args){
        Api api = Factory.createApi();
        api.func();
    }
}


问题:如果我们一个接口有多个实现类,或者在原有的基础上新增了一个实现类,那么就需要去修改工厂类的createApi方法,这样也是很不方便。
解决方法:使用配置文件
使用最简单的配置文件:定义一个名称为“Factory.properties”的配置文件,放在和Factory同一包下,内容是ImplClass=com.api.Impl
工厂类的实现改成:
/**
* 工厂类,用来创造Api对象
*/  
public class Factory {  
/**
 * 具体的创造Api的方法,根据配置文件的参数来创建接口
 * @return 创造好的Api对象
 */  
public static Api createApi(){  
    //直接读取配置文件来获取需要创建实例的类  
    //至于如何读取Properties,还有如何反射这里就不解释了  
    Properties p = new Properties();  
    InputStream in = null;  
    try {  
        in = Factory.class.getResourceAsStream("Factory.properties");  
        p.load(in);  
    } catch (IOException e) {  
        System.out.println("装载工厂配置文件出错了,具体的堆栈信息如下:");  
        e.printStackTrace();  
    }finally{  
        try {  
            in.close();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
    }  
    //用反射去创建,那些例外处理等完善的工作这里就不做了  
    Api api = null;  
    try {  
        api = (Api)Class.forName(p.getProperty("ImplClass")).newInstance();  
    } catch (InstantiationException e) {  
        e.printStackTrace();  
    } catch (IllegalAccessException e) {  
        e.printStackTrace();  
    } catch (ClassNotFoundException e) {  
        e.printStackTrace();  
    }  
    return api;  
}  
}


你可能感兴趣的:(学习笔记)