黑马程序员_JAVA设计模式之简单工厂

来源:互联网 发布:网络114推广 编辑:程序博客网 时间:2024/06/05 01:52

------- android培训、java培训、期待与您交流! ----------


        面向接口编程是JAVA编程中的一个非常重要原则! 在JAVA程序的设计中,通常将系统按三层来分,由上至下分别为表现层,逻辑层和数据层,他们之间互不污染,才能最大的松散耦合,其中关键的思想就是面向接口思想。

        既然JAVA中,面向接口编程是一个非常重要的原则,那么在实际项目中如何运用接口来做到真正的面向接口编程?我们在初学JAVA的时候还没有涉及到设计模式,那么这时候是如何使用接口的呢?我们通常是有一个接口叫Api,接着又有一个实现类Impl实现这个接口,然后我们直接在客户端创建一个Impl的实例,将其赋给一个Api接口类型的变量,最后,客户端就可以通过这个变量来操作接口的功能了,这个过程可以用以下代码过程来表示:

1、首先定义接口Api

public interface Api {public String doSomething();}

2、实现类Impl

public class Impl implements Api {public String doSomething() {return "没有使用工场设计模式!";}}


3、客户端

public class App {public static void main(String[] args) {Api api = new Impl();String s = api.doSomething();System.out.println(s);}}

当然,刚开始的时候我们就是这么干的,并没有觉得哪里不对,但是随着学习的深入,我们会发现客户端里面有这么一句代码:

Api api = new Api();

       我们会发现,在客户端App里面,客户不仅知道了接口,并且还知道了具体的实现类就是Impl,然而面向接口编程的思想告诉我们,Impl应该是被Api给封装起来,起到将实现类和客户端隔离开来的作用,Impl不应该被暴露给客户,客户不应该直接就调用Impl。这样就有个问题了,既然不让我客户端去直接得到Impl,那我从哪里得到?找谁要呢?总得有个人将Impl的实例交给我,我才能干活啊!

    解决这样一个只知接口不知实现的问题,我们使用到了简单工厂设计模式,简单工厂的定义如下:提供一个创建对象实例的功能,而无需关心其具体实现,被创建实例的类型可以是接口,抽象类,也可以是具体的类。

    在工厂内,工厂是知道具体的实现类的,而对于客户端,它不知道工厂内是如何实现的,也不需要知道,客户只需要向工厂提出他想要的东西,工厂就会按照客户端的需求向客户端提供相应的东西,这个工厂我们可以称之为Factory类,因此,客户端就可以通过Factory来获取需要的接口对象,然后调用接口的方法来实现需要的功能就可以了,而完全不需要关心具体的实现了!简单工厂的模式可以用以下代码过程来表示:

1、Api接口定义如下:

public interface Api {public String doSomething();}

2、实现类如下,分为两个实现类ImplA、ImplB:

public class ImplA implements Api {public String doSomething() {System.out.println("实现类ImplA");}}
public class ImplB implements Api {public String doSomething() {System.out.println("实现类ImplB");}}

3、下面就来实现简单工厂:

public class Factory {public static Api getApi(int type) {//简单工厂只是一个工具类,没有创建实例的必要,方法最好使用静态 Api api = null;if (type == 1) {api = new ImplA();} else if (type == 2) {api = new ImplB();}return api;}}

4、客户端使用简单工厂,有了工厂,客户端就不需要亲自创建接口对象了,示例如下:

public class App {public static void main() {Api api = Factory.getApi(1);api.doSomething();}}

        从上面可以看出来,客户端在不知道具体的实现类的情况下获取到了想要的接口Api。JAVA设计模式里面的工厂可以包含很多创建东西的方法,这些方法可以创建不同的接口、抽象类或者是类实例。从这里我们也可以看出,工厂的本质是选择实现,上面的示例中有两种实现,而实际开发中可能有多个厂家的实现,每个厂家又有多种实现,而不仅仅是两种,那到底选择哪一种实现呢?上面的示例中,客户端向工厂提出需求的时候传入了一个整形的参数,代表了客户要选择的实现类型,这样又出现了新的问题,客户每次调用工厂的时候都要传入一个选择的参数,这就要求客户知道每个参数的意义,某种程度上已经向客户暴露了内部的一些实现细节。那么有没有优化的方法?有,那就是采用配置化的简单工厂。最常用的方式就是使用配置文档,每当实现类有什么增删改的时候都不会影响到工厂,只要在配置文档中做适当的修改即可满足不断变化的需求!此时的工厂可以优化成如下示例:

public class Factory {//在实际应用中通常将Factory类私有化public static void getApi() {Properties prop = new Properties();InputStream in = null;in = Factory.class.getResourceAsStream("api.properties");prop.load(in);Api api = null;// 这里使用反射得到配置文件中国制定的实现类,反射通常使用在框架中,其实设计模式与框架也是息息相关的api = (Api) Class.forName(prop.getProperty("ApiImplClass")).newInstance();return api;}}

优化之后的工厂使得客户端使用起来就更加便利了:

public class App {public static void main(String[] args) {Api api = Factory.getApi();api.doSomething();}}

    到此,简单工厂的思想架构已经体现了出来,在实际应用中的很多情况下都会应用到简单工厂的模式,也会进行适当的变形,但是不管如何变形,其本质是不会改变的:选择实现,其目的就是为客户端选择相应的实现,从而使客户端和实现之间进行解耦,当实现有所变动,客户端根本就不需要做任何的改变,就可以实现相同的功能,或者达到功能的改变。 总的来说,使用简单工厂带来的好处就是,客户端根本就不需要知道具体是由谁来实现功能,也不用关心是怎样实现的,面对工厂,客户端需要做的只是向工厂获取它需要的接口对象就行了!






 

 


 


------- android培训、java培训、期待与您交流! ----------
原创粉丝点击