Альтернатива для переключения случая в Java

SVN сохраняет нетронутые копии всех файлов Вами контроль проложенный под землей в .svn каталогах. Это называют текстовой основой. Это допускает быстрый diffs и возвращается. Во время различных операций SVN сделает контрольные суммы на этих основных текстом файлах для ловли проблем повреждения файла.

В целом, несоответствие контрольной суммы SVN означает файл, который не должен был быть изменен, был изменен так или иначе. Что это означает?

  1. Дисковое повреждение (плохой жесткий диск или кабель IDE)
  2. Плохой RAM
  3. Плохой сетевой канал
  4. Некоторый фоновый процесс изменил файл за Вашей спиной (вредоносное программное обеспечение)

, Все они плохи.

ОДНАКО , я думаю, что Ваша проблема отличается. Посмотрите на сообщение об ошибке. Обратите внимание, что это ожидало некоторые хеши MD5, но вместо этого возвратило 'пустой указатель'. Если бы это было простой проблемой повреждения файла, то я ожидал бы, что у Вас было бы два различных хеша MD5 для ожидания/получения. То, что у Вас есть 'пустой указатель', подразумевает, что что-то еще неправильно.

у меня есть две теории:

  1. Ошибка в SVN.
  2. Что-то имело монопольную блокировку на файле, и MD5 не могло произойти.

