设计模式——工厂模式

常说的工厂模式一般认为有三种:简单工厂、工厂方法模式、抽象工厂模式。其中简单工厂严格上来说不是一种设计模式,而被认为是一种好的编码习惯/风格。

简单工厂

简单工厂的本质就是封装变化的代码,使客户代码将要面临的改变变少。而且被封装的代码也有了更好的复用性,比如服务多个客户端或者被继承/包装等工具来扩展。

下面以肾5和肾6为对象来说明

//define product(iphone) interface
public interface IPhone{
    public void model();
}

//iphone5
public class Phone5 implements IPhone{
    public void model(){
        System.out.printf("it is ipone5");
    }
}

//iphone6
public class Phone6 implements IPhone{
    public void model(){
        System.out.printf("it is ipone6");
    }
}

//Client: An apple store
public class AppleStore{
    public IPhone sellPhone(String model){
        if(model.equals("5")){
            return new Phone5();
        } else if(model.equals("6")){
            return new Phone6();
        }
    }
}

//change it with SimpleFactory
//Client: An apple store
public class AppleStore{
    private PhoneFactory factory;
    public IPhone sellPhone(String model){
        return factory.createPhone(model);
    }
}

public class PhoneFactory{
    public IPhone createPhone(String model){
        if(model.equals("5")){
            return new Phone5();
        } else if(model.equals("6")){
            return new Phone6();
        }
    }
}

从上面使用简单工厂的前后我们可以看出,简单工厂仅仅就是把if else那部分易变的代码,因为会不断的有新产品退出或者有旧的产品不再出售,进行了封装。但是这样的改变带来的优点也是很明显的。比如前面提到的服务多个客户端,假如还有一个仓库管理系统也可以利用这个PhoneFactory来创建iphone,而不用重新写一份if else的代码;再比如,假设在美国卖的是64GB版本,在中国卖的都是128GB版本,那么可以保持客户端的代码不变,只要修改一下我们提供的接口类PhoneFactory即可达到相同信号但是不同产品的目的。也可以给AppleStore添加setFactory方法来设置不同版本的Factory以达到动态设定的效果。

从"对修改关闭"的原则上来看,简单工厂也能使代码更贴近这种原则。采用简单工厂之后,需要修改的只是自己控制的工厂代码,而对于客户代码则不需要修改,遵循了“对修改关闭”原则。

也有把createPhone写成静态方法的,这样的做法就可以不用创建工厂实例,但缺点就是不能通过继承来改变工厂。

工厂模式

      工厂方法模式:定义一个创建对象的接口,但由子类决定要实例化的类是哪一个,把类的实例化推迟到工厂子类中。

下面我们看一个具体的实例,使用工厂方法模式来重写上面的卖手机模型。

 1 //change it with FactoryMode
 2 //Client: An apple store
 3 public class AppleStore{
 4     private PhoneFactory factory;
 5
 6     public AppleStore(PhoneFactory factoy){
 7         this.factory = factory;
 8     }
 9
10     public IPhone sellPhone(String model){
11         return factory.createPhone(model);
12     }
13 }
14
15 //factory interface
16 public abstract class PhoneFactory{
17     public final IPhone createPhone(String model){
18         return wrap(assemble(model));
19     }
20
21     public final void wrap(IPhone phone){
22         System.out.printf("wrap this phone");
23         return phone;
24     }
25
26     abstract IPhone assemble(String model);
27 }
28
29 // fatory of USA
30 public class PhoneFactoryA extends PhoneFactory{
31     public IPhone assemble(String model){
32         if(model.equals("5")){
33             return new Phone5ForA();
34         } else if(model.equals("6")){
35             return new Phone6ForA();
36         }
37     }
38 }
39
40 //factory of CHN
41 public class PhoneFactoryC extends PhoneFactory{
42     public IPhone assemble(String model){
43         if(model.equals("5")){
44             return new Phone5ForC();
45         } else if(model.equals("6")){
46             return new Phone6ForC();
47         }
48     }
49 }
50
51
52 //applestore in usa
53 AppleStore usaStore = new AppleStore(new PhoneFactoryA());
54 //applestore in CHN
55 AppleStore chnStore = new AppleStore(new PhoneFactoryC());

上面的工厂方法模型中,我们首先创建了一个工厂接口,然后分别实现了其子类USA工厂和CHN工厂,以分别制造适应不同国家的版本。Phone5ForA等对应的是不同国家的不同版本的类,代码中没有写出来。如果又要开一个HK店,那么只要实现一个HKPhoneFactoy子类即可。

