java工厂模式实例讲解

本文介绍了一种使用Java实现的工厂模式应用案例,通过创建不同类型的头发对象来展示如何利用工厂模式简化代码扩展并提高系统的灵活性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、引子 

            话说十年前,有一个用户,他家有三辆汽车——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();
		
	}

}









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值