demo
看这样一段恶心的代码
if (entry.getValue()<3){
ListIterator<Chart> iterator = list.listIterator();
while (iterator.hasNext()){
Chart next = iterator.next();
if (entry.getValue()==1){
if ("电视".equals(next.getType())){
Chart chart = new Chart("电脑","0",next.getDate());
iterator.add(chart);
chart = new Chart("手机","0",next.getDate());
iterator.add(chart);
}
if ("电脑".equals(next.getType())){
Chart chart = new Chart("手机","0",next.getDate());
iterator.add(chart);
chart = new Chart("电视","0",next.getDate());
iterator.add(chart);
}
if ("手机".equals(next.getType())){
Chart chart = new Chart("电视","0",next.getDate());
iterator.add(chart);
chart = new Chart("电视","0",next.getDate());
iterator.add(chart);
}
}
if (entry.getValue()==2){
List<String> listType = type.get(entry.getKey());
String firstType = listType.get(0);
String secondType = listType.get(0);
if ("电视".equals(firstType)){
if ("电脑".equals(secondType)){
Chart chart = new Chart("手机","0",next.getDate());
iterator.add(chart);
}
if ("手机".equals(secondType)){
Chart chart = new Chart("电脑","0",next.getDate());
iterator.add(chart);
}
}
if ("电脑".equals(firstType)){
if ("电视".equals(secondType)){
Chart chart = new Chart("手机","0",next.getDate());
iterator.add(chart);
}
if ("手机".equals(secondType)){
Chart chart = new Chart("电视","0",next.getDate());
iterator.add(chart);
}
}
if ("手机".equals(firstType)){
if ("电视".equals(secondType)){
Chart chart = new Chart("电脑","0",next.getDate());
iterator.add(chart);
}
if ("电脑".equals(secondType)){
Chart chart = new Chart("电视","0",next.getDate());
iterator.add(chart);
}
}
}
}
}
如何去解构这个代码呐,是不快要看吐了,没错,下面将用策略模式和工厂模式对它进行改造,当然也会用到枚举类,因为枚举类也是改造if…else语句的一把好手,来看吧
策略模式、工厂模式对if…else进行改造
首先对这段代码进行改造,
if (entry.getValue()==1){
if ("电视".equals(next.getType())){
Chart chart = new Chart("电脑","0",next.getDate());
iterator.add(chart);
chart = new Chart("手机","0",next.getDate());
iterator.add(chart);
}
if ("电脑".equals(next.getType())){
Chart chart = new Chart("手机","0",next.getDate());
iterator.add(chart);
chart = new Chart("电视","0",next.getDate());
iterator.add(chart);
}
if ("手机".equals(next.getType())){
Chart chart = new Chart("电视","0",next.getDate());
iterator.add(chart);
chart = new Chart("电视","0",next.getDate());
iterator.add(chart);
}
}
可以看到是是,if对每个type进行判断,然后iterator添加每个值,而且每个if的语句基本是一样的,所有也就有了改造思路
根据if语句处理的内容抽成一个接口,再将每个if语句负责的内容创建不同的类,实现这个接口,这就是策略模式,即上图的右边部分
public interface ChartChange {
List<Chart> addChart(String date);
String getType();
}
@Component
public class DnChart implements ChartChange, InitializingBean {
@Override
public List<Chart> addChart(String date) {
List<Chart> list = new ArrayList<>();
Chart chart = new Chart("手机","0",date);
list.add(chart);
chart = new Chart("电视","0",date);
list.add(chart);
return list;
}
@Override
public String getType() {
return "电脑";
}
@Override
public void afterPropertiesSet() throws Exception {
AddChartFactory.register(getType(),this);
}
}
@Component
public class DsChart implements ChartChange, InitializingBean {
@Override
public List<Chart> addChart(String date) {
List<Chart> list = new ArrayList<>();
Chart chart = new Chart("电脑","0",date);
list.add(chart);
chart = new Chart("手机","0",date);
list.add(chart);
return list;
}
@Override
public String getType() {
return "电视";
}
@Override
public void afterPropertiesSet() throws Exception {
AddChartFactory.register(getType(),this);
}
}
@Component
public class SjChart implements ChartChange, InitializingBean {
@Override
public List<Chart> addChart(String date) {
List<Chart> list = new ArrayList<>();
Chart chart = new Chart("电脑","0",date);
list.add(chart);
chart = new Chart("电视","0",date);
list.add(chart);
return list;
}
@Override
public String getType() {
return "手机";
}
@Override
public void afterPropertiesSet() throws Exception {
AddChartFactory.register(getType(),this);
}
}
工厂类,工厂类提供了一个注册方法,使类可以注册到这个工厂中,而工厂中提供了一个Map方法,通过传进来type,可以获取到相应的List了,这样就不用写过多的判断了
@Component
public class AddChartFactory {
private static final Map<String,ChartChange> map = new HashMap<>();
public static void register(String type,ChartChange chartChange) throws Exception {
if (type==null){
throw new Exception("type不能为空");
}
map.put(type, chartChange);
}
public static ChartChange getChart(String type){
return map.get(type);
}
}
看一下改造后的方法吧,通过传进来type,可以获取到相应的List了,也就省去了很多判断
if (entry.getValue()==1){
List<Chart> charts = AddChartFactory.getChart(next.getType()).addChart(next.getDate());
for (Chart chart : charts){
iterator.add(chart);
}
}
需要补充一点的是,如何注册到工厂中呐?相信你也以及注意到了再策略类中,除了实现ChartChange接口,还实现了InitializingBean接口,这个接口提供了一个方法,afterPropertiesSet,这个方法是干什么的呐?没错,它是Bean初始化后一定会执行的一个方法,通过这个方法就可以将策略类注册到工厂中了
那么,下面这段又改如何改造呐?它首先有三个判断,手机,电脑,电视,在三个判断里又有两个判断,然后添加一个Chart类到List中,这里看到了firstType和secondType,那么可否用枚举的方法来将所有的类型穷举掉,然后通过遍历这些类型就可以获得Chart类返回给控制层调用呐?答案是可以的
if (entry.getValue()==2){
List<String> listType = type.get(entry.getKey());
String firstType = listType.get(0);
String secondType = listType.get(0);
if ("电视".equals(firstType)){
if ("电脑".equals(secondType)){
Chart chart = new Chart("手机","0",next.getDate());
iterator.add(chart);
}
if ("手机".equals(secondType)){
Chart chart = new Chart("电脑","0",next.getDate());
iterator.add(chart);
}
}
if ("电脑".equals(firstType)){
if ("电视".equals(secondType)){
Chart chart = new Chart("手机","0",next.getDate());
iterator.add(chart);
}
if ("手机".equals(secondType)){
Chart chart = new Chart("电视","0",next.getDate());
iterator.add(chart);
}
}
if ("手机".equals(firstType)){
if ("电视".equals(secondType)){
Chart chart = new Chart("电脑","0",next.getDate());
iterator.add(chart);
}
if ("电脑".equals(secondType)){
Chart chart = new Chart("电视","0",next.getDate());
iterator.add(chart);
}
}
}
我们来看,我用枚举的办法,穷举了电脑、电视、手机的所有组合,这样就可以对原方法进行改造了
public enum AddChartEnum {
DS("电脑","手机","电视"),
DD("电脑","电视","手机"),
DSS("电视","手机","电脑"),
SD("电视","电脑","手机"),
SDS("手机","电视","电脑"),
SDN("手机","电脑","电视");
private String firstType;
private String secondType;
private String type;
private static Chart chart;
AddChartEnum(String firstType, String secondType, String type) {
this.firstType = firstType;
this.secondType = secondType;
this.type = type;
}
public static Chart of(String firstType,String secondType,String date){
for (AddChartEnum chart : AddChartEnum.values()){
if (firstType.equals(chart.firstType)&&secondType.equals(chart.secondType)){
return new Chart(chart.getType(),"0","0");
}
}
return null;
}
public void setFirstType(String firstType) {
this.firstType = firstType;
}
public void setSecondType(String secondType) {
this.secondType = secondType;
}
public void setType(String type) {
this.type = type;
}
public String getType() {
return type;
}
public String getFirstType() {
return firstType;
}
public String getSecondType() {
return secondType;
}
}
我们来看改造后的方法:
if (entry.getValue()==2){
List<String> listType = type.get(entry.getKey());
String firstType = listType.get(0);
String secondType = listType.get(0);
Chart chart = AddChartEnum.of(firstType, secondType, next.getDate());
iterator.add(chart);
break;
}
非常的Nice,为此在改造if…else…的时候,可以尝试使用策略模式和工厂模式或者枚举的方式代替掉这些if…else…,这样代码看着非常的清爽,是不,超级Nice