设计模式中的六大原则:
1、单一职责原则(Single Responsibility Principle,简称SRP )
2、里氏替换原则(Liskov Substitution Principle,简称LSP)
3、依赖倒置原则(Dependence Inversion Principle,简称DIP)
4、接口隔离原则(Interface Segregation Principle,简称ISP)
5、迪米特法则(Law of Demeter,简称LoD)
6、开放封闭原则(Open Close Principle,简称OCP)
在23中设计模式中,策略模式相对来说,还是很实用的,一般我们会碰到各种的if...else,或者switch..case,写这个时候一般情况下可以会写很多层的if..else,或者switch..case。这样写法能实现基本功能,但是如果碰到需要添加就很痛苦了,比如例子:
public void judgmentType(String type) {
switch (type) {
case "1500":
System.out.println("");
break;
case "1888":
System.out.println("");
break;
case "2100":
System.out.println("");
break;
case "5100":
System.out.println("");
break;
case "2200":
System.out.println("");
break;
case "2280":
System.out.println("");
break;
default:
break;
}
}
这种情况下,如果要添加业务,就得继续添加switch..case,非常不灵活。所以我们通过策略模式来实现对switch..case的处理。
下面代码,就是针对上面的switch..case 进行使用策略模式。
首先不管三七二十一,你先定义一个接口,这个接口就是策略类接口。找出共同的方法,这里定义了一个策略类接口,用来处理具体类的业务功能。
package com.device.state;
/**
* 创建策略类接口
*
* @author Kevin Luo
*
*/
public interface DeviceStatusStrategy {
/**
* 处理状态接口
*
* @param message
* @param deviceInfo
* @param data
* @return
*/
public boolean processingStatus(String message, String deviceInfo, byte[] data);
}
下面定义具体的实现类,用于处理业务,封装了具体的算法或行我。同时,实现策略类接口。
package com.device.resule;
import com.device.state.DeviceStatusStrategy;
/**
* 具体类,实现测试接口
*
* @author Kevin Luo
*
*/
public class resultDID1500 implements DeviceStatusStrategy {
/**
* 实现业务接口
*/
@Override
public boolean processingStatus(String message, String deviceInfo, byte[] data) {
// TODO Auto-generated method stub
System.out.println(message + "1500业务处理......" + deviceInfo);
return true;
}
}
另外一个具体实现类也是一样的事情,定一个具体实现类,用于处理业务。同时,实现策略类接口。其他的也都是一样的,只是类名不同而已,其他就不一一列举了。
package com.device.resule;
import com.device.state.DeviceStatusStrategy;
/**
* 具体类,实现测试接口
*
* @author Kevin Luo
*
*/
public class saveDeviceState2100 implements DeviceStatusStrategy {
/**
* 实现业务接口
*/
@Override
public boolean processingStatus(String message, String deviceInfo, byte[] data) {
// TODO Auto-generated method stub
System.out.println("2100业务处理......");
return true;
}
}
我们来在创建一个Context上下文类,维护一个对Strategy对象的引用。
package com.device.state;
/**
* Context上下文类,维护一个对Strategy对象的引用。
*
* @author Kevin Luo
*
*/
public class DeviceStatusContext {
/**
* 声明一个策略类接口,用于调用具体的实现类
*/
private DeviceStatusStrategy deviceStatusStrategy;
public DeviceStatusContext(DeviceStatusStrategy deviceStatusStrategy) {
this.deviceStatusStrategy = deviceStatusStrategy;
}
/**
* 执行策略类接口,会调用具体的实现类中的方法
*
* @param message
* @param deviceInfo
* @param data
* @return
*/
public boolean executeStrategy(String message, String deviceInfo, byte[] data) {
return deviceStatusStrategy.processingStatus(message, deviceInfo, data);
}
}
最后,做了一个用于初始化上下文的一个类,用于外部调用。
这里面包含了两种实现方式
第一种方式:获取对应的状态码,进行map查询,查询出对应的具体类对象
第二种方式:通过配置文件的形式,获取对应的具体实现类,通过反射获取上下文对象,在进行调用
这种方式,更加的灵活,当需要添加状态的时候,只需要添加对应的状态类,然后在配置文件中添加状态类地址就可以实现增加,非常的灵活,不需要修改内部代码,符合开闭原则。
package com.device.state;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
import com.device.resule.resultDID1500;
import com.device.resule.saveDevcieStateInfo1888;
import com.device.resule.saveDeviceState2100;
import com.device.resule.saveWifiInfo5100;
import com.device.resule.saveWifiState2200;
import com.device.resule.seeWifiStateResult2280;
import com.device.utils.PropertyUtils;
/**
* 具体的调用类
*
* @author Kevin Luo
*
*/
public class ResultHandle {
//创建一个关系型map,用来存储对象,value值为策略类
private static Map mapStrategy = new HashMap();;
//初始化map对象,存储各个需要使用的具体类
static {
mapStrategy.put("1500", new resultDID1500());
mapStrategy.put("2100", new saveDeviceState2100());
mapStrategy.put("5100", new saveWifiInfo5100());
mapStrategy.put("2200", new saveWifiState2200());
mapStrategy.put("2280", new seeWifiStateResult2280());
mapStrategy.put("1888", new saveDevcieStateInfo1888());
}
private DeviceStatusContext deviceStatusContext;
/**
* 第一种方式:获取对应的状态码,进行map查询,查询出对应的具体类对象
*
* @param message
* @param type
* @param data
* @return
*/
public boolean handleDeviceStatusStrategy(String message, String type, byte[] data) {
deviceStatusContext = new DeviceStatusContext(mapStrategy.get(type));
return deviceStatusContext.executeStrategy(message, type, data);
}
/**
* 第二种方式:通过配置文件形式,获取对应的具体实现类,通过反射获取上下文对象,在进行调用
* 这种方式,更加的灵活,当需要添加状态的时候,只需要添加类型,然后在配置文件中添加类地址就可以实现增加
*
* @param message
* @param type
* @param data
* @return
*/
public boolean handleStrategy(String message, String type, byte[] data) {
String value = PropertyUtils.getValue("device" + type);
this.CreateDeviceStateStrategy(value);
return deviceStatusContext.executeStrategy(message, "123123123", data);
}
/**
* 将具体类的对象地址通过反射生成上下文对象
*
* @param type
*/
public void CreateDeviceStateStrategy(String type) {
Class clz;
try {
clz = Class.forName(type);
Constructor> constructor = clz.getConstructor();
DeviceStatusStrategy deviceStatusStrategy = (DeviceStatusStrategy) constructor.newInstance(null);
deviceStatusContext = new DeviceStatusContext(deviceStatusStrategy);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
这个是配置类,在deviceState.properties文件中配置对应的具体类地址。用于通过反射时获取上下文的对象。
device1500 = com.device.resule.resultDID1500
device2100 = com.device.resule.saveDeviceState2100
device5100 = com.device.resule.saveWifiInfo5100
device2200 = com.device.resule.saveWifiState2200
device2280 = com.device.resule.seeWifiStateResult2280
device1888 = com.device.resule.saveDevcieStateInfo1888
下来开始测试类,第一种方式以及第二种方式也都能正常的运行成功。
package com.device.test;
import com.device.state.ResultHandle;
public class DeviceStateTest {
public static void main(String[] args) {
ResultHandle rh = new ResultHandle();
//第一种方式,运行成功
rh.handleDeviceStatusStrategy("1111111", "1500", new byte[0]);
//第二种方式,也运行成功
rh.handleStrategy("1111111", "2100", new byte[0]);
}
}
源码地址:
https://download.csdn.net/download/qq_19348391/10804100
小伙伴们有什么好的建议,欢迎在底下留言。