注意:请忽略我对
MultivaluedMap
而不是多个变量
字符串…ARGS
.
在Java中有标准的方法吗?
我拥有的是一个从远程服务器返回的资源。但是在每次查询之前,远程连接必须打开,并且在返回之后-必须关闭。
因此,这样做的一种自然方式是:
Connection c = config.configureConnection();
c.open(); //open
List<Car> cars;
try{
cars = c.getCars();
}finally{
c.close(); //close
}
现在,我想实现一些在资源本身级别上运行的东西,而不必担心连接,例如:
List<Car> cars = new CarResource().all(); //opens and closes connection
我目前的做法是用一个抽象类,
可提取的
调用抽象方法
查询(字符串…参数)
和
查询(int id)
,任何扩展它的类都必须实现。
抽象可实现
可查询的
接口,使其公开三个公共方法
筛选器(字符串…参数)
,
()
和
获取(int id)
-这是面向公众的方法。
这里是可查询的接口:
public interface Queriable <T>{
public T get(String id);
/** Simply returns all resources */
public Collection<T> all();
public Collection<T> filter(MultivaluedMap<String, String> args);
}
下面是实现它的可抽象类:
public abstract class AbstractQueriable<T> implements Queriable<T> {
@Override
public final T get(String id) {
setup();
try {
return query(id);
} finally {
cleanup();
}
}
@Override
public final Collection<T> filter(MultivaluedMap<String, String> args) {
setup();
try {
return query(args);
} finally {
cleanup();
}
}
/**
* Returns all resources.
*
* This is a convenience method that is equivalent to passing an empty
* arguments list to the filter function.
*
* @return The collection of all resources if possible
*/
@Override
public final Collection<T> all() {
return filter(null);
}
/**
* Queries for a resource by id.
*
* @param id
* id of the resource to return
* @return
*/
protected abstract T query(String id);
/**
* Queries for a resource by given arguments.
*
* @param args
* Map of arguments, where each key is the argument name, and the
* corresponing values are the values
* @return The collection of resources found
*/
protected abstract Collection<T> query(MultivaluedMap<String, String> args);
private void cleanup() {
Repository.close();
}
private void setup() {
Repository.open();
}
最后,我希望在代码中使用的资源必须扩展抽象类,例如(请注意,这些方法的细节并不重要):
public class CarRepositoryResource extends AbstractQueriable<Car> {
@Override
protected Car query(String id) {
MultivaluedMap<String, String> params = new MultivaluedMapImpl();
params.add("CarID", id);
// Delegate the query to the parametarized version
Collection<cars> cars = query(params);
if (cars == null || cars.size() == 0) {
throw new WebApplicationException(Response.Status.NOT_FOUND);
}
if (cars.size() > 1) {
throw new WebApplicationException(Response.Status.NOT_FOUND);
}
return cars.iterator().next();
}
@Override
protected Collection<Car> query(MultivaluedMap<String, String> params) {
Collection<Car> cars = new ArrayList<Car>();
Response response = Repository.getConnection().doQuery("Car");
while (response.next()) {
Returned returned = response.getResult();
if (returned != null) {
cars.add(returned);
}
}
return cars;
}
}
最后,我可以在代码中使用:
Collection<Car> cars = new CarRepositoryResource().all();
//... display cars to the client etc...
这种设置有一些我不喜欢的地方:
-
每次执行查询时,必须实例化“carrepositoryresource”的新实例。
-
方法名“query”虽然是内部的和私有的,但仍然令人困惑和笨拙。
-
我不确定是否存在更好的模式或框架。
我使用的连接不支持/实现JDBC API,也不基于SQL。