简单工厂
一: 简单工厂并不是一个标准的设计模式,但是它实在是太常用了,简单而用实用,所以需要好好掌握.
二: 接口回顾
在Java中要面向接口编程.
1. Java中接口的概念: 在Java中接口是一种特殊的抽象类,跟一般的抽象类相比,接口中的所有方法都是抽象方法,接口里面的所有属性都是常量.也就是说,接口里面只有方法定义而没有方法实现.
2. 接口的作用:
通过接口来定义实现类的外观,也就是实现类的行为定义,用来约束实现类的行为.但是具体的实现类除了实现接口约定的功能外,还可以实现其他的功能.
通过接口可以实现不相关类的相同行为.
3. 接口的思想:
根据接口的作用和用途,综合下来,接口的作用就是”封装隔离”.通常说到的封装就是对数据的封装,但这里说到的封装是对”被隔离体的行为的封装”,或者是”
对被隔离体的职责的封装”.而隔离指的是外部调用和内部实现.外部调用只能通过接口进行调用,外部调用时不知道内部的具体实现的.也就是说外部调用时被接口隔离的.
4. 使用接口的好处:
由于外部调用和内部实现是被接口隔离的,所以只要接口不变,内部实现的变化不会影响外部调用,从而使系统更灵活,具有更好的可扩展性和可维护性.这也就是接口是系统”可插拔性的保证”这句话的意思.
5. 接口和抽象类的选择原则:
★ 优先使用接口
★ 在既要定义子类的行为有要提供子类公共的功能时选择抽象了.
三: 一个不用接口的应用
(1) 定义接口Api
public interface Api {
public void test(String string);
}
(2) 一个简单的实现类
public class ApiImpl implements Api {
//实现接口中定义的功能
public void test(Stringstring){
System.out.println(string);
}
}
(3) 客户端
public class Client{
public static voidmain(String[] args){
Apia api = newApiImpl();
api.test(“不用简单工厂测试实例”);
}
}
问题:在客户端调用的时候,客户端不但知道了接口,还知道了具体的实现类ApiImpl.接口的思想是封装隔离,而实现类Impl应该是被接口Api封装并同客户端分离开的,也就是说客户端根本就不应该知道具体的实现类Impl.
在Java中知道接口而不知道具体实现该怎么办?就像现在的Client,它知道要使用Api接口,但不知道其具体的实现,从而得不到接口对象,就无法使用接口,怎么办?
解决方案: 简单工厂
简单工厂定义:提供一个创建对象实现的功能,而无需关心其具体的实现,被创建案例的类型可以使接口也可以是抽象类和具体的实现类.
结构图:
class: ApiImplA test(String string) : void |
class: ApiImplB test(String string) : void
|
class : Factory createApi(int i); |
interface: Api test(String string): void |
class: Client main(String[] args):void |
Api : 接口,用来封装隔离具体的客户端和具体的实现类
ApiImplA,ApiImplB: 具体的实现类,真正的实现相应的功能,工厂方法中根据相应的条件真正创建的类.
Factory: 工厂,一般根据相应的条件,创建客户端需要的对象.
Client: 客户端,调用接口和工厂实现相应的需求.
实例代码:
(1) 定义接口Api
public interface Api {
public void test(String string);
}
(2)简单的实现类
public class ApiImplA implements Api {
//实现接口中定义的功能
public void test(Stringstring){
System.out.println(“ApiImplA“ + string);
}
}
public class ApiImplB implements Api {
//实现接口中定义的功能
public void test(Stringstring){
System.out.println(“ApiImplB”+ string);
}
}
(4) 简单工厂
public class Factory{
public Static Api createApi(int type){
//根据条件创建具体的实现类,一般实现为静态方法
Api api = null;
if(type == 1){
api=new ApiImplA();
} else {
api = new ApiImplB();
}
return api;
}
}
(5) 客户端
public class Client{
public static voidmain(String[] args){
Apia api = Factory.createApi(2);
api.test(“正在使用简单工厂测试实例”);
}
}
疑问解答: 把new Impl()放在客户端和放在工程中的区别?
答: 接口是用来封装隔离具体的实现的,目的就是不要让客户端知道真正封装体内部真正的具体实现.简单工厂的位置是位于封装体内部的.也就是说简单工厂和接口和具体实现是在同一个封装体内部的,所以简单工厂知道具体的实现类是没有关系的.
认识简单工厂
1: 简单工厂既可以创建具体的实现类,也可以创建接口和抽象类.
2: 静态工厂: 使用简单工厂的时候一般不需要创建工厂的实例,因此可以把简单工厂实现为一个静态工厂.如果要防止客户端创建简单工厂实例,可以将简单工厂的构造函数私有化.