您的位置:首页 > 其它

设计模式随笔-策略模式

2016-10-19 16:05 441 查看
概述:

在软件开发中常常遇到这种情况,实现某一个功能有多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能.

eg:  不同的视屏,不同的播放器; 不同的请求,发送请求方式不同,处理不同(HTTP/SOA/THRIFT、SSH);  去哪儿购物,不同出行方式,不同的处理(飞机,火车,汽车)

Bruce Zhang在他的博客中提到策略模式其实是一种“面向接口”的编程方法,真是恰如其分。 

适用场景

直接看图( if else场景多的地方)



直接看图理解更好



举例:

API测试框架中同样的发请求事件,实现发送不同的请求,使用不同的机制来处理, 直接看代码

两个接口

请求接口

public interface IRequest {

IResponse sendRequest(IRequest request);

}


响应接口

public interface IResponse {

void setBody(String body);

String getBody();

void setStatusCode(int code);

int getStatusCode();

String getHeader(String key);

}


请求抽象类

public abstract class AbstractRequestImpl implements IRequest {

private String path ;  //请求路径
private Map<String,Object> headers = new HashMap<>(); //请求头
private String body ; //请求体

public String getPath() {
return path;
}

public void setPath(String path) {
this.path = path;
}

public Map<String, Object> getHeaders() {
return headers;
}

public void setHeaders(Map<String, Object> headers) {
this.headers = headers;
}

public String getBody() {
return body;
}

public void setBody(String body) {
this.body = body;
}

@Override
public abstract IResponse sendRequest(IRequest  request) ;

}


三个不同请求的具体实现

RESTFUL  请求类

public class RestfulRequestImpl extends AbstractRequestImpl {

@Override
public IResponse sendRequest(IRequest request) {
// TODO Auto-generated method stub
System.out.println("发送Restful请求");
return null;
}

}


执行SSH 命令
public class SSHRequestImpl extends AbstractRequestImpl {

private String host;

private String port;

public String getHost() {
return host;
}

public void setHost(String host) {
this.host = host;
}

public String getPort() {
return port;
}

public void setPort(String port) {
this.port = port;
}

@Override
public IResponse sendRequest(IRequest request)  {
System.out.println("发送SSH请求, 返回SSH数据");
return null;
}

}


Thrift 请求

继承抽象类后,可以定义自己不同的属性

public class ThriftRequestImpl extends AbstractRequestImpl{

private String thriftFile;

public String getThriftFile() {
return thriftFile;
}

public ThriftRequestImpl(String thriftFile){
this.thriftFile = thriftFile;
}

@Override
public IResponse sendRequest(IRequest request) {
System.out.println("发送Thrift请求");
ThriftRequestImpl thriftRequest = (ThriftRequestImpl) request;
System.out.println("thrift request file:" + thriftRequest.getThriftFile());
ThriftResponseImpl thrift = new ThriftResponseImpl();
thrift.setThriftFile("thrift response file");
return thrift;
}

}


响应三个具体实现

public class RestfulResponseImpl implements IResponse {

@Override
public void setBody(String body) {
// TODO Auto-generated method stub

}

@Override
public String getBody() {
// TODO Auto-generated method stub
return null;
}

@Override
public void setStatusCode(int code) {
// TODO Auto-generated method stub

}

@Override
public int getStatusCode() {
// TODO Auto-generated method stub
return 0;
}

@Override
public String getHeader(String key) {
// TODO Auto-generated method stub
return null;
}

}


SSH Response 

public class SSHResponseImpl implements IResponse {

@Override
public void setBody(String body) {
// TODO Auto-generated method stub

}

@Override
public String getBody() {
// TODO Auto-generated method stub
return null;
}

@Override
public void setStatusCode(int code) {
// TODO Auto-generated method stub

}

@Override
public int getStatusCode() {
// TODO Auto-generated method stub
return 0;
}

@Override
public String getHeader(String key) {
// TODO Auto-generated method stub
return null;
}

}


Thrift 响应

继承后可以定制独有的属性

public class ThriftResponseImpl implements IResponse {

private String thriftFile;

public String getThriftFile() {
return thriftFile;
}

public void setThriftFile(String thriftFile) {
this.thriftFile = thriftFile;
}

@Override
public void setBody(String body) {
// TODO Auto-generated method stub

}

@Override
public String getBody() {
// TODO Auto-generated method stub
return null;
}

@Override
public void setStatusCode(int code) {
// TODO Auto-generated method stub

}

@Override
public int getStatusCode() {
// TODO Auto-generated method stub
return 0;
}

@Override
public String getHeader(String key) {
// TODO Auto-generated method stub
return null;
}

}


环境角色

/**
* 环境(Context)角色
*/
public class RunRequest {

//持有一个具体的策略对象
private IRequest request;

public IRequest getRequest() {
return request;
}

public void setRequest(IRequest request) {
this.request = request;
}

public IResponse sendRequest(){
return this.request.sendRequest(this.request);
}

}

具体使用场景类

public class Client {

public static void main(String[] args){
RunRequest runRequest = new RunRequest();
//第一种策略
runRequest.setRequest(new RestfulRequestImpl());
runRequest.sendRequest();
//第二种策略
runRequest.setRequest(new ThriftRequestImpl("test"));
ThriftResponseImpl thrift = (ThriftResponseImpl) runRequest.sendRequest();
System.out.println(thrift.getThriftFile());

//第三种策略
runRequest.setRequest(new SSHRequestImpl());
runRequest.sendRequest();

}

}

运行结果:



策略模式,多种不同解决方案动态切换,起到改变对象行为的效果。

关键字驱动的也可以使用策略模式来实现

参考: http://blog.csdn.net/jason0539/article/details/45007553
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: