A qualified programmer must learn code refactoring

I looked at the code written by other interns a few days ago. There are a lot of if/else. Although if/else can help us write the flow control code very conveniently, it is also easy to read, but sometimes there are too many if/ else looks really uncomfortable, don’t say much, post the code first:

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;

	}

Seeing here, does it feel that the code is smelly and long, let's not say much, try to optimize it? The first thing that comes to mind is switch, the effect is as follows:

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;

	}

Oh my god, it’s still the same smelly, long, unqualified, so I am obsessive-compulsive, thinking of going back to the furnace and refactoring, here I will mainly talk about reflection and factory mode

First use reflection to reconstruct. code show as below:

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

	}

The RefactorCode code is as follows:

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);
		}
	}

}

The principle of using reflection to remove if/else is very simple. Use HashMap to establish the mapping relationship between the type type and the method name of the method that needs to be called, but everyone who knows reflection knows that the efficiency of reflection is not very high under the condition of high concurrency. Optimistic, so I thought of the factory model again.

Factory model refactoring

If you don’t know the factory model, you can Baidu:

The factory method pattern divides the ordinary factory into the concrete factory class in the simple factory and divides it into two layers: abstract factory layer + concrete factory subclass layer .

In order to solve the problem of simple factories, programmers came up with a new way, which is to design the interface of a factory. Whatever you want, write a class to inherit from this factory, so that you don’t need to modify anything, just add it directly. . It is equivalent to that my factory is used to produce shoes, and specific brands of shoes are allocated to each workshop. If there is a new brand of shoes, just add a new workshop.

  1. Abstract product role: usually an abstract class or interface, which defines abstract methods
  2. Specific product role: the implementation class of a specific product, inheriting or implementing an abstract strategy class, usually composed of one or more component classes.
  3. Factory role: Holds references to abstract product classes and is responsible for the selection and construction of dynamic runtime products

Follow the introduction of the factory model. We must first define an abstract product interface AbstractService. The code is as follows:

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);
}

Then we need to implement the products of these seven service types separately, and encapsulate different service algorithms in each product. The specific code is as follows:

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);

	}

}

The need is to realize the role of the factory, and the method to realize the product in the factory. Use HashMap to maintain the mapping relationship between the type and the object of the specific product.

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);
	}
}

Finally, the business layer implements the method call of the product:

/**
	 * 工厂模式
	 * 
	 * @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;
	}

Note: Having written so much, it’s not that if/else is not good enough, but just to illustrate the importance of learning code refactoring. Take the above example, I think the if/else or switch code is straightforward, programmers The road is too hard, and learning is endless. I hope to surpass myself every day. Don’t spray the bad writing. The technology is limited. I hope to give more guidance. Thanks

Guess you like

Origin blog.csdn.net/qq_37557563/article/details/111469943