读书人

学习设计形式系列之简单工厂模式(

发布时间: 2012-10-08 19:54:56 作者: rapoo

学习设计模式系列之——简单工厂模式(Java)

一、简单工厂模式简介
??? 简单工厂模式属于类的创建型模式,又叫做静态工厂方法模式。通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。
举例说明:

第一步:有一苹果类和香蕉类,里面有同样的摘去方法get(),代码如下:

package com.wds.simplefactory;/**  * 香蕉类 * 2010-6-26 下午09:46:59 */public class Banana{/** * 采集 * 2010-6-26 下午09:47:16 */public void get(){System.out.println("采集香蕉");}}

?苹果类如下:

/**  * 草果类 * 2010-6-26 下午09:45:41 */public class Apple{/** * 采集苹果 * 2010-6-26 下午09:46:20 */public void get(){System.out.println("采集苹果");}}

?主类MainClass:

/**  * 主类 * 2010-6-26 下午09:45:29 */public class MainClass {/** * 2010-6-26 下午09:45:29 * @param args */public static void main(String[] args) {/* * 实例化一个Apple */Apple apple=new Apple();/* * 实例化一个Banana */Banana banana=new Banana();apple.get();banana.get();              }}

?

第二步:?以前是第一部,完成了一个初步的操作,但是由苹果和香蕉这两个类中都一个采摘的方法get(),,所以我们从这两个类中抽取一个Fruit接口,代码如下:

/**  * Fruit接口 * 2010-6-26 下午09:50:57 */public interface Fruit {/** * 摘取 */public void get();}

?

那么苹果类和香蕉类实现Fruit接口,代码如下:

/**  * 苹果类 * 2010-6-26 下午09:45:41 */public class Apple implements Fruit{/** * 采集苹果 * 2010-6-26 下午09:46:20 */public void get(){System.out.println("采集苹果");}}

?

/**  * 香蕉类 * 2010-6-26 下午09:46:59 */public class Banana implements Fruit{/** * 采集 * 2010-6-26 下午09:47:16 */public void get(){System.out.println("采集香蕉");}}

?

主类中关于Apple和Banana的实例有所变化,代码如下:

/**  * 主类 * 2010-6-26 下午09:45:29 */public class MainClass {/** * 2010-6-26 下午09:45:29 * @param args */public static void main(String[] args) {//采用接口实例化一个AppleFruit apple=new Apple();//采用接口实例化一个BananaFruit banana=new Banana();apple.get();banana.get();                }}

?

第三步:由于Apple和Banana有一个共同的接口,而简单工厂模式,是通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。所以我们创建一个水果工厂类FruitFactory来创建Apple和Banana这两个类。

FruitFactory代码如下:

/**  * 水果工厂类 * 2010-6-26 下午09:53:48 */public class FruitFactory {/** * 获得Apple类的一个实例 */public static Fruit getApple(){return new Apple();}/** * 获得一个Banana的一个实例 * 2010-6-26 下午09:54:47 * @return */public static Fruit getBanan(){return new Banana();}}

?那么主类就有相就的变化,代码如下

MainClass

/**  * 主类 * 2010-6-26 下午09:45:29 */public class MainClass {/** * 2010-6-26 下午09:45:29 * @param args */public static void main(String[] args) {                             Fruit apple=FruitFactory.getApple();Fruit banana=FruitFactory.getBanan();apple.get();banana.get();               }}

?
第四步,由于在工厂类中,都是一个get方法,只是返回内容不同,我们换另一种方法,只有get方法一个,根据参数不同决定返回的类不同,FruitFactory代码如下:

/**  * 水果工厂类 * 2010-6-26 下午09:53:48 */public class FruitFactory {/** * get方法,获得所有产品对象 * 异常我人为的忽略了,大家在写的时候加上去 */public static Fruit getFruit(String type){if(type.equalsIgnoreCase("apple")){return Apple.class.newInstance();}else if(type.equalsIgnoreCase("banana")){return Banana.class.newInstance();}else{System.out.println("can not find class");return null;}}

?第五步,由于水果工厂类中的判断语句比较多,我们换一个更为普通的创建方法,代码如下:

/**  * 水果工厂类 * 2010-6-26 下午09:53:48 */public class FruitFactory {/** * get方法,获得所有产品对象 * @throws ClassNotFoundException  * @throws IllegalAccessException  * @throws InstantiationException  */public static Fruit getFruit(String type) throws ClassNotFoundException, InstantiationException, IllegalAccessException{                                //此处,之所以加com.wds.simplefacotry,是因为Apple类和Banana类与FruitFactory类同个包下面,包的名字是com.wds.simplefactoryClass fruit=Class.forName("com.wds.simplefactory."+type);//System.out.println(FruitFactory.class.getResource(""));//Class fruit=Class.forName(FruitFactory.class.getClassLoader().getResource("")+type);return (Fruit) fruit.newInstance();}}

?至此,工厂类已经完成,那么主类代码也有所变化,变化如下:

/**  * 主类 * 2010-6-26 下午09:45:29 */public class MainClass {/** * 2010-6-26 下午09:45:29 * @param args */public static void main(String[] args) {try {               Fruit banana=FruitFactory.getFruit("Banana");                               Fruit apple = FruitFactory.getFruit("Apple");apple.get();banana.get();} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();}}

?

,我有两点建议:

1.
if(type.equalsIgnoreCase("apple")){  


建议写成"apple".equalsIgnoreCase(type),这样可以防止NPE(NullPointerException)。


2.
public void get();  


建议改成
public String get();  
,这样API的动词方法不会产生歧义。

我有一篇文章说到这个的,你有时间可以参考一下:
http://mercyblitz.iteye.com/blog/667939

读书人网 >软件开发

热点推荐