Bru*_*Kim 14 java design-patterns builder
我想将Web服务URL请求表示为对象,并发现有许多常见参数可以在继承层次结构中"冒泡".一个请求可能有很多参数,一些是必需的,另一些是可选的,我相信Bloch的Builder模式是一个很好的选择,用一个流畅的接口模拟命名参数.
具体来说,我正在设计Google Maps Web服务API,它具有一般的Web服务请求
http://maps.googleapis.com/maps/api/service/output?{parameters}
Run Code Online (Sandbox Code Playgroud)
service
并且output
是必需参数和sensor
必需参数.还有一个可选参数language
.
每个服务都有一组强制和可选参数.地理编码服务有两个可选参数,bounds
和region
.它还具有互斥的强制参数,address
或者location
指定服务类型(分别为直接或反向地理编码).我用新的儿童班来代表这种互斥.
我想象类层次结构如下:
.-----.
| Url |
'-----'
^
|
.---------.
| Request |
'---------'
^
|----------------------------+--------------...
.---------. .------------.
| Geocode | | Directions |
'---------' '------------'
^ ^
|------------+ .
.--------. .---------. .
| Direct | | Reverse | .
'--------' '---------'
Run Code Online (Sandbox Code Playgroud)
然后,我想做类似以下的事情:
String output = "xml";
boolean sensor = true;
String address = "Av. Paulista, São Paulo, Brasil";
Bounds bounds = new Bounds(-20, -10, -25, -20); //Geographic rectangle
String region = "br";
String lang = "pt-BR";
Coord location = new Coord(-12,-22);
DirectGeocodeRequestUrl direct =
new DirectGeocodeRequestUrl.Builder(output, sensor, address)
.bounds(bounds)
.language(lang)
.build();
ReverseGeocodeRequestUrl reverse =
new ReverseGeocodeRequestUrl.Builder(output, sensor, location)
.language(lang)
.region(region)
.build();
Run Code Online (Sandbox Code Playgroud)
如何创建一个使用类和插入它的超类中的参数和方法的构建器?
Bru*_*Kim 18
我正在/sf/answers/639704061/上建立我的答案,但考虑到这个多层次的层次结构.
我们需要的是使用Builder内部类复制相同的层次结构.由于我们需要方法链接,我们需要一个getThis()
返回层次结构的叶对象的方法.为了将其类型向上传递给层次结构,父类具有泛型T
,并且叶子绑定T
到自身.
它确保了类型安全,并避免因未初始化的强制参数或拼写错误而导致的任何异常抛出,以及良好的流畅界面.然而,代表如URL这样简单的结构是一种非常昂贵和复杂的设计.我希望它对某些人有用 - 我最后喜欢字符串连接.
RequestUrl:
public abstract class RequestUrl{
public static abstract class Builder<T extends Builder<T>>{
protected String output;
protected boolean sensor;
//Optional parameters can have default values
protected String lang = "en";
public Builder(String output, boolean sensor){
this.output = output;
this.sensor = sensor;
}
public T lang(String lang){
this.lang = lang;
return getThis();
}
public abstract T getThis();
}
final private String output;
final private boolean sensor;
final private String lang;
protected RequestUrl(Builder builder){
this.output = builder.output;
this.sensor = builder.sensor;
this.lang = builder.lang;
}
// other logic...
}
Run Code Online (Sandbox Code Playgroud)
GeocodeRequestUrl:
public abstract class GeocodeRequestUrl extends RequestUrl {
public static abstract class Builder<T extends Builder<T>>
extends RequestUrl.Builder<Builder<T>>{
protected Bounds bounds;
protected String region = "us";
public Builder(String output, boolean sensor){
super( output, sensor );
}
public T bounds(Bounds bounds){
this.bounds = bounds;
return getThis();
}
public T region(String region){
this.region = region;
return getThis();
}
@Override
public abstract T getThis();
}
final private Bounds bounds;
final private String region;
protected GeocodeRequestUrl(Builder builder){
super (builder);
this.bounds = builder.bounds;
this.region = builder.region;
}
// other logic...
}
Run Code Online (Sandbox Code Playgroud)
DirectGeocodeRequestUrl:
public class DirectGeocodeRequestUrl extends GeocodeRequestUrl {
public static class Builder<Builder>
extends GeocodeRequestUrl.Builder<Builder>{
protected String address;
public Builder(String output, boolean sensor, String address){
super( output, sensor );
this.address = address;
}
@Override
public Builder getThis(){
return this;
}
public DirectGeocodeRequestUrl build(){
return new DirectGeocodeRequestUrl(this);
}
}
final private String address;
protected DirectGeocodeRequestUrl(Builder builder){
super (builder);
this.address = builder.address;
}
// other logic...
}
Run Code Online (Sandbox Code Playgroud)
ReverseGeocodeRequestUrl:
public class ReverseGeocodeRequestUrl extends GeocodeRequestUrl {
public static class Builder<Builder>
extends GeocodeRequestUrl.Builder<Builder>{
protected Coord location;
public Builder(String output, boolean sensor, Coord location){
super( output, sensor );
this.location = location;
}
@Override
public Builder getThis(){
return this;
}
public ReverseGeocodeRequestUrl build(){
return new ReverseGeocodeRequestUrl(this);
}
}
final private Coord location;
protected ReverseGeocodeRequestUrl(Builder builder){
super (builder);
this.location = builder.location;
}
// other logic...
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
8450 次 |
最近记录: |