Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用装饰图案而不添加;不同的;行为_Java_Design Patterns_Decorator - Fatal编程技术网

Java 使用装饰图案而不添加;不同的;行为

Java 使用装饰图案而不添加;不同的;行为,java,design-patterns,decorator,Java,Design Patterns,Decorator,我有一个facade界面,用户可以在其中询问关于工程师的信息。这些信息应该作为JSON传输,我们为其制作了DTO。现在请记住,我有多个数据源可以为这个DTO列表提供一个项 所以我现在相信,我可以通过将数据源的处理程序添加到类型的列表的myEngineerListDTO中来使用装饰图案。所以我的意思是所有的数据源都有相同的DTO 下图显示垂直滚动条和水平滚动条添加了不同的行为。这意味着他们将行为添加到WindowDecorator界面。 我的问题是,我的情况是否符合装饰者的模式?我是否特别需要添

我有一个facade界面,用户可以在其中询问关于工程师的信息。这些信息应该作为JSON传输,我们为其制作了DTO。现在请记住,我有多个数据源可以为这个DTO列表提供一个项

所以我现在相信,我可以通过将数据源的处理程序添加到
类型的
列表的
myEngineerListDTO
中来使用装饰图案。所以我的意思是所有的数据源都有相同的DTO

下图显示垂直滚动条和水平滚动条添加了不同的行为。这意味着他们将行为添加到WindowDecorator界面。

我的问题是,我的情况是否符合装饰者的模式?我是否特别需要添加一个行为来使用此模式?还有其他模式适合我的情况吗?我已经考虑过责任链模式,但因为我不需要在任何时候终止我的责任链,所以我认为装饰者模式可能会更好

编辑: 我的最终结果应该是:
List
来自所有数据源。我想添加此模式的原因是,我可以轻松地在“管道”的其余部分后面添加另一个数据源。与其他数据源一样,此数据源将具有
addEngineersDTOToList
方法

来进一步说明我如何组合一个小示例。我相信您应该能够调整此解决方案,以适应现实世界问题的需要


问题空间 我们有一组未知的用户请求,其中包含要检索的属性的名称。有多个数据源,每个数据源具有不同数量的属性。我们希望搜索所有可能的数据源,直到发现请求中的所有属性。某些数据类型和数据源可能如下所示(注意,为了简洁起见,我使用了):

@lombok.Data
FooBarData类{
私人最终字符串foo;
私人最终字符串栏;
}
@龙目数据
类数据{
私人最终弦乐嘶嘶作响;
私人最终字符串嗡嗡声;
}
类FooBarService{
公共foobardatainvoke(){
System.out.println(“这是一个昂贵的FooBar调用”);
返回新的FooBarData(“FOO”、“BAR”);
}
}
班级服务{
公共FizzBuzzData调用(){
System.out.println(“这是一个昂贵的FizzBuzz电话”);
返回新的fizzbuzz数据(“FIZZ”、“BUZZ”);
}
}
我们的最终用户可能需要多种方法来解析数据。以下可能是有效的用户输入和预期响应:

//输入
“foobar”、“foo”、“fizz”
//输出
{
“foobar”:{
“foo”:“foo”,
“酒吧”:“酒吧”
},
“foo”:“foo”,
“嘶嘶声”:“嘶嘶声”
}
我们的属性解析器的基本接口和简单具体实现可能如下所示:

接口属性Resolver{
映射解析(列表属性);
}
类UnknownResolver实现PropertyResolver{
@凌驾
公共地图解析(列表属性){
映射结果=新的HashMap();
用于(字符串属性:属性){
结果.出售(财产,“未知”);
}
返回结果;
}
}
解空间 与使用普通的“装饰者模式”不同,更好的解决方案可能是“责任链模式”。此模式类似于decorator模式,但是,链中的每个链接都可以处理项、忽略项或结束执行。这有助于确定是否需要进行调用,或者如果请求的工作已完成,则终止链。与decorator模式的另一个区别是,
resolve
不会被每个具体类覆盖;我们的抽象类可以在需要时使用抽象方法调用子类

回到手头的问题上来。。。对于每个解析器,我们需要两个组件。一种从远程服务获取数据的方法,以及一种从检索到的数据中提取所有必需属性的方法。对于获取数据,我们可以提供一个抽象方法。为了从提取的数据中提取属性,我们可以制作一个小界面,并维护这些提取器的列表,因为可以从一段数据中提取多个属性:

接口属性抽取器{
对象提取(数据);
}
抽象类PropertyResolverCain实现PropertyResolver{
私有最终映射提取器=新HashMap();
私人最终财产所有者继承人;
受保护财产ResolverCain(财产Resolver继承人){
这个后继者=后继者;
}
受保护的抽象数据getData();
受保护的最终无效设置绑定(字符串属性、PropertyExtractor提取器){
提取器。put(属性,提取器);
}
@凌驾
公共地图解析(列表属性){
...
}
}
resolve
方法的基本思想是首先评估该
PropertyResolver
实例可以实现哪些
属性。如果有符合条件的属性,那么我们将使用
getData
获取数据。对于每个符合条件的属性,我们提取属性值并将其添加到结果映射中。对于无法解析的每个属性,将请求后续属性解析该属性。如果所有属性都已解析,则执行链将结束

@覆盖
公共地图解析(列表属性){
映射结果=新的HashMap();
List eligibleProperties=新建ArrayList(属性);
retainAll(提取器.keySet());
如果(!eligibleProperties.isEmpty()){
Data=getData();
对于(字符串属性:eligibleProperties){
put(属性,提取器.get(属性).extract(数据));
}
}
List remainingProperties=new ArrayList(属性);
剩余属性