一个合格的程序员,要学会代码重构

前几天看了一下别人实习生写的代码,有了大量的if/else,虽然if/else可以帮助我们很方便的写出流程控制代码,也便于阅读,但是有时候的过多的if/else看起来确实不舒服,话不多说,先把代码贴出来:

public BaseData updateBaseData(List<DataParams> params) {
		BaseData data = new BaseData();

		for (DataParams dataParams : params) {
			if (dataParams.type == 1) {
				data.setCode1(dataParams.code);
			} else if (dataParams.type == 2) {
				data.setCode2(dataParams.code);
			} else if (dataParams.type == 3) {
				data.setCode3(dataParams.code);
			} else if (dataParams.type == 4) {
				data.setCode4(dataParams.code);
			} else if (dataParams.type == 5) {
				data.setCode5(dataParams.code);
			} else if (dataParams.type == 6) {
				data.setCode6(dataParams.code);
			} else if (dataParams.type == 7) {
				data.setCode7(dataParams.code);
			} else if (dataParams.type == 8) {
				data.setCode8(dataParams.code);
			}
		}

		return data;

	}

看到这里 是不是感觉代码又臭又长,咱们话不多说,尝试优化一下?第一时间想到的是switch,效果如下:

public BaseData updateBaseData2(List<DataParams> params) {
		BaseData data = new BaseData();
		params.stream().forEach(param -> {
			switch (param.type) {
			case 1:
				data.setCode1(param.code);
				break;
			case 2:
				data.setCode2(param.code);
				break;
			case 3:
				data.setCode3(param.code);
				break;
			case 4:
				data.setCode4(param.code);
				break;
			case 5:
				data.setCode5(param.code);
				break;
			case 6:
				data.setCode6(param.code);
				break;
			case 7:
				data.setCode7(param.code);
				break;

			default:
				break;
			}
		});
		return data;

	}

唉呀妈呀  还是一样又臭又长,不合格,于是强迫症的我,想到直接回炉重构吧,这里我就主要讲一下反射和工厂模式

首先利用反射来进行重构。代码如下:

/**
	 * 利用反射重构代码
	 * 
	 * @param params
	 * @return
	 */
	public BaseData updateBaseData3(List<DataParams> params) {
		return RefactorCode.getReflect(params);

	}

RefactorCode代码如下:

package com.example.demo.com.example.utils;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.example.demo.com.example.wxPay.entity.BaseData;
import com.example.demo.com.example.wxPay.entity.DataParams;

public class RefactorCode {
	private static Map<Integer, String> map = new HashMap<>();

	static {
		map.put(1, "setCode1");
		map.put(2, "setCode2");
		map.put(3, "setCode3");
		map.put(4, "setCode4");
		map.put(5, "setCode5");
		map.put(6, "setCode6");
		map.put(7, "setCode7");
	}

	public static BaseData getReflect(List<DataParams> params) {
		BaseData data = new BaseData();
		params.stream().forEach(param -> commom(data, param));
		return data;
	}

	private static void commom(BaseData data, DataParams param) {
		String codeName = map.get(param.getType());
		try {
			Method method = BaseData.class.getMethod(codeName, Integer.class);
			method.invoke(data, param.getType());
		} catch (Exception e) {
			System.out.println(e);
		}
	}

}

使用反射去掉if/else的原理很简单,使用HashMap建立类型type和需要调用的方法的方法名之间的映射关系,但是知道反射的都知道,在高并发的条件下,反射的效率并不是很乐观,所以我又想到了工厂模式。

工厂模式重构

不知道工厂模式的可以百度一下:

工厂方法模式是把普通工厂就是把简单工厂中具体的工厂类,划分成两层:抽象工厂层+具体的工厂子类层

为了解决简单工厂的问题,程序员们又想出来一个新的办法,就是设计一个工厂的接口,你想要什么东西,就写个类继承于这个工厂,这样就不用修改什么,直接添加就行了。就相当于,我这个工厂是用来生产鞋子的,而要什么品牌的鞋子具体分到了每个车间,如果新多了一种品牌的鞋子,直接新增一个车间就行了。

  1. 抽象产品角色:通常是一个抽象类或者接口,里面定义了抽象方法
  2. 具体产品角色:具体产品的实现类,继承或是实现抽象策略类,通常由一个或多个组成类组成。
  3. 工厂角色:持有抽象产品类的引用,负责动态运行时产品的选择和构建

按照工厂模式的介绍。我们先要定义一个抽象产品接口AbstractService.代码如下:

package com.example.demo.com.example.wxPay.service;

import com.example.demo.com.example.wxPay.entity.BaseData;

public interface AbstractService {
	void refactoringCode(BaseData data, String code);
}

接着我们需要分别实现这七种服务类型的产品,在每种产品中封装不同的服务算法,具体的代码如下所示:

public class Code1Service implements AbstractService {

	@Override
	public void refactoringCode(BaseData data, String code) {
		data.setCode1(code);

	}

}

public class Code2Service implements AbstractService {

	@Override
	public void refactoringCode(BaseData data, String code) {
		data.setCode2(code);

	}

}

public class Code3Service implements AbstractService {

	@Override
	public void refactoringCode(BaseData data, String code) {
		data.setCode3(code);

	}

}

public class Code4Service implements AbstractService {

	@Override
	public void refactoringCode(BaseData data, String code) {
		data.setCode4(code);

	}

}

public class Code5Service implements AbstractService {

	@Override
	public void refactoringCode(BaseData data, String code) {
		data.setCode5(code);

	}

}

public class Code6Service implements AbstractService {

	@Override
	public void refactoringCode(BaseData data, String code) {
		data.setCode6(code);

	}

}

public class Code7Service implements AbstractService {

	@Override
	public void refactoringCode(BaseData data, String code) {
		data.setCode7(code);

	}

}

需要是实现工厂角色,在工厂内需要实现产品的方法,使用HashMap维护type和具体产品的对象之间的映射关系,

package com.example.demo.com.example.wxPay.service;

import java.util.HashMap;
import java.util.Map;

public class ServieFactory {
	private static Map<Integer, AbstractService> map = new HashMap<>();

	static {
		map.put(1, new Code1Service());
		map.put(2, new Code2Service());
		map.put(3, new Code3Service());
		map.put(4, new Code4Service());
		map.put(5, new Code5Service());
		map.put(6, new Code6Service());
		map.put(7, new Code7Service());
	}

	public static AbstractService getCodeService(Integer type) {
		return map.get(type);
	}
}

最后就是业务层实现产品的方法调用:

/**
	 * 工厂模式
	 * 
	 * @param params
	 * @return
	 */
	public BaseData updateBaseData4(List<DataParams> params) {
		BaseData data = new BaseData();
		params.stream().forEach(
				param -> ServieFactory.getCodeServicre(param.getType()).refactoringCode(data, param.getCode()));
		return data;
	}

注:写了这么多,并不是说if/else不够好,只是说明一下学会代码重构的重要性,就拿上述例子来说,我觉得还是if/else 或者switch代码来的直接明了,程序员之路太艰辛,学习永无止境,希望每天都在超越自己,写的不好的也不要喷,技术有限,希望多指导一下,感谢

猜你喜欢

转载自blog.csdn.net/qq_37557563/article/details/111469943