我正在与许多社交网络连接以登录我的应用程序。每个社交网络响应都有一个DTO。
public class GoogleUserInfo {
private String id;
private String firstName;
private String lastName;
private String email;
private AgeRange ageRange;
// more specific fields
}
public class FacebookUserInfo {
private String id;
private String firstName;
private String lastName;
private String email;
private String picture;
// more specific fields
}
public class AppleUserInfo {
private String id;
private String firstName;
private String lastName;
private String email;
private Boolean emailVerified;
// more specific fields
}
[在每个社交网络连接器中,我都采取类似的步骤来获取信息,所以我认为我可以按照以下方式使用一些DTO:
public class SocialNetworkInfo {
protected String id;
protected String firstName;
protected String lastName;
protected String email;
}
社交网络DTO可以对此进行扩展以获得公共字段。然后,我可以使用此通用DTO来实现一个抽象连接器,该连接器处理连接器之间的所有重复逻辑(生成请求,解析响应等):
abstract class AbstractConnector {
abstract SocialNetworkInfo fetchUserInfo(String networkId);
...
}
但是我意识到,在服务层中,我需要那些特定的字段来进行一些更改和操作。
SocialNetworkInfo networkUserInfo = facebookConnector.fetchUserInfo(facebookId);
facebookService.updatePicture(networkUserInfo.getPicture()); // can't access this specific field
您认为这是在不进行强制转换并避免逻辑或DTO重复的情况下解决此问题的最佳方法?
很想听听您的想法。
谢谢!
根据您的情况,所有社交网络模型都具有相同的性质,因此,如果将公共属性移到CommonSocialInfo
之类的共享类中就可以了。然后,我建议为连接器提供接口,例如:
interface SocialNetworkConnector<T extends SocialNetworkInfo> {
T fetchUserInfo(String userId);
}
当然,对于常用功能(用于连接器),最好定义实现以上接口的通用抽象类(实现模板模式)。我看到您正在分别使用FacebookService
和相关的连接器。我认为在这种情况下使用合成并使SocialNetworkService依赖于它的连接器是个好主意。简而言之,FacebookService依赖于FacebookConnecter等。只是一个简单的例子:
public class FacebookService implements SocialNetworkService {
private final SocialNetworkConnector<FacebookSocialInfo> connector;
...
}
并且如果您需要实施多种社交服务,则可以使用Factory模式来生成所需的服务,快速示例:
interface SocialNetworkServiceFactory {
SocialNetworkService getFacebookService();
...
}
如果您需要更详细的帮助,或者在理解此主意时遇到麻烦,请随时提问!