工厂模式概述
设计模式理解
工厂模式主要目的是进行对象实例的创建,并对对象实例进行统一集约化管理,主要的模式主要包括:普通工厂模式,抽象工厂模式,反射工厂模式等三种。
在使用场景上,三种工厂模式主要体现在客户端的调用策略的不同:
普通工厂:不同的业务类实现,在一个工厂类中进行实例化
抽象工厂:不同的业务类实现,在不同的工厂类中进行实例化
反射工厂:不同的业务类实现,使用一个反射工厂进行统一处理
不同工厂模式的优缺点
普通工厂:在同一个工厂内完成对象实例化,在大部分业务场景中都能适用,而且相对而言,不需要编写大量的工厂类。缺点是:工厂类本身功能过于集中,可能需要需要被频繁的改动。
抽象工厂:在普通工厂的基础上,进一步抽象工厂类,把原本集中在一个类的工厂方法进行功能剥离,降低了代码耦合度,符合基于抽象编程的原则。缺点是:可能导致出现大量的类
反射工厂:基于上述两种工厂的缺点,利用反射技术,能够进一步降低代码耦合度,核心思路就是将需要实例化的对象从代码抽离,使用配置的方式,进一步提高客户端代码的灵活性
代码实现
抽象工厂
普通的工厂模式,在之前的策略模式中已经描述过具体的代码应用,此处仅仅对抽象工厂以及反射工厂进行描述。
业务类接口:
需要生产一部手机,生产手机则需要屏幕、相机镜头、cpu、外壳等各个零部件
public interface IPhone {
public void screenProduct();
public void cameraProduct();
public void cpuProduct();
public void shellProuct();
}
业务接口实现类:这个类主要用于实现具体业务,是需要被实例化的核心对象:
对手机零部件进行生产,苹果手机
public class IPhoneApple implements IPhone{
@Override
public void screenProduct() {
System.out.println("完成苹果手机屏幕的组装");
}
@Override
public void cameraProduct() {
System.out.println("完成苹果手机相机的组装");
}
@Override
public void cpuProduct() {
System.out.println("完成苹果手机CPU的组装");
}
@Override
public void shellProuct() {
System.out.println("完成苹果手机外壳的组装");
}
}
生产小米手机:
public class IPhoneXiaomi implements IPhone{
@Override
public void screenProduct() {
System.out.println("完成小米手机屏幕的组装");
}
@Override
public void cameraProduct() {
System.out.println("完成小米手机相机的组装");
}
@Override
public void cpuProduct() {
System.out.println("完成小米手机CPU的组装");
}
@Override
public void shellProuct() {
System.out.println("完成小米手机外壳的组装");
}
}
建立手机生产组装工厂:注意这个工厂类需要定义成接口
/*抽象工厂类*/
public interface IFactory {
public IPhone productMake();
}
具体的生产车间:生产手机并返回具体的手机实例,不同的生产车间,将会返回不同的生产对象实例
生产一个苹果手机:
public class AppleFactory implements IFactory {
@Override
public IPhone productMake(){
return new IPhoneApple();
}
}
生产一个小米手机
public class XiaoMiFactory implements IFactory{
@Override
public IPhone productMake(){
return new IPhoneXiaomi();
}
}
客户端调用:
import com.ruoli.designmode.factory.normal.IFactory;
import com.ruoli.designmode.factory.normal.IPhone;
import com.ruoli.designmode.factory.normal.impl.AppleFactory;
import com.ruoli.designmode.factory.normal.impl.XiaoMiFactory;
import org.testng.annotations.Test;
public class NormalFactory {
@Test
public void testNormalFactoryApple(){
IFactory iFactory = new AppleFactory();
IPhone iPhone = iFactory.productMake();
iPhone.cameraProduct();
iPhone.cpuProduct();
iPhone.screenProduct();
iPhone.shellProuct();
}
@Test
public void testNormalFactoryXiaomi(){
IFactory iFactory = new XiaoMiFactory();
IPhone xiaomi = iFactory.productMake();
xiaomi.cameraProduct();
xiaomi.cpuProduct();
xiaomi.screenProduct();
xiaomi.shellProuct();
}
}
运行结果如下:
反射工厂
定义业务接口,生产一辆汽车:
public interface ICar {
public String makeShell();
public String makeEngine();
public String makeTyre();
}
实际的业务类,实现具体的接口,生产一辆BENZ汽车:
public class BenzCarImpl implements ICar{
@Override
public String makeShell(){
return new String("完成奔驰外壳的组装");
}
@Override
public String makeEngine(){
return new String("完成奔驰引擎的组装");
//System.out.println("完成奔驰引擎的组装");
}
@Override
public String makeTyre(){
return new String("完成奔驰车轮的组装");
//System.out.println("完成奔驰车轮的组装");
}
public String toString(){
return new String(makeEngine()+","
+makeShell()+","
+makeTyre());
}
}
生产一辆BWM汽车
public class BWMCarImpl implements ICar{
@Override
public String makeShell(){
//System.out.println("完成宝马外壳的组装");
return new String("完成宝马外壳的组装");
}
@Override
public String makeEngine(){
//System.out.println("完成宝马引擎的组装");
return new String("完成宝马引擎的组装");
}
@Override
public String makeTyre(){
//System.out.println("完成宝马车轮的组装");
return new String("完成宝马车轮的组装");
}
public String toString(){
return new String(makeEngine()+","
+makeShell()+","
+makeTyre());
}
}
重点内容:利用反射完成对象实例的创建:
外部只需要传入需要实例化的类名称,即可完成反射
package com.ruoli.designmode.factory.reflect;
public class ReflectFactoryContext {
public ICar doCarFactory(String className) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
return (ICar)Class.forName(className).newInstance();
}
public IShip doShipFactory(String className) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
return (IShip)Class.forName(className).newInstance();
}
}
利用testng的配置注解进行测试:
package com.ruoli.designmode.Factory;
import com.ruoli.designmode.factory.reflect.ICar;
import com.ruoli.designmode.factory.reflect.IShip;
import com.ruoli.designmode.factory.reflect.ReflectFactoryContext;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
/*
Parameters注解功能可以利用testng的xml文件,从xml文件中读取配置参数并传入test方法
*/
public class ReflectFactory {
@Test
@Parameters({"className1","className2"})
public void testReflectFactory(String clazzName1
,String clazzName2)
throws IllegalAccessException, InstantiationException, ClassNotFoundException {
ReflectFactoryContext reflectFactoryContext =
new ReflectFactoryContext();
ICar iCar = reflectFactoryContext.doCarFactory(clazzName1);
System.out.println(iCar.toString());
IShip iShip = reflectFactoryContext.doShipFactory(clazzName2);
System.out.println(iShip.toString());
}
}
test.xml文件内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="action test">
<test name="ruoli">
<parameter name="className1" value="com.ruoli.designmode.factory.reflect.impl.BenzCarImpl"/>
<parameter name="className2" value="com.ruoli.designmode.factory.reflect.impl.DestroyerShipImpl"/>
<parameter name="className3" value="com.ruoli.designmode.factory.reflect.impl.BWMCarImpl"/>
<parameter name="className4" value="com.ruoli.designmode.factory.reflect.impl.CruiserShipImpl"/>
<classes>
<class name="com.ruoli.designmode.Factory.ReflectFactory"></class>
</classes>
</test>
</suite>
执行结果: