Как мне справиться с этой грязной переменной теневого копирования?

1

У меня есть класс SharedFolder который реализует абстрактный класс Endpoint, проблема связана с одним из атрибутов подкласса (baseDir), который зависит от значения другого атрибута (environment), который обновляется после создания экземпляра класса, вот что Я говорю о:

public class SharedFolderEndpoint extends Endpoint {

    private String name = "SharedFolder";
    private String hostname = "somehostname";
    private Environment environment;
    private String baseDir;
    private String format = "someformat"
    private String pattern = "somepattern";

    public SharedFolderEndpoint() {

    }
    ...

Путь basedir зависит от значения среды, переменная должна быть инициализирована с чем-то вроде этого:

this.baseDir= "/env-"+this.environment+"/somefolder/files";

Класс создается с помощью GUI, и тогда пользователь должен выбрать среду, с которой он/она хочет взаимодействовать, поэтому, как вы можете видеть, до этого ручного взаимодействия this.environment ссылается на null значение.

Интересно, будет ли элегантное решение обновить это значение без создания нового метода добавления значения к пути. Есть идеи?

  • 2
    Это довольно открытый вопрос, потому что он действительно зависит от того, как baseDir значение baseDir . Если он используется редко и должен быть действительным только в какой-то более поздний момент, нет причин не просто вычислять его на лету. Если он должен быть действительным и использоваться сразу же, вам понадобится какой-то способ предоставить допустимое значение по умолчанию. Если он используется часто, вы можете рассчитать его только при необходимости и сохранить рассчитанное значение. Есть множество способов сделать это в зависимости от этих опций.
Теги:
oop
design

2 ответа

3
Лучший ответ

Чтобы добавить вариант ответа Taks (1+ на него), вы можете сделать baseDir "вычисленным" свойством, которое построено из константного формата String, так что скелет String доступен для быстрого просмотра как константа, что-то как:

public class SharedFolderEndpoint extends Endpoint {
   private static final String BASEDIR_FORMAT = "/env-%s/somefolder/files";
   //...


   // might need to declare this as throwing the exception
   public String getBaseDir() {  
      if (environment.isPopulated()) {
        return String.format(BASEDIR_FORMAT, environment.toString());
      } else {
        // throw an exception...
      }
   }
}

Этот пример показывает, что он создается только с одной переменной String, %s, но было бы тривиально добавить больше.

Например, если вы хотите использовать переменную папки и переменную файлов, вы можете сделать следующее:

public class SharedFolderEndpoint extends Endpoint {
   private static final String BASEDIR_FORMAT = "/env-%s/%s/%s";
   //...


   // might need to declare this as throwing the exception
   public String getBaseDir() {  
      if (!environment.isPopulated()) {
        // ... throw exception showing no environment
      } else {
      if (!folder.isPopulated()) {
        // ... throw exception showing no folder
      } else {
      if (!file.isPopulated()) {
        // ... throw exception showing no file
      } else {
        // throw an exception...
        return String.format(BASEDIR_FORMAT, 
               environment.getText(),
               folder.getText(),
               files.getText());
      }
   }
}
2

Вы можете хранить среду в отдельной переменной и иметь метод, который лениво загружает путь basedir:

   public void setEnvironment(Environment environment)
   {
        this.environment=environment;
        baseDir = null;
   }


   public String getBaseDir() {
       if(baseDir==null)
           "/env-"+this.environment+"/somefolder/files";
       return baseDir
   }

если бы переменная окружения была бы очень часто изменена, вы могли бы использовать StringBuilder и снова кэшировать значение. Также вы можете использовать StringFormat, чтобы сделать concat очень красивым. Если один экземпляр SharedFolderEndpoint разделяется между всеми пользователями, вы можете создать какую-то карту userId-> Путь.

  • 0
    Это работает, но ... это как бы создает проблему в моем API, что если кто-то заполняет baseDir но не переменную environment ? Что если я захочу использовать этот код где-нибудь еще?
  • 1
    Было бы невозможно оценить baseDir, если переменная окружения не установлена. В этом случае у вас может быть какое-то значение по умолчанию, исключение или возвращаемое значение null. Поведение там полностью зависит от вас. О каком повторном использовании мы говорим?
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню