【问题标题】:What approach to take to make my code more generic Java/ Spring?采取什么方法使我的代码更通用 Java/Spring?
【发布时间】:2019-12-27 16:51:32
【问题描述】:

SpringBoot 应用程序中,我有一个服务(在 Spring 意义上)调用客户端,这些客户端通过调用与createXXX 相同的函数来使用 RestFul Web 服务,只是对象的性质在输入处发生了变化的方法。 为简化起见,假设我对动物的创建进行建模:将对象 CatDTODogDTOHorseDTO 作为 Web 服务的输入。 AnimaslDTO是由不同种类的动物组成的对象(没有继承关系)。

我用同样的方法做三个客户端我们以猫为例

package com.animals.client;
import ...

@Service
public class CatClient {

    private static final String CODE_WS_CREATE_CAT = "createCat";
    /**
     * Call RestFul WS for Cat Creation
     * @param catDTO
     */
    public ResponseEntity<String> createCat(CatDTO catDTO)
    {
        // ... Call a RestFul WS in the same manner for each animal. Only the parameter change in each client
        // --> ie dogDTO in DogClient.createDog, HorseDTO in HorseClient.createHorse,
    }
}

AnimalServiceImpl实现的AnimalService中,我尝试创建三个动物 这是代码

package com.animals.service.impl;

import ...

@Service
public class AnimalServiceImpl implements AnimalService {

    @Autowired
    private CatClient catClient;

    @Autowired
    private DogClient dogClient;

    @Autowired
    private HorseClient horseClient;

    @Override
    public ResponseEntity<String> createAnimals(AnimalsDTO animalsDTO) {
        catClient.createCat(animalsDTO.getCat());
        dogClient.createDog(animalsDTO.getDog());
        horseClient.createHorse(animalsDTO.getHorse());
        .... 
    }
}

我想知道如何在 Spring 或 Java 中为我的客户端生成与createXXX 非常相似的方法。我可以使用什么设计模式?我尝试过的是使用 Java 泛型,但它不适合 Spring。我试图创建一个 AnimalClient(T) 类,其中 T 是动物,但我在使用一个参数自动装配构造函数时遇到问题。

提前致谢!

【问题讨论】:

  • 可以添加 AnimalsDTO 吗?还有一个来自 CatDTO 或 DogDTO?
  • 我认为泛型在这里工作得很好。不过,你看过工厂还是适配器?
  • @MehulGayate 我采用“动物”案例来简化我的用例并使其更易于理解。实际上,我使用许多复合对象
  • @askappy 我遇到的泛型问题如下: 好的,我创建了 AnimalClient ,因此实例化泛型类型 T 的唯一方法是在一个参数构造函数中定义它。但是当我在 AnimalServiceImpl 中定义我的三个“真正的动物”客户端组件时,我无法自动装配三个构造函数 AnimalClient AnimalClient, AnimalClient 因为这三个构造函数会发生冲突。 Perharps 有一个聪明的方法可以用 Spring 来做,但我不知道。对于我来说,工厂设计模式似乎很复杂

标签: java spring generics design-patterns autowired


【解决方案1】:

除非您有Inheritance,否则即使您尝试使用Generics,也无法有效解决此问题

这是简化代码的一种方法:

BaseAnimalDto 目前是一个标记接口。如果你愿意,你可以在这里使用常用的方法。

public interface BaseAnimalDTO {

}

CatDTO

public class CatDTO implements BaseAnimalDTO {
    // Cat DTO code
}

如下创建BaseAnimalClient

public interface BaseAnimalClient {

    ResponseEntity<String> create(BaseAnimalDTO dto);
}

CatClient 看起来像这样

@Service
public class CatClient implements BaseAnimalClient {

    private static final String CODE_WS_CREATE_CAT = "createCat";

    @Override
    public ResponseEntity<String> create(BaseAnimalDTO dto) {
        return null;
    }
}

让我们像这样创建一个通用的AnimalClient

@Service
public class AnimalClient implements BaseAnimalClient {

    @Autowired
    private CatClient catClient;

    @Autowired
    private DogClient dogClient;

    @Autowired
    private HorseClient horseClient;

    @Override
    public ResponseEntity<String> create(BaseAnimalDTO dto) {
        BaseAnimalClient client;
        if (dto instanceof CatDTO) {
            client = catClient;
        } else if (dto instanceof DogDTO) {
            client = dogClient;
        } else {
            client = horseClient;
        }
        return client.create(dto);
    }
}

现在,您的 AnimalServiceImpl 看起来像这样

@Service
public class AnimalServiceImpl implements AnimalService {

    @Autowired
    private AnimalClient animalClient;

    @Override
    public ResponseEntity<String> createAnimals(AnimalsDTO animalsDTO) {
        animalClient.create(animalsDTO.getCat());
        animalClient.create(animalsDTO.getDog());
        animalClient.create(animalsDTO.getHorse());
        .... 
    }
}

但是,如果您可以像这样修改您的AnimalsDTO

public class AnimalsDTO {

    private List<? extends BaseAnimalDTO> animalDtos;

    // getter, setters

}

然后,您的AnimalServiceImpl 将更加简化,如下所示:

@Service
public class AnimalServiceImpl implements AnimalService {

    @Autowired
    private AnimalClient animalClient;

    @Override
    public ResponseEntity<String> createAnimals(AnimalsDTO animalsDTO) {
        for (BaseAnimalDTO animalDTO : animalsDTO.getAnimalDtos()) {
            animalClient.create(animalDTO);
        }
        ....
    }
}

【讨论】:

  • 很好!这是一种简单明了的方法,正是我正在寻找的方法。非常感谢
  • 很高兴它有帮助。如果它解决了您的问题,请标记答案。谢谢
猜你喜欢
  • 2010-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-11
相关资源
最近更新 更多