Могу ли я иметь открытые статические поля в служебном компоненте? - PullRequest
0 голосов
/ 10 ноября 2019

Я немного скептически отношусь к этому коду, поскольку он как бы нарушает YAGNI. Мне нужны некоторые открытые статические поля для моего класса обслуживания, но обычно это плохой дизайн, когда они есть в вашем компоненте службы, поэтому я создал интерфейс для этой службы, но я не уверен, что это правильный выбор. Должны ли я иметь эти поля в классе обслуживания?

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...
    }

1 Ответ

1 голос
/ 10 ноября 2019

Если вопрос заключается в том, возможно ли устанавливать общедоступные статические поля в управляемом компоненте Spring - тогда да, это возможно, хотя я полностью согласен с вами, что это плохой дизайн.

Оставляя в покое пружину, помещая константыв интерфейсе, так что реализации интерфейса будут иметь к ним доступ, считается запахом кода, потому что все реализации (при условии, что их много) теперь могут вести себя по-разному, потому что некоторые постоянные изменения или, что еще хуже, не будут компилироваться больше, есликонстанта удалена (что, если не все реализации находятся в проекте).

Гораздо лучший подход - создать класс констант:

 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 промежуточном объекте, нет необходимости в свойствах соединения), IMHO, это только усложняет код.

Вы можете сделать что-то вроде этого:

 @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

Еще один момент, на который следует обратить внимание: кажется, вы пытаетесьчтобы загрузить некоторые свойства самостоятельно, обратите внимание, что пружина может работать в одиночку.

Я не видел реального использования этих свойств в коде, представленном в вопросе, поэтому я не могу предоставить рабочий пример,но, пожалуйста, убедитесь, что вы понимаете, как загружать свойства весной, вы можете добавить уже загруженные свойства в метод youtube в конфигурации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...