上面比较重要的一点是:写了两个final方法:创建手机和包装手机,然后从代码可以看出来,手机组装好后,必须经过wrap(包装)才可以从store中售出。我们知道final方法不可以被重写,也就是说,上面的流程:“组装-包装-出售”是不可以在子类中被更改的,这样的话,就可以防止不良工厂卖出没有包装盒的手机,即就对子类的一些行为进行了控制,这也是工厂方法模式中很重要的一点。

工厂方法最重要的特点的就是创建工厂接口,使得能够针对接口编程,而不是针对实现编程,简单工厂就是针对实现编程。使用针对接口编程可以带来更大的弹性。工厂方法接口的子类与简单工厂中的工厂十分相似,从功能上看也是一致的,都实现了封装变化部分的效果。但是从大局上看,简单工厂仅仅就是实现封装变化部分的效果,而工厂方法模式则是搭建了一个很有弹性的框架。

抽象工厂模式

抽象工厂定义:提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。

继续上面的例子。我们知道手机是由多个零件组装起来的,比如CPU,屏幕等,对于上面的Phone5和Phone6,组装他们的时候都需要CPU和屏幕,但是各自的具体零件型号又不相同,这时,就该我们的抽象工厂方法上场了。

//define product(iphone) interface
public interface IPhone{
    protected IComponentFactory componentFactory;
    public void model();
}

//iphone5
public class Phone5 implements IPhone{

    public Phone5(){
        componentFactory = new ComponentFactory5();
    }

    public void model(){
        System.out.printf("it is ipone5");
    }
}

//iphone6
public class Phone6 implements IPhone{

    public Phone6(){
        componentFactory = new ComponentFactory6();
    }

    public void model(){
        System.out.printf("it is ipone6");
    }
}

//ComponentFactory interface
public interface IComponentFactory{
    protected CPU cpu;
    protected Screen screen;
}

