工厂模式
1、定义
工厂模式很简单,就是用来创建对象实例的,所有的对象实例,都交给工厂类生成。
2、类型
简单工厂、工厂方法、抽象工厂
以下是笔者对这三种工厂模式的一些个人理解,希望对读者有帮助!
简单工厂
简单工厂模式的工厂类一般是使用静态方法,通过接收的参数的不同来返回不同的对象实例。
优点:实现客户与具体实现类的松耦合,对于客户来说,他只需要传入对象的类型参数,就可以通过工厂获得所需要的对象实例
缺点:1、与具体实现类松耦合,却又和工厂绑在了一起2、当有新的对象加入时,得修改工厂类的代码
简单工厂模型代码实现:
/** * 简单工厂模式 * @Author 先 * @ClassName Client_SimpleFactory.java * @Time 2017年3月12日 下午1:15:17 */ public class Client_SimpleFactory { public static void main(String[] args) { //在不实用简单工厂模式前 /* //买小米 Mobie xiaomi = new Xiaomi(); xiaomi.getMobie(); //买iphone Mobie iphone = new IPhone(); iphone.getMobie(); //买华为 Mobie huawei = new Huawei(); huawei.getMobie();*/ //使用了简单工厂之后,买什么手机直接告诉工厂, //不需要客户去到每一个专卖店买(这里只是为了说明工厂模式作的比喻) SimpleFactory sf = new SimpleFactory(); //买小米 sf.getMobie("xiaomi").getMobie(); //买iphone sf.getMobie("iphone").getMobie(); //买华为 sf.getMobie("huawei").getMobie(); } } /** * 抽象手机类 * @Author 先 * @ClassName Client_SimpleFactory.java * @Time 2017年3月12日 下午1:24:45 */ interface Mobie{ abstract void getMobie(); } /** * 具体手机--小米 * @Author 先 * @ClassName Client_SimpleFactory.java * @Time 2017年3月12日 下午1:25:52 */ class Xiaomi implements Mobie{ @Override public void getMobie() { System.out.println("我是小米手机……"); } } /** * 具体手机--iphone * @Author 先 * @ClassName Client_SimpleFactory.java * @Time 2017年3月12日 下午1:26:32 */ class IPhone implements Mobie{ @Override public void getMobie() { System.out.println("我是苹果手机……"); } } /** * 具体手机--华为手机 * @Author 先 * @ClassName Client_SimpleFactory.java * @Time 2017年3月12日 下午1:27:44 */ class Huawei implements Mobie{ @Override public void getMobie() { System.out.println("我是华为手机……"); } } /** * 简单工厂 * @Author 先 * @ClassName Client_SimpleFactory.java * @Time 2017年3月12日 下午1:32:27 */ class SimpleFactory{ /** * 工厂根据类型生产手机 * @param type * @return Mobie */ public static Mobie getMobie(String type){ Mobie mobie = null; switch(type){ case "xiaomi" : mobie = new Xiaomi();break; case "iphone" : mobie = new IPhone();break; case "huawei" : mobie = new Huawei();break; } return mobie; } }
工厂方法
工厂方法是针对每一种产品提供一个工厂类。通过不同的工厂实例来创建不同的产品实例。在同一等级结构中,支持增加任意产品。
工厂方法模型
代码实现:
分析:/** * 工厂方法设计模式 * @Author 先 * @ClassName Client_FactoryMethod.java * @Time 2017年3月12日 下午1:46:22 */ public class Client_FactoryMethod { public static void main(String[] args) { //使用工厂方法模式 //买小米,找小米手机工厂 Factory f_xiaomi = new Factory_xiaomi(); f_xiaomi.produce_Mobie().getMobie(); //买iphone,找iphone手机工厂 Factory f_iphone = new Factory_iphone(); f_iphone.produce_Mobie().getMobie(); //买华为,找华为工厂 Factory f_huawei = new Factory_huawei(); f_huawei.produce_Mobie().getMobie(); } } /** * 抽象手机类 * @Author 先 * @ClassName Client_SimpleFactory.java * @Time 2017年3月12日 下午1:24:45 */ interface Mobie{ abstract void getMobie(); } /** * 具体手机--小米 * @Author 先 * @ClassName Client_SimpleFactory.java * @Time 2017年3月12日 下午1:25:52 */ class Xiaomi implements Mobie{ @Override public void getMobie() { System.out.println("我是小米手机……"); } } /** * 具体手机--iphone * @Author 先 * @ClassName Client_SimpleFactory.java * @Time 2017年3月12日 下午1:26:32 */ class IPhone implements Mobie{ @Override public void getMobie() { System.out.println("我是苹果手机……"); } } /** * 具体手机--华为手机 * @Author 先 * @ClassName Client_SimpleFactory.java * @Time 2017年3月12日 下午1:27:44 */ class Huawei implements Mobie{ @Override public void getMobie() { System.out.println("我是华为手机……"); } } /** * 抽象工厂 * @Author 先 * @ClassName Client_FactoryMethod.java * @Time 2017年3月12日 下午1:48:32 */ interface Factory{ abstract Mobie produce_Mobie(); } /** * 小米工厂,小米系列的手机由它生产 * @Author 先 * @ClassName Client_FactoryMethod.java * @Time 2017年3月12日 下午1:51:40 */ class Factory_xiaomi implements Factory{ @Override public Mobie produce_Mobie() { Mobie mobie = new Xiaomi(); return mobie; } } /** * iphone工厂,苹果系列的手机由它生产 * @Author 先 * @ClassName Client_FactoryMethod.java * @Time 2017年3月12日 下午1:52:30 */ class Factory_iphone implements Factory{ @Override public Mobie produce_Mobie() { Mobie mobie = new IPhone(); return mobie; } } /** * 华为工厂,华为系列的手机由它生产 * @Author 先 * @ClassName Client_FactoryMethod.java * @Time 2017年3月12日 下午1:52:41 */ class Factory_huawei implements Factory{ @Override public Mobie produce_Mobie() { Mobie mobie = new Huawei(); return mobie; } }
使用开闭原则来分析下工厂方法模式。当有新的产品产生时,只要按照抽象产品角色、抽象工厂角色提供的合同(即接口)来生成,那么就可以被客户使用,而不必去修改任何已有的代码。(即当有新产品时,只要创建并继承抽象产品;新建具体工厂继承抽象工厂;而不用修改任何一个类)工厂方法模式是完全符合开闭原则的!
抽象工厂
在认识抽象工厂前,我们得先认识一下产品族。
所谓的产品族,就是位于不同产品等级结构中,功能相关联的产品组成的家族
先看抽象工厂的模型图
我们可以看到,抽象工厂中利用到了工厂方法的方式实现,但又有所不同,所以在此将抽象工厂与工厂方法加以区分。
抽象工厂与工厂方法的区别
1、抽象工厂模式是工厂方法模式的升级版本(因为用到了工厂方法的实现方式),他用来创建一组相关或者相互依赖的对象。工厂方法模式针对的是一个产品等级结构;而抽象工厂模式则是针对的多个产品等级结构。在编程中,通常一个产品结构,表现为一个接口或者抽象类,也就是说,工厂方法模式提供的所有产品都是衍生自同一个接口或抽象类,而抽象工厂模式所提供的产品则是衍生自不同的接口或抽象类。
2、抽象工厂模式所提供的一系列产品就组成一个产品族;而工厂方法提供的一系列产品称为一个等级结构。
我们先看一个例子,再做详细分析
/** * 抽象工厂模式 * @Author 先 * @ClassName Client_AbstractFactory.java * @Time 2017年3月12日 下午1:58:21 */ public class Client_AbstractFactory { public static void main(String[] args) { //现在,需要小米屏幕 //1、找屏幕工厂(创建屏幕工厂对象) AbstractFactory af = new ScreenFactory(); //2、屏幕工厂里生产出小米的屏幕 XiaomiComponent xiaomiScreen = af.Xiaomi(); //3、得到小米屏幕 xiaomiScreen.produceComponent(); //若需要其他产品,操作类似 } } /** * 抽象工厂,这里生产一些手机的零件 * @Author 先 * @ClassName Client_AbstractFactory.java * @Time 2017年3月12日 下午4:56:08 */ interface AbstractFactory{ //小米零件 abstract XiaomiComponent Xiaomi(); //华为零件 abstract HuaweiComponent Huawei(); } /** * 具体零件工厂--屏幕工厂 * @Author 先 * @ClassName Client_AbstractFactory.java * @Time 2017年3月12日 下午6:56:04 */ class ScreenFactory implements AbstractFactory{ //小米屏幕 @Override public XiaomiComponent Xiaomi() { XiaomiComponent xiaomiScreen = new XiaomiScreen(); return xiaomiScreen; } //华为屏幕 @Override public HuaweiComponent Huawei() { HuaweiComponent huaweiScreen = new HuaweiScreen(); return huaweiScreen; } } /** * 具体工厂--电池工厂 * @Author 先 * @ClassName Client_AbstractFactory.java * @Time 2017年3月12日 下午7:10:56 */ class BatteryFactory implements AbstractFactory{ //小米电池 @Override public XiaomiComponent Xiaomi() { XiaomiComponent xiaomiBattery = new XiaomiBattery(); return xiaomiBattery; } //华为电池 @Override public HuaweiComponent Huawei() { HuaweiComponent huaweiBattery = new HuaweiBattery(); return huaweiBattery; } } /** * 抽象产品--小米零件 * @Author 先 * @ClassName Client_AbstractFactory.java * @Time 2017年3月12日 下午7:03:02 */ interface XiaomiComponent{ //生产小米零件 abstract void produceComponent(); } /** * 抽象产品--华为零件 * @Author 先 * @ClassName Client_AbstractFactory.java * @Time 2017年3月12日 下午7:07:27 */ interface HuaweiComponent{ //生产华为零件 abstract void produceComponent(); } /** * 具体产品--小米屏幕 * @Author 先 * @ClassName Client_AbstractFactory.java * @Time 2017年3月12日 下午7:05:04 */ class XiaomiScreen implements XiaomiComponent{ @Override public void produceComponent() { System.out.println("小米屏幕生产完毕!"); } } /** * 具体产品--小米电池 * @Author 先 * @ClassName Client_AbstractFactory.java * @Time 2017年3月12日 下午7:06:22 */ class XiaomiBattery implements XiaomiComponent{ @Override public void produceComponent() { System.out.println("小米电池生产完毕!"); } } /** * 具体产品--华为屏幕 * @Author 先 * @ClassName Client_AbstractFactory.java * @Time 2017年3月12日 下午7:08:04 */ class HuaweiScreen implements HuaweiComponent{ @Override public void produceComponent() { System.out.println("华为屏幕生产完毕!"); } } /** * 具体产品--华为电池 * @Author 先 * @ClassName Client_AbstractFactory.java * @Time 2017年3月12日 下午7:09:01 */ class HuaweiBattery implements HuaweiComponent{ @Override public void produceComponent() { System.out.println("华为电池生产完毕!"); } }
在上例子中,小米零件和华为零件就分别为一个等级结构(小米结构,华为结构,我们勉强这么理解),而电池和屏幕就分别为一个产品族(电池产品、屏幕产品)。在这里,小米电池和小米屏幕就是同一个等级结构,而小米电池和华为电池就是同一个产品族。正如上述所说,如果一个工厂生产的产品来自同一个接口或抽象类,那么属于工厂方法;如果一个工厂生产的产品来自不同的接口,那么属于抽象工厂,很明显,上例子中,无论是电池工厂还是屏幕工厂,他们的产品都来自不同接口,并且在各自的接口中,它们属于同一类产品(即都为电池或者都为屏幕)。现在,应该明白什么叫抽象工厂了吧,也能区分工厂方法和抽象工厂了吧。
总结
1、工厂模式中,重要的是工厂类,而不是产品类;
2、使用工厂模式,返回的实例一定是工厂创建的,而不是从其他对象中获取的。这也正是工厂模式的宗旨(或者说存在的意义)--创建对象实例;
3、简单工厂--对于增加新的产品,无能为力;
4、工厂方法--支持增加任意产品(常用);
5、抽象工厂--对于增加新的产品,无能为力;支持增加产品族(这句话的意思是,用上例来说,如果增加一个新的产品(比如魅族电池),那么得改写原有代码,很麻烦;但如果加入的是一个产品族(如手机壳),抽象工厂是很容易做到的,即再创建一个手机壳工厂,这个工厂依然是实现抽象工厂,在这个工厂里,生产小米手机壳和华为手机壳,这样的做法是不需要改动原来代码的)。
注:转载请注明出处!