阅读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;
}
}