研磨设计模式之创建模式:简单工厂

来源:互联网 发布:linux sqlplus 乱码 编辑:程序博客网 时间:2024/06/06 12:57
  1. 定义
    提供一个创建对象实例的功能,无须关心具体实现。(被创建类型,接口,抽象类,具体类)。

  2. 结构和说明

这里写图片描述

  • api 定义客户所需要的功能接口。
  • apia,apib 具体实现api的实现类,可能有多个。
  • factory :工厂选择适合的类来创建api接口对象。
  • client 客户端,通过factory获取api接口对象,然后面向api接口编程

面向接口编程

接口的思想-“封装隔离”
封装:功能封装在接口内部。隔离:客户端和功能实现隔离开来。面向接口编程的好处:接口不变,内部实现变化不影响外部应用,使得系统更加灵活,易于扩展。


思考:factory 选择接口实现类?如何选?传递参数?如何传递参数?
方式一:参数源于客户端;方式二:参数源于配置文件;方式三:源于系统本身,系统运行时的某个值。

public interface Api{    void callApi();}public class ApiA implements Api{    @override    public void callApi(){        System.out.println("call apia...");    }}public class ApiB implements Api{    @override    public void callApi(){        System.out.println("call apib...");    }}

方式一:通过client端传递参数

/* * 方式一:通过客户端传递choose参数选择具体接口实现类 */public class SimpleApiFactory{    private SimpleApiFactory{};    //choose通过client传递参数表明使用那个api    public static Api createApi(int choose){        if (choose == 0) return new APIA();        else if(choose == 1)return new APIB();        else return null;    }       }public class Client{    public void static main(String []args){        //factory 传递参数表明使用哪个api?(存在隐藏问题)        Api api = SimpleApiFactory.createApi(0);        if (api == null) return;        api.callApi();    }   }

方式二:通过配置文件解析 添加test.properties配置文件,添加ImplClass = ApiB 来指定使用接口实现类。

public class Factory{private Factory{};public static Api createApi(){    Properties pro = new Properties();    InputStream in = null;    try{        in = Factory.class.getResourceAsStream("test.properties");        p.load(in);        Api api = null;        api = (Api)Class.forName(p.getProperty("ImplClass")).newInstance();        return api;    }catch(Exception ex){        ex.printStack();    }    finally{        in.close();    }   }}   

方式三:系统运行时的某个系统值

public class Factory{//系统保存值public static int count = 0;private Factory{};  public static Api createApi(){    Api api = null;    if (count<3) {        api = new ApiA();        count++;    }    else if (count>3){        api = new ApiB();        count++;    }    return null;    }   }
  • 简单工厂优缺点
    a.帮助模块封装
    b.解耦
    c.增加客户端的复杂度(需要客户端传递参数,暴露参数定义意义)
    d.不方便扩展子工厂

  • 简单工厂本质
    选择实现

  • 何时选用简单工厂
    a. 如果想要完全封装隔离具体实现,让外部只能通过接口来操作封装体,那么可以选择简单工厂,让客户端通过工厂来获取相应接口,,无须关心具体实现。
    b. 如果想把对外创建对象的职责集中管理和控制,可以选用简单工厂,一个简单工厂可以创建很多不相关的对象,可以把对外创建对象的职责集中到一个简单工厂来,从而实现集中管理和控制。