//ComponentFactory5
public class ComponentFactory5 implements IComponentFactory{
    public ComponentFactory5(){
        cpu = CPUFactory.createCPU(5);
        screen = ScreenFactory.createScreen(5);
}

//ComponentFactory6
public class ComponentFactory6 implements IComponentFactory{
    public ComponentFactory6(){
        cpu = CPUFactory.createCPU(6);
        screen = ScreenFactory.createScreen(6);
}

//cpu
public interface CPU{
}

public class CPU5 implements CPU{
}

public class CPU6 implements CPU{
}

public class CPUFactory{
    public static CPU createCPU(int model){
        if(model == 5){
              return new CPU5();
        } else if (model == 6){
              return new CPU6();
        }
}

//screen
public interface Screen{
}

public class Screen5 implements Screen{
}

public class Screen6 implements Screen{
}

public class ScreenFactory{
    public static Screen createScreen(int model){
        if(model == 5){
              return new Screen5();
        } else if (model == 6){
              return new Screen6();
        }
}

在上面的代码中,组装Phone5和Phone6都需要CPU和Screen零件,于是他们都有一个零件工厂IComponentFactory(抽象工厂接口),各自的零件工厂都指定了自己需要什么样子的零件。而零件工厂创建零件的时候,则都是分别调用的具体零件工厂CPUFactory和ScreenFactory来创建具体的零件,也即本抽象工厂的实现中也应用到了前面提到的工厂方法模型。从这里也可以发现:抽象工厂他们不真正的制造具体的对象,他们仅仅指定我们需要什么要的对象,就好比抽象工厂方法就是一张装配清单(比如大部分手机厂干的就是这个活),而工厂方法则是负责制造这个装配清单上的具体零件(比如高通、联发科等就是干的制造CPU的活),这也许是抽象工厂之所以被叫做抽象的原因。更进一步的我们可以发现,抽象工厂其实可以理解为组装工厂,它的模型就是通过组合不同的Component来实现的;而工厂方法模式则是通过继承,把具体实现交给子类来实现的。

在上面的抽象工厂代码中,Phone类不需要关心CPU和Screen具体是怎么创建的(这些具体的创建都是CPUFactory和ScreenFactory),而只知道我需要哪种CPU和Screen,这样就把Phone从具体的CPU和Screen类解耦了。

时间: 2024-11-14 04:39:25

设计模式——工厂模式的相关文章

6.大话设计模式-工厂模式

工厂模式和简单工厂有什么区别.废话不多说,对比第一篇例子应该很清楚能看出来. 优点: 工厂模式弥补了简单工厂模式中违背开放-封闭原则,又保持了封装对象创建过程的优点. using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks; namespace DesignModel{    public interface Factory   

设计模式---工厂模式---生产水果

设计模式---工厂模式 需要一个基本的抽象类:相当一个基本的工厂 需要若干个具体类:相当若干个产品 需要工具类:相当工厂中机器,用来选择不同的产品生产 需要主类:相当顾客所想的订单 主类 ----> 工厂类 ----> 产品类 ---> 产品具体类 老板根据顾客的订单,在工具堆中选择合适的,然后去工厂中生产适合的产品,返回给顾客 优势:能够在不修改原先的代码情况,增加所需的类与方法. 不足:会增多类文件的数量 接口:提供的内容,相当于协议,即外界使用此接口时,接口的内容是不允许外界对接口

设计模式——工厂模式学习

1.概念 工厂模式定义:实例化对象,用工厂方法代替new操作.达到解耦的目的(避免硬编码耦合).工厂方法模式是类的创建模式,又叫做虚拟构造子(Virtual Constructor)模式或者多态性工厂(Polymorphic Factory)模式. 工厂模式是我们最常用的模式了,著名的Jive论坛 ,就大量使用了工厂模式,工厂模式在Java程序系统可以说是随处可见.因为工厂模式就相当于创建实例对象的new,我们经常要根据类Class生成实例对象,如A a=new A() 工厂模式也是用来创建实例

二十三种设计模式——工厂模式

二十三种设计模式--工厂模式 简单工厂模式 简单工厂模式又称静态工厂方法(StaticFactory Method)模式,不属于23种模式之一. 简单工厂模式是工厂模式最简单使用的模式. 类图: 程序: #include <iostream> #include<string> using namespace std; class NationalFlag//父类 { public: NationalFlag(){} ~NationalFlag(){} virtual void di

设计模式-工厂模式[Factory]

先看下一个简单的实现: 1 package org.masque.designpatterns.factorymethod.one; 2 /** 3 * 4 * Description: Sample子类的标示 5 * BeanEm.java Create on 2014年7月11日 下午2:37:58 6 * @author [email protected] 7 * @version 1.0 8 * Copyright (c) 2014 Company,Inc. All Rights Res

5分钟读书笔记之 - 设计模式 - 工厂模式

一个类或者对象中,往往会包含别的对象.在创建这种对象的时候,你可能习惯于使用常规方式,即用 new 关键字和类构造函数. 这会导致相关的俩个类之间产生依赖. 工厂模式,就是消除这俩个类之间的依赖性的一种模式,它使用一种方法来决定究竟实例化那个具体的类. 简单工厂模式 假设你想开几个自行车商店,每个商店都有几种型号的自行车出售,可以用这样一个类来表示: var BicycleShop = function(){} BicycleShop.prototype = { sellBicycle:func

java设计模式--工厂模式

总结 (1)简单工厂模式是由一个具体的类去创建其他类的实例,父类是相同的,父类是具体的. (2)工厂方法模式是有一个抽象的父类定义公共接口,子类负责生成具体的对象,这样做的目的是将类的实例化操作延迟到子类中完成. (3)抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,而无须指定他们具体的类.它针对的是有多个产品的等级结构.而工厂方法模式针对的是一个产品的等级结构. 一.工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的. 工厂模式在<Java

设计模式-工厂模式

一.工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的. 工厂模式在<Java与模式>中分为三类:1)简单工厂模式(Simple Factory):不利于产生系列产品: 2)工厂方法模式(Factory Method):又称为多形性工厂: 3)抽象工厂模式(Abstract Factory):又称为工具箱,产生产品族,但不利于产生新的产品:             这三种模式从上到下逐步抽象,并且更具一般性.             GOF在<

JavaScript设计模式——工厂模式

工厂模式:是一种实现“工厂”概念的面上对象设计模式.实质是定义一个创建对象的接口,但是让实现这个接口的类来决定实例化哪个类.工厂方法让类的实例化推迟到子类中进行.创建一个对象常常需要复杂的过程,所以不适合在一个复杂的对象中.创建对象可能会导致大量的重复代码,也可能提供不了足够级别的抽象.工厂方法模式通过定义一个单独的创建对象的方法来解决这些问题,由子类实现这个方法来创建具体类型的对象. 1.简单工厂: //定义接口 var Bicycle = new Interface('Bicycle', [