`

简单工厂方法

阅读更多

 

简单工厂模式又叫做静态工厂方法模式,根据提供给它的数据,返回几个可能类中的一个类的实例。通常它返回的类都有一个共同的父类和共同的方法,但每个方法 执行的行为不同。简单工厂模式实际上不属于 23 GOF 模式,但它可以作为工厂方法模式的一个引导。

 

工厂模式如何工作:

工厂类( Creator )角色:该角色是工厂方法模式的核心,含有按照一定商业逻辑创建产品。工厂类在客户端的直接调用下创建产品对象,它往往由一个具体类实现。

抽象产品( Product )角色:担任这个角色的类是工厂方法模式所创建的对象的父类,或它们共同拥有的接口。抽象产品角色可以用一个接口或者抽象类实现。

具体产品( Concrete Product )角色:工厂方法模式所创建的任何对象都是这个角色的实例,具体产品角色由一个具体类实现。

 

 


 

 

下面我们来看看工厂模式的的优点和缺点:

优点:

1 、分工明确,各司其职。
2
、客户端不再创建对象,而是把创建对象的职责交给了具体的工厂去创建。
3
、客户端只负责调用。

缺点:

1 、工厂的静态方法无法被继承。

2 、代码维护不易 ( 对象要是很多的话,工厂是一个很庞大的类 )

3 、这种模式对 - 原则支持的不够,如果有新的产品加入到系统中就要修改工厂类。

使用时机:

客户端需要创建对象,但是数量不多的情况下,可以考虑使用简单工厂模式。

 

如何使用:

1. 使用字符串唯一标识符或者 id 号。

public class SimpleFactory {
    public static Product factoryProduct(String productName) {
        if(productName.equals("product1")) {
            return new Product1();
        }else if(productName.equals("product2")) {
            return new Product2();
        }
        return null;
    }
}

 

 

2. 使用反射:

 

 public class AnimalFactory {
	/**
	 * 静态工厂方法
	 * @param clazz class
	 * @return 传进来的类的实例
	 */
	public static Object factory(Class clazz) {
		try {
			return clazz.newInstance();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		return null;
	}
}

 

 

 

1.       jdk dataFormat 简单工厂使用示例

         

 Locale locale = Locale.FRENCH;
		Date date = new Date();
		String now = DateFormat.getTimeInstance(DateFormat.DEFAULT, locale).format(date);
		try {
			date = DateFormat.getDateInstance(DateFormat.DEFAULT, locale).parse("16 nov. 01");
			System.out.println(date);
		} catch (ParseException e) {
			System.out.println("Parsing exception:" + e);
		}

 

 

2.       jdk Boolean valueOf 方法

      

public static Boolean valueOf(boolean b) {
        return (b ? TRUE : FALSE);
    }
         public static Boolean valueOf(String s) {
	return toBoolean(s) ? TRUE : FALSE;
    }

 

 

 

3.        jdk Integer valueOf 方法

 

Integer a = Integer.valueOf(3);
    public static Integer valueOf(int i) {
	final int offset = 128;
	if (i >= -128 && i <= 127) { // must cache 
	    return IntegerCache.cache[i + offset];
	}
        return new Integer(i);
    }
    private static class IntegerCache {
	private IntegerCache(){}

	static final Integer cache[] = new Integer[-(-128) + 127 + 1];

	static {
	    for(int i = 0; i < cache.length; i++)
		cache[i] = new Integer(i - 128);
	}
}

 

 

4.       抽象类 java.util.Calendar getInstance 方法将根据不同的情况返回不同的 Calendar 子类的对象

 

       

 private static Calendar createCalendar(TimeZone zone,
					   Locale aLocale)
    {
	// If the specified locale is a Thai locale, returns a BuddhistCalendar
	// instance.
	if ("th".equals(aLocale.getLanguage())
	    && ("TH".equals(aLocale.getCountry()))) {
	    return new sun.util.BuddhistCalendar(zone, aLocale);
	} else if ("JP".equals(aLocale.getVariant())
		   && "JP".equals(aLocale.getCountry())
		   && "ja".equals(aLocale.getLanguage())) {
	    return new JapaneseImperialCalendar(zone, aLocale);
	}	    
	// else create the default calendar
        return new GregorianCalendar(zone, aLocale);	
    }

 

 

可以想象到 当调用 Calendar 类的 getInstance 方法时 该方法会根据系统的默认地区信息返回一个合适的 Calendar 子类对象。而且将来如果需要支持某个其他地区的特殊历法,可以改变 Calendar getInstance 方法逻辑,但 Calendar 的使用者无需承担这种变化的影响。

 

4. spring.core用来判断jdk的版本:

http://www.blogjava.net/killme2008/archive/2007/04/11/109675.html

 

简单工厂模式是否支持 OCP 呢?
答案:只能在有限程度上支持。因为 OCP 要求不能对以 发布 的行为做修改,例如字段或方法,但是可 以进行扩展,可以增加字段或方法。而简单工厂模式中的工厂类不能做到这一点,当加入新的产品类的时候不得不修改工厂类创建产品方法的逻辑。

 

 

  • 大小: 28.8 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics