一、引子
话说十年前,有一个用户,他家有三辆汽车——Benz奔驰、Bmw宝马、Audi奥迪,还雇了司机为他开车。不过,用户坐车时总是怪怪的:上Benz车后跟司机说“开奔驰车!”,坐上Bmw后他说“开宝马车!”,坐上Audi说“开奥迪车!”。你一定说:这人有病!直接说开车不就行了?!
而当把这个用户的行为放到我们程序设计中来时,会发现这是一个普遍存在的现象。幸运的是,这种有病的现象在OO(面向对象)语言中可以避免了。下面就以Java语言为基础来引入我们本文的主题:工厂模式。
二、分类
1)简单工厂模式(Simple Factory)
2)工厂方法模式(Factory Method)
3)抽象工厂模式(Abstract Factory)
这三种模式从上到下逐步抽象,并且更具一般性。
三、代码
1.说明:
装扮操作,客户通过点击不同的头发,便会生成不同的对象,那么当我们想新增加一个头发类型时,如果不用工厂模式,那么就去多添加else if 去新生成一个新的对象给客户端,这个每添加一个类就要去改动一下代码的方式极不合适,这时我们就用到了工厂,通过头发生成工厂,我们只会需要改一个配置文件,同时告诉客户端我们有这个 新的对象可以使用,那么客户就可以直接使用了。
头发接口
Hair.java
package com.lei.model;
public interface Hair {
public void drawHair();
}
BlueHair.java
package com.lei.model.impl.hair;
import com.lei.model.Hair;
public class BlueHair implements Hair {
@Override
public void drawHair() {
System.out.println("----------蓝色头发---------------");
}
}
BlackHair.java
package com.lei.model.impl.hair;
import com.lei.model.Hair;
public class BlackHair implements Hair {
@Override
public void drawHair() {
System.out.println("---------黑色头发------------");
}
}
RedHair.java
package com.lei.model.impl.hair;
import com.lei.model.Hair;
public class RedHair implements Hair {
@Override
public void drawHair() {
System.out.println("-------------红色头发-----------");
}
}
读取配置文件工具类
PropertiesReadUtil
package com.lei.utils;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
public class PropertiesReadUtil {
public Map<String, String> getProperties(){
Map<String,String> map = new HashMap<>();
Properties properties = new Properties();
try {
InputStream in = getClass().getResourceAsStream("/com/lei/pro/hair.properties");
properties.load(in);
Enumeration<Object> ens = properties.keys();
while (ens.hasMoreElements()) {
String key = (String) ens.nextElement();
String value = properties.getProperty(key);
map.put(key, value);
}
return map;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
生成头发工厂
HairFactory.java
package com.lei.utils;
import java.util.Map;
import java.util.Properties;
import com.lei.model.Hair;
/**
* 生产头发的工厂
* @author pibigstar
*
*/
public class HairFactory {
public Hair getHairByKey(String key){
PropertiesReadUtil pr = new PropertiesReadUtil();
Map<String, String> map = pr.getProperties();
try {
//通过反射机制,生成对像,通过key得到类名,通过类名生成对应的对象
Hair hair = (Hair) Class.forName(map.get(key)).newInstance();
return hair;
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
public Hair getHairByClassName(String className){
try {
/*通过反射机制,生成对像,通过类名去生成一个对象
*这样你就算增加了新的类,只要告诉客户端有这个类,不需要改动任何代码就可以动态的生成这个新类的对象
*
*/
Hair hair = (Hair) Class.forName(className).newInstance();
return hair;
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
}
配置文件
hair.properties
red=com.lei.model.impl.hair.RedHair
black=com.lei.model.impl.hair.BlackHair
blue=com.lei.model.impl.hair.BlueHair
测试类
FactoryTest.java
package com.lei.test;
import com.lei.model.Hair;
import com.lei.utils.HairFactory;
public class FactoryTest {
public static void main(String[] args) {
// HairFactory factory = new HairFactory();
// Hair hair = factory.getHairByClassName("com.lei.model.impl.hair.BlueHair");
//
// hair.drawHair();
HairFactory factory = new HairFactory();
Hair hair = factory.getHairByKey("red");
hair.drawHair();
}
}