设计模式(实战)-抽象工厂模式

一:抽象工厂模式说明

模式定义:为创建一组相关或相互依赖的对象提供一个接口,而且无须指定它们的具体类(取自《设计模式之禅》)。

抽象工厂模式是工厂方法模式的升级版本,在有多个业务品种、业务分类时,通过抽象工厂模式产生需要的对象是一种非常好的解决方式。

通用类图如下(可能有不同版本,本文中仿照这个版本):

AbstractProductA,AbstractProductB.....无限扩展,具体实现的子类为ProductA1,ProductA2...也是无限扩展,不管是产品类型维度和具体现实类都是可以动态扩展的,最后由AbstractCreator工厂创建对象。

二:项目实战

需求如下,

1.前端需要展现Echarts图表,后台接口提供json数据对象;

2.一个类可以调用多种图表;

3.而且图表封装的工具类可以进行动态的扩展而不需要增加和修改很多代码;

echarts官网json对象截图

痛点如下:

  1. 数据组装过程复杂;
  2. Java后台已经使用模板模式,如果一个类要实现多种图表,无法多继承;
  3. 图表的扩展和调用也比较困难;

故选用抽象工厂模式,图1.1中不同的产品类型正好对应Echarts中不同的图表类型,productA对应柱状图,productB对应折线图等等;工厂模式很好的解决了问题2和问题3,而模板模式又很好的解决了问题1,完美。

模板模式传送门:https://blog.csdn.net/xiewenfeng520/article/details/83278250

项目类图如下

EchartsFactory为顶层的工厂抽象类,定义工厂需要创建对象的抽象方法。

DefaultEchartsFactory继承EchartsFactory,是具体方法的实现类。

AbstractBarSimple和AbstractLineSimple为不同图表产品的抽象父类,而BarSimpleImpl1,BarSimpleImpl2....为具体业务实现。

BsaeEchartsBean为顶层的图表对象抽象类,定义图表的公告抽象方法。

核心代码如下:

EchartsFactory:

package com.huajie.service.echarts;

import java.util.Map;
/**
 * @author xiewenfeng Echarts抽象工厂
 */
public abstract class EchartsFactory {

	public abstract AbstractBarSimple createBarSimple(Map<String, Object> parameters, Class<?> cls);

	public abstract AbstractLineSimple createLineSimple(Map<String, Object> parameters, Class<?> cls);
	
}

DefaultEchartsFactory:

package com.huajie.service.echarts;

import java.lang.reflect.Method;
import java.util.Map;
import org.springframework.beans.BeansException;
import com.huajie.utils.Spring.SpringUtils;

public class DefaultEchartsFactory extends EchartsFactory {

	@Override
	public AbstractBarSimple createBarSimple(Map<String, Object> parameters, Class<?> cls) {
		return (AbstractBarSimple)getBeanInstance(cls,parameters);
	}

	@Override
	public AbstractLineSimple createLineSimple(Map<String, Object> parameters, Class<?> cls) {
		return (AbstractLineSimple)getBeanInstance(cls,parameters);
	}
	
	
	@SuppressWarnings("unchecked")
	public static <T> T getBeanInstance(Class<T> cls,Map<String, Object> parameters) throws BeansException {
        try {
        	/**
			 * 如果使用反射newInstance()之后<br/>
			 * cls实现类springIOC容器失效<br/>
			 * 所以从SpringIOC容器中获取该实例
			 */
        	Object obj = SpringUtils.getBeanByName(cls);
			Method method = cls.getDeclaredMethod("setParameters", new Class[] { Map.class });
			method.setAccessible(true);
			method.invoke(obj, parameters);
            return (T)obj;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } 
    }

}

BsaeEchartsBean: 

package com.huajie.service.echarts;

import java.util.Map;
/**
 * @author xiewenfeng 
 */
public abstract class BsaeEchartsBean<T>{
	
	protected Map<String, Object> parameters;
	
	protected abstract void setParameters(Map<String, Object> parameters);

	protected abstract T initEchartsData() ;

}

AbstractLineSimple:

package com.huajie.service.echarts;

import java.util.ArrayList;
import java.util.List;
import com.huajie.entity.echarts.ExtMapData;
import com.huajie.entity.echarts.LineSimple;

/**
 * @author xiewenfeng 封装后台echarts 图表数据组合 LineSimple折线图
 */
public abstract class AbstractLineSimple extends BsaeEchartsBean<LineSimple>{

	/**
	 * 获取data数据集 
	 * name :x轴值集合 
	 * value :对应的y轴值集合
	 * ExtMapData<name:value> 的List集合形式
	 * @return
	 */
	protected abstract List<ExtMapData<String, String>> ListXYAxis();

	public LineSimple initEchartsData() {
		LineSimple lineSimple = new LineSimple();
		List<String> xAxisDataList = new ArrayList<String>();
		List<String> seriesDataList = new ArrayList<String>();
		List<ExtMapData<String, String>> listData = ListXYAxis();
		
		for (ExtMapData<String, String> extMapData : listData) {
			xAxisDataList.add(String.valueOf(extMapData.getName()));
			seriesDataList.add(String.valueOf(extMapData.getValue()));
		}
		
		lineSimple.setXAxisData(xAxisDataList);
		lineSimple.setSeriesData(seriesDataList);
		return lineSimple;
	}

}

