OO设计-该设计有缺陷吗?

时间:2018-11-18 21:01:34

标签: java oop design-patterns

我正在为Web应用程序创建逻辑来管理用户的同意。

数据库中保留的模型类将具有多个字段,根据用户请求,其中只有一组将被更改。例如班级将有10个字段,并有各种同意,但用户只愿意更改其中2个。为了避免编写大量if-else链,我设计了此类,以利用多态性为我完成工作,但是在某种程度上,这种设计对我来说是有缺陷的。你能告诉我这样做是否合适吗?

问题:仅从类中的大量字段中更改字段子集的值。

为简单起见,我删除了getter / setters方法和一些字段。 更改同意的主要逻辑:

public class GdprServiceImpl implements GdprService {

private final ConsentRepository consentRepository;

@Autowired
public GdprServiceImpl(ConsentRepository consentRepository) {
    this.consentRepository = consentRepository;
}

@Override
public void changeConsent(User user, List<ConsentDto> consents) {
    Optional<Consent> optionalConsent = consentRepository.findByUser(user);
    if(optionalConsent.isPresent()) {
        Consent consent = optionalConsent.get();
        for(ConsentDto consentDto : consents) {
            consentDto.apply(consent);
        }
        consentRepository.save(consent);
    }
    else {
        Consent consent = new Consent();
        consent.setUser(user);
        for(ConsentDto consentDto : consents) {
            consentDto.apply(consent);
        }
        consentRepository.save(consent);
    }
}

模型类:

public class Consent {

    private Boolean messageConsent;
    private Boolean recordConsent;
    /*CONSTRUCTOR, OTHER METHODS AND FIELDS OMITTED*/
}

将更改同意类中的一组字段的类:

public abstract class ConsentDto {

    public abstract void apply(Consent consent);
}



public class RecordConsentDto extends ConsentDto {

   private boolean consentValue;

   public RecordConsentDto(boolean consentValue) {
        this.consentValue = consentValue;
    }

    @Override
    public void apply(Consent consent) {
        consent.setRecordConsent(consentValue);
    }
}



public class MessageConsentDto extends ConsentDto {

    private boolean consentValue;

    public MessageConsentDto(boolean consentValue) {
        this.consentValue = consentValue;
    }

    @Override
    public void apply(Consent consent) {
        consent.setMessageConsent(this.consentValue);
    }
}

2 个答案:

答案 0 :(得分:2)

您对带有“气味”的设计是正确的。
这是因为数据库设计未标准化。
在一条记录中列出同意列表是一种指示。虽然从技术上讲是允许的,但是经典的RDBMS设计要求将数组表示为表之间的一对多或多对多关系。当然,在对象模型中也是如此。

完全规范化的解决方案将具有一个accept_catalog表以及与用户的多对多关系:

table consent_catalog {
  int id // PK
  String name
}

目录充当“同意枚举”,每种同意类型(记录,消息等)都有一行

table user_consents {
  int user_id references users(id)
  int consent_id references consent_catalog(id)
}

此表仅包含用户接受的行。没有“假”同意。这种设计开辟了新的可能性,例如知道哪些用户具有特定的同意或共同同意。

答案 1 :(得分:1)

这种设计感觉有点过分。在一天结束时,您总是在调用consent.setMessageConsent()或类似的名称,它包含一个枚举字段和一个实现ConsumerDto的类(实际上是一个Consumer)。通常,DTO不应实现业务逻辑,但人们可能会说apply方法是一种。

拥有UserConsent个字段的Boolean POJO确实更清洁。唯一的例外是触发一个同意应触发另一个同意,但您的示例尚不清楚。

我只有两美分。我更希望看到传递的是贫乏的POJO或DDD的聚集根,这些根用于管理同意的用户,但两者之间却没有。