java - 我可以在服务 bean 中拥有公共(public)静态字段吗?

标签 java spring oop

我对这段代码有点怀疑,因为它有点违反了 YAGNI。我的服务类需要一些公共(public)静态字段,但当您的服务 bean 中有这些字段时,通常这是一个糟糕的设计,因此我为该服务创建了一个接口(interface),但我不确定这是正确的选择。我应该在服务类中包含这些字段吗?

public interface IYouTubeServiceBuild {
    /**
     * Define a global instance of the HTTP transport.
     */
    public static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
    /**
     * Define a global instance of the JSON factory.
     */
    public static final JsonFactory JSON_FACTORY = new JacksonFactory();
    /**
     * Define a global variable that identifies the name of a file that
     * contains the developer's API key.
     */
    public static final String PROPERTIES_FILENAME = "youtube.properties";
}
@Service
@Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
public class YouTubeServiceBuild implements IYouTubeServiceBuild {
    @Getter
    private Properties properties;

    /**
     * Define a global instance of a Youtube object, which will be used
     * to make YouTube Data API requests.
     */
    @Getter
    private YouTube youtube;

    @PostConstruct
    public void init() {
        properties = new Properties();
        youtube = new YouTube.Builder(HTTP_TRANSPORT, JSON_FACTORY, request -> {
        }).setApplicationName("youtube-search-demo").build();
        //etc...
        }
    }
}

上述服务类然后在其他服务中使用,如下所示:

@Service
public class YouTubeApiService {
    @Autowired
    private YouTubeServiceBuild serviceBuild;

    public List<SearchResult> searchYouTube(String searchQuery) {
        List<SearchResult> searchResults =
                executeSearch(searchQuery, serviceBuild.getProperties(), serviceBuild.getYoutube());
        //etc...
    }

最佳答案

如果问题是是否可以在 Spring 托管 bean 中设置公共(public)静态字段 - 那么是的,它是可能的,尽管我完全同意你的观点,认为这是一个糟糕的设计。

不考虑 spring,将常量放入接口(interface)中以便接口(interface)的实现能够访问它们被认为是代码味道,因为所有实现(假设有很多)现在可以表现不同,因为一些常量发生变化,或者更糟糕的是 - 如果删除常量,将不再编译(如果不是所有实现都在项目中怎么办)。

更好的方法是创建一类常量:

 public class YouTubeConstants {
    public static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
    public static final JsonFactory JSON_FACTORY = new JacksonFactory();
    ...
 }

在需要访问这些常量的类中,您可以使用 YouTubeConstants.HTTP_TRANSPORT(甚至可以使用静态导入来缩短)。

现在对于所提出的设计,让我提出一个替代方案:

YouTubeApiService 类基本上只需要访问 YouTube 对象,它需要它来执行查询。不需要 YouTubeServiceBuild 中间对象,不需要连接属性),恕我直言,它只会使代码变得复杂。

你可以这样做:

 @Service
 public class YouTubeApiService {
    @Autowired
    private YouTube youtube;

     public List<SearchResult> searchYouTube(String searchQuery) {
         List<SearchResult> searchResults =
            executeSearch(searchQuery,youtube);
         //etc...
     }
 } 

看起来好多了,不是吗?

现在为了创建一个 youtube 对象,您需要一些超出常规"new"范围的代码。您可以为此使用配置:

 import static YoutubeConstants.*;
 @Configuration
 public class YouTubeConfig {

    @Bean
    public YouTube youtube() {
      return new YouTube.Builder(HTTP_TRANSPORT, JSON_FACTORY, request -> {
         }).setApplicationName("youtube-search-demo").build();
    }
 } 

在此实现中,根本不需要 YouTubeBuilder

还有一点需要考虑: 看起来你正在尝试自己加载一些属性,注意,spring 可以单独加载它。

我在问题中提出的代码中没有看到这些属性的任何实际用法,所以我无法提供工作示例,但请确保您了解如何在 spring 中加载属性,您可能会注入(inject)已经- 将属性加载到配置中的 youtube 方法中。

关于java - 我可以在服务 bean 中拥有公共(public)静态字段吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58787584/

相关文章:

java - java中方法 "passing reference after assigning an object"和 "passing object using new keyword"之间的区别?

java - JUnit4 fail() 在这里,但是 pass() 在哪里?

java - 计算 View 的宽度,以便它们始终适合屏幕

java - java中随机颜色填充三角形

java - EJB-QL 3 中的 MEMBER OF 不起作用

java - Spring 启动 : "Scope ' request' is not active for the current thread"in Asynch method

spring - Hadoop Mapper 中的依赖注入(inject)

java - Spring Framework 5 简单 bean 示例 - 为什么出现 NoSuchBeanDefinitionException

java - 工厂类

java - OOP的缺点?