Android开发设计模式之——工厂模式

在android中用到了很多的工厂类,如ThreadFactory创建抽象Runnable 。下面通过简单的例子来学习工厂模式。

一、作用

工厂模式(Factory Method):定义一个用于创建对象的接口,让子类决定将哪一个类实例化。从而使一个类的实例化延迟到其子类。

抽象工厂模式(Abstract Factory):提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

二、使用场景

1. 对同一个接口的实现类进行管理和实例化创建

三、常用的使用方式

讲例子之前,先假设要做这样的一个设计。设计一个Usb功能的接口,具有store(存储)和takeAlong(携带方便)两个行为。然后要设计两个产品,一个是 Phone(手机),另一个是Camera(照相机),很显然,它们都可以是 Usb的实现类。为了便于统一管理和创建,我们很容易就能设计出一个简单的工厂模式。

(1)普通的工厂方法

首先,我们可以画出相关的设计图:

《Android开发设计模式之——工厂模式》

代码实现如下:

定义Usb接口

public interface Usb {

    void store();

    void takeAlong();
}

Phone类

public class Phone implements Usb {

    @Override
    public void store() {

        System.out.println("this is Phone usb!");
    }

    @Override
    public void takeAlong() {
        // TODO Auto-generated method stub

    }

    public void call() {
        //TODO
    }

    public void sms() {
        //TODO
    }

}

Camera类

public class Camera implements Usb {

    @Override
    public void store() {
        System.out.println("this is Camera usb!");
    }

    @Override
    public void takeAlong() {
        // TODO Auto-generated method stub

    }

    public void takePhotos() {
        //TODO
    }

}

创建一个简单的工厂类UsbFactory1,负责生产

/**
 * 普通工厂方法
 * 参数传递的字符串会出错
 * :正确创建对象
 * 
 * @author xuzhaohu
 * 
 */
public class UsbFactory1 {

    public Usb produce(String type) {
        if ("phone".equals(type)) {
            return new Phone();
        } else if ("camera".equals(type)) {
            return new Camera();
        } else {
            System.out.println("请输入正确的类型!");
            return null;
        }
    }
}

子类实例化通过工厂类去创建,如要创建camera,

        /*普通工厂方法**/
        UsbFactory1 factory1 = new UsbFactory1();
        Usb usb1 = factory1.produce("camera");//+phone
        usb1.store();

输出:this is Camera usb!

总结:实现了工厂模式的基本功能,但是需要传参去控制,会出现很多不确定的问题,可以在工厂类中定义不同产品的生产,就是如下介绍的工厂多方法生产。

(2)工厂多方法

只要在UsbFactory中再定制一下就行,业务更加分明

《Android开发设计模式之——工厂模式》

根据设计修改工厂类

**
 * 多个工厂类方法
 * 
 * @author xuzhaohu
 * 
 */
public class UsbFactory2 {

    public Usb producePhone() {
        return new Phone();
    }

    public Usb produceCamera() {
        return new Camera();
    }

}

同样,要实例化某个子类对象,则可以这样去调用:

/*多个工厂方法模式**/
        UsbFactory2 factory2 = new UsbFactory2();
        Usb usb2 = factory2.producePhone();//+camera
        usb2.store();

输出:this is Phone usb!

这样是不是让业务逻辑更加清晰了一些呢!

但是如果在多处都要调用生产的话,不能每次都通过实例化工厂类然后去生产吧,这时候可以怎么样呢?

对,可以通过类访问,在工厂类中加上static方法。

/**
 * 静态工厂方法
 * :不需要实例
 * 
 * @author xuzhaohu
 * 
 */
public class UsbFactory3 {

    public static Phone producePhone() {
        return new Phone();
    }

    public static Camera produceCamera() {
        return new Camera();
    }
}

那么这时候可以直接不用实例化工厂类去访问了

        /*静态工厂方法模式**/
        Usb usb3 = UsbFactory3.producePhone();//+camera
        usb3.store();

输出:this is Phone usb!

这样就更加方便了一些。一般情况下,这样就基本能满足需求了,但是如果现在需求又要增加生产另外一个实现类产品Phone1,这时候肯定需要修改工厂类,在工厂类中增加一个新类型的生产Phone1方法。从设计的角度上讲,可能违背了 闭包(对扩展要开放对修改要关闭) 的设计原则,为了不违背这个原则,可以抽象工厂方法去设计,下面将讲到。

(3)抽象的工厂方法

为了不修改工厂中方法,我们可以对每个产品都创建相应工厂类去实现生产。这时候可以通过一个接口 Provider 去定义生产(produce)这个行为,然后让每个产品的工厂类都实现这个接口。这样如果有新的产品要生产的话只需要先实现一个工厂类就行。如下设计《Android开发设计模式之——工厂模式》

生产接口Provider

/**
 * 将工厂生产的行为写成接口独立
 * 
 * @author xuzhaohu
 * 
 */
public interface Provider {

    Usb produce();
}

每个产品都有自己的工厂

PhoneFactory工厂

public class PhoneFactory implements Provider {

    @Override
    public Usb produce() {
        // TODO Auto-generated method stub
        return new Phone();
    }

}

CameraFactory工厂

public class CameraFactory implements Provider {

    @Override
    public Usb produce() {
        // TODO Auto-generated method stub
        return new Camera();
    }

}

每一个产品可以根据自己的业务来去工厂生产产品,如要生产Camera

       /*抽象工厂方法模式**/
        /*1.扩展性好,不用修改源代码
         *2.添加一个实现USB接口的类+一个对应的实现Provider的工厂类**/
        Provider provider = new CameraFactory();
        Usb usb4 = provider.produce();
        usb4.store();

输出:this is Camera usb!

总结:抽象工厂模式从软件设计模式的原则上讲还是值得去推荐的。

参考:http://zz563143188.iteye.com/blog/1847029

    原文作者:beyond0525
    原文地址: https://blog.csdn.net/Beyond0525/article/details/22806393
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