开发中常见的场景
- JavaSE中GUI编程中的布局管理
-
Spring框架中,Resource接口,资源访问策略
-
javax.servlet.http.HttpServlet#service()
场景
-
某个市场人员接到单后的报价策略(CRM系统中常见问题),报价策略很复杂,可以简单作如下分类:
- 普通客户小批量的报价
-
普通客户大批量的报价
-
老客户小批量的报价
-
老客户大批量的报价
-
具体选用那个报价策略,这需要根据实际情况来确定.这时候,我们采用策略模式即可
-
使用条件语句也可以处理,但是如果类型特别多,算法比较复杂时,整个条件控制代码会变得很长,难于维护
使用策略模式
策略模式对应于解决某一个问题的一个算法族,允许用户从该算法族中任选一个算法解决某一问题,同时可以方便的更换算法或者增加新的算法.并且由客户端决定调用那个算法
类图
本质
分离算法,选择实现
Code
/**
* 策略接口
* @author Matrix42
*
*/
public interface Strategy {
public double getPrice(double standaPrice);
}
/**
* 普通客户少量
* @author Matrix42
*
*/
public class NewCustomerFewStrategy implements Strategy{
@Override
public double getPrice(double standaPrice) {
System.out.println("不打折!");
return standaPrice;
}
}
/**
* 普通客户大量
* @author Matrix42
*
*/
public class NewCustomerManyStrategy implements Strategy{
@Override
public double getPrice(double standaPrice) {
System.out.println("打九折!");
return standaPrice*0.9;
}
}
/**
* 老客户少量
* @author Matrix42
*
*/
public class OldCustomerFewStrategy implements Strategy{
@Override
public double getPrice(double standaPrice) {
System.out.println("打八五折!");
return standaPrice*0.85;
}
}
/**
* 老客户大量
* @author Matrix42
*
*/
public class OldCustomerManyStrategy implements Strategy{
@Override
public double getPrice(double standaPrice) {
System.out.println("打八折!");
return standaPrice*0.8;
}
}
/**
* 负责和具体的策略类交互
* 这样的话,具体的算法和直接的客户端调用分离了,使得算法可以独立于客户端独立额变化
* 如果使用spring的依赖注入功能,还可以通过配置文件,动态的切换不同的算法
* @author Matrix42
*
*/
public class Context {
//当前采用的算法对象
private Strategy strategy;
public Context(Strategy strategy) {
super();
this.strategy = strategy;
}
public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}
public void printPrice(double s){
System.out.println("您的报价:"+strategy.getPrice(s));
}
}
public class Client {
public static void main(String[] args) {
Strategy strategy = new OldCustomerFewStrategy();
Context ctx = new Context(strategy);
ctx.printPrice(998);
}
}
我在项目中用到的一个时间转换类
public class DateToTimestamp implements Serializable {
private static final long serialVersionUID = 1L;
public static void main(String[] args) {
String time0 = "2016-11-19 12:28:12";
String time1 = "2016-11-19 12:28:12.342412";
String time2 = "2016-11-19";
String time3 = "12:00:50.3";
String time4 = "00:50.3";
String time5 = "12:00:50";
DateToTimestamp dt = new DateToTimestamp();
System.out.println("time:" +dt.call(time0,"yyyyMMddHHmm"));
System.out.println("time:" + dt.call(time1,2));
System.out.println("time:" + dt.call(time2,0));
System.out.println("time:" + dt.call(time3,1));
System.out.println("time:" + dt.call(time4,0));
System.out.println("time:" + dt.call(time5,1));
}
abstract class Algo {
protected String timeString;
protected SimpleDateFormat format;
protected long time = 0L;
public void setTimeString(String timeString) {
this.timeString = timeString;
}
public void setFormat(SimpleDateFormat format) {
this.format = format;
}
abstract long getTime();
}
class Match {
private String timeString;
private Pattern pattern;
private Matcher matcher;
private Algo algo;
public Match(String timeString, Pattern pattern,SimpleDateFormat format, Algo algo) {
this.timeString = timeString.trim();
algo.setTimeString(timeString.trim());
this.pattern = pattern;
algo.setFormat(format);
this.algo = algo;
}
public boolean isMatch() {
matcher = pattern.matcher(timeString);
return matcher.matches();
}
public long getTime() {
return algo.getTime();
}
}
/**
* 自定义日期格式
* @param timeString
* @param formatString
* @return formated time
*/
public Long call(String timeString,String formatString){
SimpleDateFormat format = new SimpleDateFormat(formatString);
String string = format.format(call(timeString,0));
return Long.parseLong(string);
}
/**
* 日期转换成毫秒
* @param timeString
* @return
*/
public Long call(String timeString,final int length) {
List<Match> mList = new ArrayList<Match>();
// 匹配 年-月-日 时:分:秒.毫秒
Pattern p1 = Pattern
.compile("\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}(\\.\\d+)?");
SimpleDateFormat f1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Match m1 = new Match(timeString, p1, f1, new Algo() {
@Override
long getTime() {
String[] times = timeString.split("\\.");
try {
time += format.parse(times[0]).getTime();
} catch (ParseException e) {
e.printStackTrace();
}
if (times.length == 2 && length!=0) {
int msLength = times[1].length();
if (msLength >= length) {
time += Long.parseLong(times[1].substring(0, length))*Math.pow(10, msLength-length);
} else {
time += Long.parseLong(times[1].substring(0, msLength));
}
}
return time;
}
});
mList.add(m1);
// 匹配 年-月-日
Pattern p2 = Pattern.compile("\\d{4}-\\d{2}-\\d{2}");
SimpleDateFormat f2 = new SimpleDateFormat("yyyy-MM-dd");
Match m2 = new Match(timeString, p2, f2, new Algo() {
@Override
long getTime() {
try {
time = format.parse(timeString).getTime();
} catch (ParseException e) {
e.printStackTrace();
}
return time;
}
});
mList.add(m2);
// 匹配 时:分:秒.毫秒
Pattern p3 = Pattern.compile("\\d{2}:\\d{2}:\\d{2}(\\.\\d*)?");
SimpleDateFormat f3 = new SimpleDateFormat("HH:mm:ss");
Match m3 = new Match(timeString, p3, f3, new Algo() {
@Override
long getTime() {
String[] times = timeString.split("[:.]");
time += Long.parseLong(times[0]) * 60 * 60 * 1000;
time += Long.parseLong(times[1]) * 60 * 1000;
time += Long.parseLong(times[2]) * 1000;
if (times.length == 4 && length != 0) {
int msLength = times[3].length();
if (msLength >= length && length!=0) {
time += Long.parseLong(times[3].substring(0, length))*Math.pow(10, msLength-length);
} else {
time += Long.parseLong(times[3].substring(0, msLength));
}
}
return time;
}
});
mList.add(m3);
// 匹配 分:秒.毫秒
Pattern p4 = Pattern.compile("\\d{2}:\\d{2}(\\.\\d*)?");
SimpleDateFormat f4 = new SimpleDateFormat("mm:ss");
Match m4 = new Match(timeString, p4, f4, new Algo() {
@Override
long getTime() {
String[] times = timeString.split("[:.]");
time += Long.parseLong(times[0]) * 60 * 1000;
time += Long.parseLong(times[1]) * 1000;
if (times.length == 3 && length!=0) {
int msLength = times[2].length();
if (msLength >= length) {
time += Long.parseLong(times[2].substring(0, length))*Math.pow(10, msLength-length);
} else {
time += Long.parseLong(times[2].substring(0, msLength));
}
}
return time;
}
});
mList.add(m4);
for (Match match : mList) {
if (match.isMatch()) {
return match.getTime();
}
}
throw new RuntimeException("时间格式不匹配!");
}
public Long call() {
return 0001L;
}
}