一:接口回顾
1.Java中接口的概念
在Java 中接口是一种特殊的抽象类,跟一般的抽象类相比,接口里面的所有方法都是抽象方法,接口里面的属性都是常量。
2.接口是用来干什么的
接口就是”封装隔离“
接口用来定义实现类的外观
接口是系统可插拔性的保证
3.接口和抽象类的选择
1)优先选用接口
2)在既要定义子类行为,又要为子类提供公共的功能时应该选择抽象类。
二:面向接口编程
在Java程序设计里面,非常讲究层的划分和模块的划分。通常按照三层来划分 Java程序,分别是表现层、逻辑层、数据称,它们之间通过接口来通信。
在每一个层里面,又有很多个小模块,每个小模块对外则是一个整体,所以一个模块对外应该提供接口,其他地方需要使用到这个模块的功能时,可以通过此接口来进行调用。也就是常说的”接口是被其隔离部分的外观“。
所谓组件:从设计上讲,组件就是能够完成一定功能的封装体。
从设计的角度看,系统、子系统、模块、组件等说的其实是同一回事,都是完成一定功能的封装体,只不过功能多少而已。
三:简单工厂设计模式
1.不用模式的解决方案
1)首先定义接口Api,示例代码如下:
3.使用简单工厂设计模式
1)Api 定义的示例代码:
2)定义接口。ImplA 的示例代码如下:
ImplB 的示例代码如下:
3)简单工厂的实现,代码如下:
4)客户端代码如下:
4.可配置的简单工厂
1)环境和问题
现在希望新增加了实现类过后不修改工厂类,怎么办?
一个解决的方法就是使用配置文件,当有了新的实现类后,只要在配置文件里面配置上性的实现类即可。在简单工厂的方法里面可以使用反射。
2)使用可配置的简单工厂
a.配置文件使用最简单的 properties 文件,实际开发中多是xml配置。
定义一个名为“”的配置文件,放置到Factory 同一个包下面,内容如下:
b.此时的工厂类实现如下:
c.客户端的代码:
四:总结简单工厂
1.简单工厂的功能
一定要注意,虽然示例代码是利用简单工厂来创建接口,但是也可以用简单工厂来创建抽象类或普通类的实例。
2.静态工厂
简单工厂的方法通常是静态的,所以它被称为静态工厂。通常不需要创建简单工厂的类实例,所以如果要防止客户端无谓地创造简单工厂实例,还可以把简单工厂的构造方法私有化。
3.万能工厂
一个简单工厂可以包含很多用来构造东西的方法,这些方法可以创建不同的接口,抽象类,或是类实例。
简单工厂可以有多个构造接口,抽象类,实例类对象的方法。
4.简单工厂创建对象的范围
通常不要太大,建议控制在一个独立的组件级别或者一个模块级别,也就是一个组件或模块简单工厂,否则这个工厂会职责不明。
5.简单工厂的命名建议
1)类名称建议为“模块名称+Factory”
2)方法通常为“get+接口名称”或者“create+接口名称”
五:思考简单工厂
1.简单工厂的本质
简答工厂的本质是:选择实现
实现工厂的难点就在于“如何选择”的实现,前面讲到了几种传递参数的方法都是静态的参数,还可以实现成为动态的参数。比如在运行期间,由工厂去读取摸个内存的值,或者是读取数据库中的值,然后在根据具体的值来实现。
2.合适选用简单工厂
1)如果想要完全封装隔离具体实现,让外部只能通过接口来操作封装体。
2)如果想要把对外创建对象的指责集中管理和控制。
1.不用模式的解决方案
1)首先定义接口Api,示例代码如下:
<span style="font-size:14px;">/**
* 某个接口(通用的、抽象的、非具体的)
*/
public interface Api{
/**
* 某个具体的功能方法定义,用test1 来演示一下
* 这里的功能很简单,把传人的 s 打印出来即可
* @param s 任意想要打印输出字符串
*/
public void test1(String s);
}</span>
2)既然有了接口,自然就要有实现,实现 Impl ,示例代码如下
<span style="font-size:14px;">/**
* 对接口的实现
*/
public class Impl implements Api{
public void test1(String s ){
System.out.println("Now In Impl. The input s == "+s);
}
}</span>
3)客户端代码示例<span style="font-size:14px;">/**
* 客户端:测试使用 Api 接口
*/
public class Client{
public static void main (String [] args){
Api api = new Impl();
api.test1("这是一个测试!");
}
}</span>
3.使用简单工厂设计模式
1)Api 定义的示例代码:
<span style="font-size:14px;">/**
* 接口的定义,该接口可以通过简单工厂来创建
*/
public interface Api{
/**
* 具体功能方法的定义
* @param s ,需要的参数
*/
public void operation(String s);
}</span>
2)定义接口。ImplA 的示例代码如下:
<span style="font-size:14px;">/**
* 接口的具体实现对象 A
*/
public class ImplA implements Api{
public void operation(String s){
//实现功能代码
System.out.println("ImplA s == "+s);
}
}</span>
ImplB 的示例代码如下:
<span style="font-size:14px;">/**
* 接口的具体实现对象 B
*/
public class ImplB implements Api{
public void operation(String s){
//实现功能代码
System.out.println("ImplB s == "+s);
}
}
</span>
3)简单工厂的实现,代码如下:
<span style="font-size:14px;">/**
* 工厂类,用来创建 Api 的
*/
public class Factory{
/**
* 防止客户端无谓地创造简单的工厂实例,把构造方法私有化
*/
private Factory(){
}
/**
* 简单工厂的方法内部主要实现的功能是——选择合适的实现类
* 选择的条件和参数的来源:
* 1.来源于客户端,由Client来传人参数
* 2.来源于配置文件,从配置文件获取用于判断的值
* 3.来源于程序运行期的某个值,比如从缓存中获取某个运行期间的值,或者数据库中的值
*/
public static Api getApi(int type){
Api api = null;
/**
* Api 接口的实现类可以有多个,可以更具需要来选择使用那种实现方式
*/
if(type == 1){
api = new ImplA();
}
else if(type == 2){
api = new ImplB();
}
}
}
</span>
4)客户端代码如下:
/**
* 客户端代码,测试使用Api接口
*/
public class Client {
public static void main(String [] args){
//注意这里传递的参数
Api api = Factory.getApi(2);
api.test1("这只是一个测试!");
}
}
4.可配置的简单工厂
1)环境和问题
现在希望新增加了实现类过后不修改工厂类,怎么办?
一个解决的方法就是使用配置文件,当有了新的实现类后,只要在配置文件里面配置上性的实现类即可。在简单工厂的方法里面可以使用反射。
2)使用可配置的简单工厂
a.配置文件使用最简单的 properties 文件,实际开发中多是xml配置。
定义一个名为“”的配置文件,放置到Factory 同一个包下面,内容如下:
ImplClass = cn.javass.dp.simplefactory.example5.Impl
如果添加了实现类,修改这里的配置文件即可。
b.此时的工厂类实现如下:
/**
* 工厂类,用来创建Api 对象
*/
public class Factory{
/**
* 具体创建 Api 的方法,根据配置文件的参数来创建接口
* @return 创建好的 Api 对象
*/
public static Api getApi(){
//直接读取配置文件来获取需要创建实例的类
//至于如何读取 Properties ,还有如何反射就不解释了
Properties p = new Properties();
ImputStream in = null;
try{
in = Factory.class.getResourceAsStream("FactoryTest.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;
}
}
c.客户端的代码:
public class Client{
public static void main(String[] args){
Api api = Factory.getApi();
api.test1("这是一个测试!");
}
}
四:总结简单工厂
1.简单工厂的功能
一定要注意,虽然示例代码是利用简单工厂来创建接口,但是也可以用简单工厂来创建抽象类或普通类的实例。
2.静态工厂
简单工厂的方法通常是静态的,所以它被称为静态工厂。通常不需要创建简单工厂的类实例,所以如果要防止客户端无谓地创造简单工厂实例,还可以把简单工厂的构造方法私有化。
3.万能工厂
一个简单工厂可以包含很多用来构造东西的方法,这些方法可以创建不同的接口,抽象类,或是类实例。
简单工厂可以有多个构造接口,抽象类,实例类对象的方法。
4.简单工厂创建对象的范围
通常不要太大,建议控制在一个独立的组件级别或者一个模块级别,也就是一个组件或模块简单工厂,否则这个工厂会职责不明。
5.简单工厂的命名建议
1)类名称建议为“模块名称+Factory”
2)方法通常为“get+接口名称”或者“create+接口名称”
五:思考简单工厂
1.简单工厂的本质
简答工厂的本质是:选择实现
实现工厂的难点就在于“如何选择”的实现,前面讲到了几种传递参数的方法都是静态的参数,还可以实现成为动态的参数。比如在运行期间,由工厂去读取摸个内存的值,或者是读取数据库中的值,然后在根据具体的值来实现。
2.合适选用简单工厂
1)如果想要完全封装隔离具体实现,让外部只能通过接口来操作封装体。
2)如果想要把对外创建对象的指责集中管理和控制。