码迷,mamicode.com
首页 > 编程语言 > 详细

Java设计模式之工厂方法模式

时间:2015-08-09 00:33:37      阅读:157      评论:0      收藏:0      [点我收藏+]

标签:

工厂方法模式介绍

有时候,由于产品的多样化,但是产品的功能却有某种共同的联系。我们希望定义一个用于创建产品对象的公共接口,让子类决定去如何实现这个功能。然后,我们定义一个生产产品的“工厂”,所有的产品将从这个工厂里面生产出来,这样我们就使得产品的构造的细节与工厂分离了,这样产品的实现细节就被封装起来了,并且产品的可扩展性也很强。那么,这种设计模式我们称为工厂方法模式。具体的实例有很多,比如说去年的某一阵子脸萌软件爆红,其中就运用到了工厂方法模式来给用户生产各种脸型。

工厂方法模式分类

根据我个人的总结,我认为工厂方法模式总共分为四种,它们的具体差别如下表所示:

静态模式 工厂中使用静态方法来直接创建各个产品
普通模式 工厂中使用if-else语句来判断用户需求,进而生产产品
映射模式 工厂中使用key-value读取配置文件来映射产品种类,进而生产产品
反射模式 工厂中使用反射生产产品的实例

工厂方法模式的代码实现

公共代码部分

现在我们使用微信的发送文字、发送图片、发送视频三个功能来简单的说明一下工厂方法模式,当然本例中并不去具体实现如何发送文字、图片、视频等内容,只是以此为模板来示范一下。

首先,我们考虑到三个功能都有一个共同点,即都具有发送这一行为,因此,在Java中接口与抽象类的最重要的区别就是接口是对行为的抽象,而抽象类是对类的抽象,具有同一行为的场景下我们优先想到定义一个接口来约束它们,相当于是给它们指定了一个原则,必须要实现接口中定义的这个行为(功能)。

因此,先设计一个公共接口Sendable,其中要定义一个方法send(),是子类必须要实现的功能。

package com.factory.factoryMethod;

public interface Sendable {

	public void send();
}



接下来,写三个具体的产品,即文字、图片、视频。

发送文字:

package com.factory.factoryMethod;

public class TextSender implements Sendable {

	@Override
	public void send() {
		System.out.println("发送文字");
	}
}



发送图片:

package com.factory.factoryMethod;

public class PhotoSender implements Sendable {

	@Override
	public void send() {
		System.out.println("发送图片");
	}
}



发送视频:

package com.factory.factoryMethod;

public class VideoSender implements Sendable{

	@Override
	public void send() {
		System.out.println("发送视频");
	}
}



以上就是四中不同设计方法的公共部分,即产品的实现部分,因此,无论采用哪种方法,产品的实现与生产是分离的。

下面分别介绍四中不同的工厂设计方法。

工厂方法模式——普通模式

普通模式即在工厂中使用传统的if-else来判断用户的需求。如下面的代码所示:

package com.factory.factoryMethod;

public class SenderFactory {
	
	 public Sendable produce(String type) {  
	        if ("text".equals(type)) {  
	            return new TextSender();  
	        } else if ("photo".equals(type)) {  
	            return new PhotoSender();  
	        } else if ("video".equals(type)) {  
	            return new VideoSender(); 
	        } else {
	        	System.err.println("暂无此产品");
	        	return null;
	        }
	    }  
}

工厂方法模式——映射模式

映射模式中采用了配置文件来处理键值对,好处就是用户不需要记得太多的产品类名,只需要记住关键词即可,工厂会自动映射过去。代码实现如下:

package com.factory.factoryMethod;

import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

public class SenderFactory {
	
	 public Sendable produce(String key) {  
		 try {
				PropertiesReader propertiesReader = new PropertiesReader();
				Map<String, String> properties = propertiesReader.getProperties();
				String className = properties.get(key);
				Sendable sender = (Sendable) Class.forName(className).newInstance();
				return sender;
			} catch (InstantiationException | IllegalAccessException
					| ClassNotFoundException e) {
				e.printStackTrace();
			}
			return null;
	 }  
}

class PropertiesReader {
	public Map<String,String> getProperties() {
		Properties properties = new Properties();
		Map<String, String> hashMap = new HashMap<String,String>();
		try {
			InputStream resourceAsStream = this.getClass().getResourceAsStream("type.properties");
			properties.load(resourceAsStream);
			Enumeration<?> propertyNames = properties.propertyNames();
			while(propertyNames.hasMoreElements()) {
				String key = (String)propertyNames.nextElement();
				String property = properties.getProperty(key);
				hashMap.put(key, property);
			}
		} catch(Exception ex) {
			ex.printStackTrace();
		}
		return hashMap;

	}
}



上面代码用到的配置文件为type.properties,内容如下:

T=com.factory.factoryMethod.TextSender
P=com.factory.factoryMethod.PhotoSender
V=com.factory.factoryMethod.VideoSender



工厂方法模式——反射模式

反射模式其实跟上面一种方法差不多,只不过少了配置文件而已,而且没有了关键词,需要提供方法名了,代码如下:

package com.factory.factoryMethod;

public class SenderFactory {
	
	 public Sendable produce(String className) {  
		try {
				Sendable sender = (Sendable) Class.forName(className).newInstance();
				return sender;
			} catch (InstantiationException | IllegalAccessException
					| ClassNotFoundException e) {
				e.printStackTrace();
			}
		return null;
	 }  
}



工厂方法模式——静态模式

静态模式,顾名思义,在工厂中静态创建产品,不需要创建工厂对象了,这种模式用得比较广泛一点,代码示例如下:

package com.factory.factoryMethod;

public class SenderFactory {
	
	 public static Sendable produceTextSender() {  
		return new TextSender();
	 }
	 public static Sendable producePhotoSender() {  
		return new PhotoSender();
	 }
	 public static Sendable produceVideoSender() {  
		return new VideoSender();
	 }  
}



工厂方法模式总结

当有大量产品需要被创建时,并且具有共同的某些行为时,可以考虑使用工厂模式,将产品实现细节分离开来。而这四种方法中,最常用的是静态创建方法,其他的三种可能由于参数传递错误,导致无法创建,需要熟悉具体的调用参数才行。

Java设计模式之工厂方法模式

标签:

原文地址:http://my.oschina.net/zzw922cn/blog/489614

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