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

工厂方法模式介绍

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

工厂方法模式分类

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

静态模式

工厂中使用静态方法来直接创建各个产品

普通模式

工厂中使用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 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 getProperties() {

Properties properties = new Properties();

Map hashMap = new HashMap();

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();

}

}

工厂方法模式总结

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值