我们正在实施一个具有战略模式的系统。
某些特定方法的调用者需要数据的Hashmap,而在某些情况下,它将是用户定义的DTO。有些人需要两者。
我们如何决定使用哪种返回类型,而不是包含Hashmap和DTO的Arraylist?还有更适合的吗?
示例:
某些调用者只需要2个字符串,并且更喜欢Hashmap。
同一API的其他一些调用者需要12个适合放入DTO的值。第一个调用者不需要DTO中的所有元素。
第三个调用者需要所有14个值,因此需要两个结构。
答案 0 :(得分:10)
如果某些呼叫者需要Map
(BTW不要在接口中使用HashMap
等具体类型)而其他人需要使用对象,则可能有两个原因:
该方法根据参数返回完全不同的东西(例如如果设置了标志,则返回特权映射,如果不是,则返回表示用户自己的对象)
您要返回同一实体的不同视图
在第一种情况下,您的界面存在严重缺陷,应重新设计。可能你需要两种执行不同任务的方法。你是什么意思“不同的来电者”?根据谁调用该方法,您决定返回什么?
在第二种情况下,考虑一个更通用的模型并将其返回。然后让客户端将其转换为适当的格式。有几种方法可以做到这一点:
返回格式不可知类型,并提供转换为map和object的方法,以便客户端可以决定。例如,如果您不确定客户端是否更喜欢具有属性的弱类型映射或具有相同属性/字段的强类型对象,请返回具有toMap
和toObject
方法的简单包装器。请注意,在这种情况下,内部表示并不重要,客户端始终使用视图,您可以随时添加新格式
返回具有两个子类的通用Model
类:MapModel
和ObjectModel
,在子类中公开适当的getter。 不使用instanceof
而不是访问者模式。在此模型中,您始终返回单个值,客户端必须能够处理每种格式。如果添加新格式(如XmlModel
),则需要自定义使用Model
的所有位置以处理新类型。但是,在这种情况下,您无需将内部表示转换为不同的格式。
请注意,返回Object
或其中的任何变体只是在动态语言中登陆,您不再需要任何静态输入帮助。
答案 1 :(得分:1)
使用getter和setter创建一个数据类并返回相同的Object ..
答案 2 :(得分:1)
我将创建一个特定于策略的返回类型类,它封装了两个选项以提供一个清除类型的接口,而不是在整个实现代码中处理Object instanceof / casts。在我看来,一小部分样板是可以接受的:
SomeClass {
private final Map values;
private final Object dto;
SomeClass(Map values, Object dto) {
...
}
<D> D getDTO(Class<D> dtoType);
Map getMap();..
}
如果你事先知道DTO类型,那么返回类型也是通用的(你不应该,这意味着你做出了糟糕的设计选择)
答案 3 :(得分:0)
为什么不简单地返回一个Object。理想情况下,我会将其作为最后一个选项。但你可以考虑返回一个通用的
public Object myMethod1(){}
public T myMethod2(){}
在第二种情况下,很明显您可能必须定义通用对象。
答案 4 :(得分:0)
仿制药怎么样?
public <T> T getPojo(final Object o, final Class<T> returnType)
{
if (o instanceof HashMap)
{
return (T) getPojoHash((HashMap) o);
}
return (T) getPojoDTO((DTO) o);
}
private HashMap getPojoHash(final HashMap map)
{ // mount map
return newMap;
}
private DTO getPojoDTO(final DTO d)
{ // mount dto
return newDTO;
}
您可以使用反射来避免returnType
参数。但我更喜欢打字。
答案 5 :(得分:0)
假设您正在返回Generic类型并且列表可以是异构的,返回对ArrayList的引用并不是一个坏主意。您可以将所有内容封装在另一个类中,但最后,您需要在某处保留某种列表。
答案 6 :(得分:0)
您可以使用泛型,但是您需要同时返回两个内容时存在问题。最好的解决方案是创建一个包含两种返回类型的类,并简单地使用泛型来创建一个返回所需内容的方法:
public <T extends SomeReturnObject> List<T> doSomething(Object someObject, Class<T> classToReturn) {
// Do something here
}
答案 7 :(得分:0)
如果没有关于您的方法的更多信息,我会尝试使用提供所需方法的界面。然后你可以为HashMap
提供一个包装器,你的DTO可以直接实现该接口,你也可以有一个包含HashMap
和DTO的包装器。
只要提供了所需的方法,调用者就不应该真正知道返回的内容。
答案 8 :(得分:0)
我认为最简单的解决方案是在您的 Strategy 接口上放置 2 个方法,每个返回类型一个。
public interface Strategy {
Map<String, String> executeReturningMap();
DTO executeReturningDTO();
}
然后调用者可以通过调用适当的方法为自己选择他们想要的返回类型。
不用大惊小怪,只是背离了一个策略只能有一种方法的纯粹思想。