首页 > 解决方案 > 用于转换 Java 对象字段的设计模式

问题描述

我有一堂课:

@Getter
@Setter
public class Message {

  private String sender;

  private Set<String> receivers;

  private String text;

}

该类Message可以通过EmailMessageSMSMessage具有自己的附加字段进行扩展。

有 2 种服务 - EmailService 和 SMSService。它们都执行以下操作:

  1. 获取包含发送者和接收者用户 ID 的消息对象。
  2. EmailService 调用另一个服务来将用户 ID 转换为电子邮件 ID。SMSService 也将用户 ID 转换为电话号码。
  3. Message 对象应在其各自的服务中转换为 EmailMessage 和 SMSSMEssage。
  4. 发送 EmailMessage 和 SMSMessage。

我一直在经历许多设计模式来解决这个问题。但是我没有找到任何这样的模式来转换对象的字段和/或将父对象转换为子对象。
唯一接近的设计模式是策略和装饰器。
我正在使用策略模式在运行时使用 EmailService 或 SMSService。它只是解决了我问题的一部分。装饰器模式是否有助于解决其他问题?

编辑:添加当前实现

public abstract class AbstractMessageService<T extends Message> {

  @KafkaHandler(isDefault = true)  
  public final void consume(Message message) {  
    T convertedMessage = getMessageConverterStrategy().convert(message);
    send(convertedNotificationMessage);
  }

  protected abstract void send(T message) throws Exception;

  protected abstract MessageConverterStrategy getMessageConverterStrategy();  

}
@KafkaListener(
    topics = "topicName",
    groupId = "email-group")
public class EmailService extends AbstractMessageService<EmailMessage> {

  @Override
  protected void send(EmailMessage message) {
    // Some logic to send email.
  }

  @Override
  protected MessageConverterStrategy getMessageConverterStrategy() {
    return new EmailMessageConverterStrategy();
  }  

}
@KafkaListener(
    topics = "topicName",
    groupId = "sms-group")
public class SMSService extends AbstractMessageService<SMSMessage> {

  @Override
  protected void send(SMSMessage message) {
    // Some logic to send sms.
  }

  @Override
  protected MessageConverterStrategy getMessageConverterStrategy() {
    return new SMSMessageConverterStrategy();
  }  

}
public interface MessageConverterStrategy<T extends Message> {

  T convert(Message message);

}

在 SMSMessageConverterStrategy 和 EmailMessageConverterStrategy 中,我想使用其他设计模式分别将 Message 转换为 SMSMessage 和 EmailMessage。

标签: javadesign-patterns

解决方案


因为你必须转换几乎所有东西,我认为MessageEmailSMS不相关。我认为你应该使用这样的工厂方法:

public class Test {
    public static void main(String[] args) throws Exception {
        Message m = new Message();
        Email email = Email.from(m);
        EmailService.sendMail(email);
    }
}

class Message {
      private String sender;
      private Set<String> receivers;
      private String text;
}

class Email {
    private String senderMailId;
    private String text;
    private Set<String> receiverMailIds;

    //make it private
    private Email() {

    }
    
    public static Email from(Message m) {
        Email email = new Email();
        email.senderMailId = ""; //call MappingService.toEmailId(m.getSender());
        //do rest of the conversion and processing
        return email;
    }
}

class EmailService {
    public static void sendMail(Email e) {
        //send the mail
    }
}

推荐阅读