AbstractBarSimple:

package com.huajie.service.echarts;

import java.util.ArrayList;
import java.util.List;
import com.huajie.entity.echarts.BarSimple;
import com.huajie.entity.echarts.ExtMapData;

/**
 * @author xiewenfeng 
 * 封装后台echarts 图表数据组合
 * BarSimple柱状图
 */
public abstract class AbstractBarSimple extends BsaeEchartsBean<BarSimple>{
	
	protected abstract List<String> getLegendList();
	
	/**
	 * 获取data数据集
	 * name :x轴值集合
	 * value :对应的y轴值集合
	 * ExtMapData<name:value> 的List集合形式
	 * @return
	 */
	protected abstract List<ExtMapData<String, String>> ListXYAxis();

	public BarSimple initEchartsData() {
		BarSimple barSimple = new BarSimple();
		List<String> legendList = getLegendList();
		List<ExtMapData<String, String>> listData = ListXYAxis();
		List<String> xAxisDataList = new ArrayList<String>();
		List<Object> serieDataList = new ArrayList<Object>();
		List<List<Object>> serieDataListSum = new ArrayList<List<Object>>();
		
		for (ExtMapData<String, String> extMapData : listData) {
			xAxisDataList.add(String.valueOf(extMapData.getName()));
			serieDataList.add(String.valueOf(extMapData.getValue()));
		}
		
		barSimple.setLegendData(legendList);
		barSimple.setXAxisData(xAxisDataList);
		serieDataListSum.add(serieDataList);
		barSimple.setSeriesData(serieDataListSum);
		return barSimple;
	}

}

对应业务实现类(每个项目根据自身需求同步,对应现实类不同)

BarSimpleImpl

package com.huajie.service.impl.echarts.LeadergroupTotalAnalysis;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.huajie.entity.echarts.ExtMapData;
import com.huajie.mapper.report.LeadergroupTotalAnalysisMapper;
import com.huajie.service.echarts.AbstractBarSimple;

/**
 * @author xiewenfeng 总体分析柱状图
 */
@Service
public class BarSimpleImpl extends AbstractBarSimple {

	@Autowired
	private LeadergroupTotalAnalysisMapper leadergroupTotalAnalysisMapper;
	
	@Override
	protected void setParameters(Map<String, Object> parameters) {
		super.parameters = parameters;
	}

	@Override
	protected List<String> getLegendList() {
		List<String> legendList = new ArrayList<String>();
		legendList.add("分数");
		return legendList;
	}

	@Override
	protected List<ExtMapData<String, String>> ListXYAxis() {
		return leadergroupTotalAnalysisMapper.getLeadergroupQuotaDistribute(parameters);
	}


}

LineSimpleImpl

package com.huajie.service.impl.echarts.LeadergroupTotalAnalysis;

import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.huajie.entity.echarts.ExtMapData;
import com.huajie.mapper.report.LeadergroupTotalAnalysisMapper;
import com.huajie.service.echarts.AbstractLineSimple;

@Service
public class LineSimpleImpl extends AbstractLineSimple {

	@Autowired
	private LeadergroupTotalAnalysisMapper leadergroupTotalAnalysisMapper;

	
	@Override
	protected void setParameters(Map<String, Object> parameters) {
		super.parameters = parameters;
	}

	@Override
	protected List<ExtMapData<String, String>> ListXYAxis() {
		return leadergroupTotalAnalysisMapper.getLeadergroupExcellentRates(parameters);
	}

}

对应的javaBean对象

BarSimple

package com.huajie.entity.echarts;

import java.util.List;
import lombok.Data;

/**
 * @author xiewenfeng
 * echarts普通柱状图
 */
@Data
public class BarSimple {
	//legend中data的数据
	private List<String> legendData;
	private List<String> xAxisData;
	private List<String> yAxisData;
	private List<List<Object>> seriesData;
}

LineSimple

package com.huajie.entity.echarts;

import java.util.List;

import lombok.Data;
@Data
public class LineSimple {
	private List<String> xAxisData;
	private List<String> yAxisData;
	private List<String> seriesData;
}
package com.huajie.entity.echarts;

import lombok.Data;

@Data
public class ExtMapData<K,V> {
	private K name;
	private V value;
}

最后一步,业务模板调用的代码如下:

        private  EchartsFactory echartsFactory = new DefaultEchartsFactory();    
        @Override
	public BarSimple getBarSimple(Map<String, Object> conditionMap) {
		AbstractBarSimple createBarSimple = echartsFactory.createBarSimple(conditionMap,BarSimpleImpl.class);
		return createBarSimple.initEchartsData();
	}
	
	@Override
	public LineSimple getLineSimple(Map<String, Object> conditionMap) {
		AbstractLineSimple createLineSimple = echartsFactory.createLineSimple(conditionMap,LineSimpleImpl.class);
		return createLineSimple.initEchartsData();
	}

实际项目效果图:

猜你喜欢

转载自blog.csdn.net/xiewenfeng520/article/details/83544073