В случае № 1, попытайтесь обновить до последней версии SVN. Возможно, также отправьте это в svn-devel списке рассылки ( http://svn.haxx.se ), таким образом, разработчики видят его.

В случае № 2, проверьте, чтобы видеть, заблокировали ли чему-нибудь файл. Можно загрузить копию Проводника Процесса для проверки. Обратите внимание, что Вы, вероятно, хотите видеть, у кого есть блокировка на текстовая основа файл, не фактический файл, который Вы пытались фиксировать.

9
задан Ben 26 January 2013 в 12:31
поделиться

10 ответов

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

Map<String,Object> map = new HasMap<String,Object>();
// ... insert stuff into map
// eg: map.add("something", new MyObject());

String key = "something";
if (map.contains(key)) {
    Object o = map.get(key);
}

В приведенном выше примере вы можете захотеть сопоставить «обработчики», что-то вроде

interface Handler {
    public void doSomething();
}

, что затем превратит все это в поиск.

if (map.contains(key)) { map.get(key).doSomething(); }

Опять же, это немного запах, поэтому, пожалуйста, задайте вопрос, который иллюстрирует рассуждения.

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

Map<String,Object> map = new HasMap<String,Object>();
// ... insert stuff into map
// eg: map.add("something", new MyObject());

String key = "something";
if (map.contains(key)) {
    Object o = map.get(key);
}

В приведенном выше примере вы можете захотеть сопоставить «обработчики», что-то вроде

interface Handler {
    public void doSomething();
}

, что затем превратит все это в поиск.

if (map.contains(key)) { map.get(key).doSomething(); }

Опять же, это немного запах, поэтому, пожалуйста, задайте вопрос, который иллюстрирует рассуждения.

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

Map<String,Object> map = new HasMap<String,Object>();
// ... insert stuff into map
// eg: map.add("something", new MyObject());

String key = "something";
if (map.contains(key)) {
    Object o = map.get(key);
}

В приведенном выше примере вы можете захотеть сопоставить «обработчики», что-то вроде

interface Handler {
    public void doSomething();
}

, что затем превратит все это в поиск.

if (map.contains(key)) { map.get(key).doSomething(); }

Опять же, это немного запах, поэтому, пожалуйста, задайте вопрос, который иллюстрирует рассуждения.

16
ответ дан 4 December 2019 в 05:57
поделиться

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

5
ответ дан 4 December 2019 в 05:57
поделиться

уродливая серия if, else if, else ?

1
ответ дан 4 December 2019 в 05:57
поделиться

или можно представить себе что-то вроде динамического переключателя:

public interface Task<T>
     {
     public void doSomething(T context);
     }

public Class SwitchCase<T>
     {
     Map<Integer,Task<T>> tasks;
     Task<T> defaultTask;

     public void choose(int choice, T context)
         {
         Task<T> t= this.tasks.get(choice);
         if(t!=null) { t.doSomething(context); return;}
         if(defaultTask!=null)  { defaultTask.doSomething(context);}
         }
     }
1
ответ дан 4 December 2019 в 05:57
поделиться

Чем вы хотите заняться? Почему Switch-Case недостаточно хорош?

Быстрый ответ: используйте if-else

0
ответ дан 4 December 2019 в 05:57
поделиться

Думаю, в "Чистом коде" есть хорошая глава, посвященная переключению / регистру по сравнению с if / else.

Кроме того: я думаю, имеет смысл решить, можете ли вы уменьшить "шум" и сделайте код чище, используя регистр переключателя, полиморфизм или даже старый добрый if / else. Думаю, здесь большую роль играет количество дел.

1
ответ дан 4 December 2019 в 05:57
поделиться
    if () {}
    else if () {}
...
    else if () {}

?

Но я бы не сказал, что это лучше ...

0
ответ дан 4 December 2019 в 05:57
поделиться

Как насчет оператора if (вместе с else if и else )? В то время как переключатель позволяет переключаться только с использованием равенства целочисленных или Enum типов, if позволяет использовать любую логическую логику.

0
ответ дан 4 December 2019 в 05:57
поделиться

Вы всегда можете заменить переключатель на if-else if-else if-else if ... , хотя я не понимаю, зачем вам это нужно. В зависимости от контекста переключатели также иногда могут быть заменены массивами или хэш-картами.

0
ответ дан 4 December 2019 в 05:57
поделиться

Если в вашем коде много операторов switch / case и они сводят вас с ума.

Вы можете выбрать рефакторинг: Замените условное выражение полиморфизмом.

Допустим, у вас есть программное обеспечение, которое используется для сохранения информации на различных устройствах: определены 4 операции сохранения: выборка, сохранение, удаление, обновление , которые могут быть реализованы с помощью механизма сохранения N-числа (плоская файлы, сеть, СУБД, XML и т. д.).

Ваш код должен поддерживать их все, поэтому в 4 разных местах у вас есть это:

ДО

class YourProblematicClass { 

....

     public void fetchData( Object criteria ) {

          switch ( this.persitanceType ) {
              case FilePersistance:
                  // open file
                  // read it
                  // find the criteria
                  // build the data
                  // close it.
                  break;
               case NetWorkPersistance: 
                   // Connect to the server
                   // Authenticate
                   // retrieve the data 
                   // build the data 
                   // close connection
                   break(); 
                case DataBasePersistace:
                   // Get a jdbc connection
                   // create the query
                   // execute the query
                   // fetch and build data
                   // close connection
                   break;
           }
           return data;
         }    

То же самое для сохранения / удаления / обновления

 public void saveData( Object data) {

      switch ( this.persitanceType ) {
          case FilePersistance:
              // open file, go to EOF, write etc.
              break;
           case NetWorkPersistance: 
               // Connect to the server
               // Authenticate
               // etc
               break(); 
            case DataBasePersistace:
               // Get a jdbc connection, query, execute...
               break;
       }
     }

И так далее ....

 public void deleteData( Object data) {

      switch ( this.persitanceType ) {
          case FilePersistance:
              break;
           case NetWorkPersistance: 
               break(); 
            case DataBasePersistace:
               break;
       }
  }

 public  void updateData( Object data) {

      switch ( this.persitanceType ) {
          case FilePersistance:
              break;
           case NetWorkPersistance: 
               break(); 
            case DataBasePersistace:
               break;
       }
  }

Использование переключателя / Оператор case становится проблематичным:

  • Каждый раз, когда вы хотите добавить новый тип, вы должны вставлять новый переключатель / регистр в каждый раздел.

  • Часто некоторые типы похожи, но они не Не нужен другой переключатель / регистр (вы могли бы их каскадировать)

  • Есть другие варианты, а иногда они немного отличаются
  • Возможно, вам даже понадобится загрузить другой тип во время выполнения (например, плагины)

Итак, рефакторинг здесь можно было бы добавить интерфейс или абстрактный тип, а различные типы реализуют этот интерфейс и делегировать ответственность этому объекту.

Таким образом, у вас будет что-то вроде этого:

ПОСЛЕ

   public interface PersistenceManager {
        public void fetchData( Object criteria );
        public void saveData( Object toSave );
        public void deleteData( Object toDelete );
        public void updateData( Object toUpdate );
   }  

И разные реализации

  public class FilePersistence implements PersistanceManager {
        public void fetchData( Object criteria ) {
                  // open file
                  // read it
                  // find the criteria
                  // build the data
                  // close it.
         }
        public void saveData( Object toSave ) {
                 // open file, go to EOF etc. 
        }
        public void deleteData( Object toDelete ){
           ....
        }
        public void updateData( Object toUpdate ){
          ....
        }
  }

И другие типы будут реализованы в соответствии с их логикой. Сеть будет иметь дело с сокетами и потоками, БД будет иметь дело с JDBC, ResultSets и т. Д. XML с узлом и т. Д.

  public class NetworkPersistence implements PersistanceManager {
        public void fetchData( Object criteria ) {
             // Socket stuff
         }
        public void saveData( Object toSave ) {
             // Socket stuff
        }
        public void deleteData( Object toDelete ){
           // Socket stuff
        }
        public void updateData( Object toUpdate ){
           // Socket stuff
        }
  }


  public class DataBasePersistence implements PersistanceManager {
        public void fetchData( Object criteria ) {
             // JDBC stuff
         }
        public void saveData( Object toSave ) {
             // JDBC  stuff
        }
        public void deleteData( Object toDelete ){
           // JDBC  stuff
        }
        public void updateData( Object toUpdate ){
           // JDBC  stuff
        }
  }

И, наконец, вам просто нужно делегировать вызовы.

Позже:

public YouProblematicClass { // not longer that problematic

    PersistamceManager persistance = // initialize with the right one.


        public void fetchData( Object criteria ) {
             // remove the switch and replace it with:
             this.persistance.fetchData( criteria );
         }
        public void saveData( Object toSave ) {
             // switch removed
             this.persistance.saveData(  toSave );
        }
        public void deleteData( Object toDelete ){
           this.persistance.deleteData( toDelete );
        }
        public void updateData( Object toUpdate ){
           this.persistance.updateData( toUpdate );
        }
  }

Итак, вы просто нужно создать правильный экземпляр для диспетчера сохраняемости в соответствии с типом только один раз. Затем все вызовы разрешаются полиморфизмом. Это одна из ключевых особенностей объектно-ориентированной технологии.

Если вы решите, что вам нужен другой менеджер сохраняемости, вы просто создаете новую реализацию и назначаете ее классу.

 public WavePersistance implements PersistanceManager {

        public void fetchData( Object criteria ) {
             // ....
         }
        public void saveData( Object toSave ) {
             //  ....
        }
        public void deleteData( Object toDelete ){
           //  ....
        }
        public void updateData( Object toUpdate ){
           //  ....
        }
   }
29
ответ дан 4 December 2019 в 05:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: