码迷,mamicode.com
首页 > 其他好文 > 详细

设计模式之工厂模式

时间:2015-06-01 18:52:10      阅读:106      评论:0      收藏:0      [点我收藏+]

标签:设计模式   接口   工厂模式   

1、概念

Define an interface for creating an object,but let subclasses decide which class to instantiate.Factory Method lets a class defer instantiation to subclasses.(定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。)
工厂模式是经常用到的设计模式之一。其作用是,延迟子类初始化,客户端只需从工厂中获取产品,而不用了解产品生产的细节,降低了模块之间的耦合。也是面向接口编程体现。

2、通用类图

技术分享

图片摘自HeadFirst

从类图上看,有产品接口,制造者也就是工厂接口。具体产品实现产品接口,具体工厂实现工厂接口。然后工厂的实现类,关联具体的产品。为了更好地理解这个模式,敲了一个小例子,加以辅助,希望可以取得一些助攻。【深入了解这个模式可以参考 《设计模式之禅》 和《HeadFirst》 这两本书都是良心之作 文档下载见参考资料】

3、例子

例子背景:有个平板工厂,工厂可以生产苹果平板,安卓平板。平板可以连接wifi关闭wifi等功能。

例子类图如下:
技术分享

PAD接口代码:

package phlin.samples.factory.pad;

public interface PAD {

    /**
     * 联网功能
     */
    public void linkToNet();
    /**
     * 打开wifi功能
     */
    public void openWifi();
    /**
     * 关闭wifi功能
     */
    public void closeWifi(); 
/**
 * other functions
 */
}

工厂接口代码:

package phlin.samples.factory.pad;

/**
 * 平板 工厂 接口
 * @author lin
 *
 */
public interface PADFactoryI {

    public PAD createPad(String padType); 
}

安卓平板代码:【实现平板接口】

package phlin.samples.factory.pad;

public class AndroidPad implements PAD {

    @Override
    public void linkToNet() {
        // TODO Auto-generated method stub
        UtilClass.Dis("I use a android pad to get msg from Intener");
    }

    @Override
    public void openWifi() {
        // TODO Auto-generated method stub
        UtilClass.Dis("open android pad wifi");
    }

    @Override
    public void closeWifi() {
        // TODO Auto-generated method stub
        UtilClass.Dis("close android pad wifi");
    }

}

苹果平板代码:【实现平板接口】

package phlin.samples.factory.pad;

public class IOSPad implements PAD{


    @Override
    public void linkToNet() {
        // TODO Auto-generated method stub
        UtilClass.Dis("I use a IOS pad to get msg from Intener");
    }

    @Override
    public void openWifi() {
        // TODO Auto-generated method stub
        UtilClass.Dis("open IOS pad wifi");
    }

    @Override
    public void closeWifi() {
        // TODO Auto-generated method stub
        UtilClass.Dis("close IOS pad wifi");
    }


}

工厂实现代码:【实现工厂接口】

package phlin.samples.factory.pad;

public class PadFactory  implements PADFactoryI{

    PAD pad=null;
    @Override
    public PAD createPad(String padType) {
        // TODO Auto-generated method stub

        if(padType.equals("android"))
        {
            pad=new AndroidPad();
        }else if(padType.equals("iso"))
        {
            pad=new IOSPad();
        }else
        {
            UtilClass.Dis("no instance");
        }

        return pad;
    }      

}

辅助显示类:

package phlin.samples.factory.pad;

public final class UtilClass {

    /**
     * 终端显示
     * @param str
     */
    public static void Dis(String str)
    {
        System.out.println(str);
    }
}

测试类代码:

package phlin.samples.factory.pad;


public class TestClass {
    public static void main(String[] args) {
        PAD andPad=null,iosPad=null;
        //pad工厂实例化
        PadFactory factory=new PadFactory();

        //生产安卓平板
        andPad=factory.createPad("android");
        andPad.linkToNet();
        //生产苹果平板
        iosPad=factory.createPad("iso");
        iosPad.linkToNet();

    }
}

测试结果:

I use a android pad to get msg from Intener
I use a IOS pad to get msg from Intener

可以发现。测试类代码中只需实例化工厂,然后通过createPad方法 就可以实例化相对应的平板,而且,关键是,测试类中,无需关系平板是如何生产的,极大降低了模块直接耦合,有利于拓展。

但是这种通过 String padType 的方式来判断那类产品要生产,似乎比较麻烦,如果款式比较多,还得一个个加。这里有一种比较好的优化方案,用泛型来实现,直接通过类名来实例化子类。

下面对工厂接口和工厂实现类做一些改动:
注意不同之处:
工厂接口:

package phlin.samples.factory.pad;

/**
 * 平板 工厂 接口
 * @author lin
 *
 */
public interface PADFactoryI {

    public <T extends PAD>  T ceratePad(Class <T> c);
}

工厂实现类:

package phlin.samples.factory.pad;

public class PadFactory  implements PADFactoryI{

    PAD pad=null;  
    @Override
    public <T extends PAD> T ceratePad(Class<T> c) {
        // TODO Auto-generated method stub
        PAD pad=null;
    try {
        pad=(PAD)Class.forName(c.getName()).newInstance();
    } catch (Exception e) {
        // TODO: handle exception
    }
        return (T)pad;
    }

}

测试类代码:

package phlin.samples.factory.pad;


public class TestClass {
    public static void main(String[] args) {
        PAD andPad=null,iosPad=null;
        PadFactory factory=new PadFactory();

        andPad=factory.ceratePad(AndroidPad.class);
        andPad.linkToNet();

        iosPad=factory.ceratePad(IOSPad.class);
        iosPad.linkToNet();
    }
}

测试结果:

I use a android pad to get msg from Intener
I use a IOS pad to get msg from Intener

测试结果一样,但是对于工厂实现类,要添加新类型产品是,该类几乎不用改动。对于产品,只需拓展产品也就是平板类型即可。

4、参考资料

设计模式之禅
HeadFirst
资料链接:http://pan.baidu.com/s/1i3rfm9B 密码:6q98

转载注明出处:http://blog.csdn.net/androidolblog/article/details/46275725

有所不足,多多指正,谢谢!

设计模式之工厂模式

标签:设计模式   接口   工厂模式   

原文地址:http://blog.csdn.net/androidolblog/article/details/46275725

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!