Справка по рефакторингу кода - PullRequest
2 голосов
/ 19 октября 2010

У меня есть пример, подобный этому

class A {

   A() {}
   public C createC () {
      ...
   }

} 

class B {

   B() {}
   public C createC () {

   }
}

Объекты для A и B создаются на основе

public enum D { ii, jj };

И я вижу код повсюду, как

D d; 

switch (d) {
    case ii: (new A()).createC(); break;
    case jj: (new B()).createC(); break;
 };

Как можно избежать случаев переключения повсюду?Я так понимаю, код не так понятен.

Ответы [ 5 ]

3 голосов
/ 19 октября 2010

Я был бы склонен добавить код создания в перечисление.

enum D {
    ii {
        public void createC() { new A().createC(); }
    },
    jj {
        public void createC() { new B().createC(); }
    };

    public abstract void createC();
}

Затем вы можете заменить переключатель на

d.createC();

Сказав, что я также посмотрю на созданиеметод createC статический или перемещение кода createC в перечисление, а не оставление его в классах A и B.

Если вы сделаете метод createC в A и B статическим, перечисление будет выглядеть как

enum D {
    ii {
        public void createC() { A.createC(); }
    },
    jj {
        public void createC() { B.createC(); }
    };

    public abstract void createC();
}
3 голосов
/ 19 октября 2010

Вы можете просто создать класс Factory:

public class ClassFactory {

     public static C createC(D type) {
         C c = null;
         switch (type) {
              case ii: 
                  c = new A(); 
                  break;
              case jj: 
                  c = new B(); 
                  break;
         };

         return c;

     }
}

Тогда в вашем коде просто сделайте:

C c = ClassFactory.createC(type);

Очень похоже на то, что делает запись вики для Шаблон метода фабрики со своей PizzaFactory.

1 голос
/ 19 октября 2010

Я не вижу здесь возможности рефакторинга.

Я вижу необходимость в фабрике.Посмотрите "фабричный" шаблон проектирования.

И я вижу код повсюду, например ... (за которым следует условное выражение, в котором создается конкретный экземпляр) _ это огромный совет-off.

По сути, то, что вы хотите сделать, толкает все уродство принятия решения о том, какой класс создавать в одном месте.Во-первых, в вашем примере A и B должны совместно использовать суперкласс или, что еще лучше, реализовать интерфейс, в котором определен public C createC().

Фабрика - это не что иное, как класс со статическим методом, который принимает решение окакой экземпляр A или B. создать.

    public class SomeFactory {
        public static YourInterface make(int someNumber) {
            switch (someNumber) {
                case 1: return new A();
                case 2: return new B();
                default:
                    throw new RuntimeException("unknown type");
                }
            }
        }

Итак, что вы делаете:

YourInterface yi = SomeFactory.make(1);
C c = yi.createC();

Или

C c = SomeFactory.make(1).createC();

И теперь ваш код довольно чистый.Создать новую реализацию SomeInterface?Нет проблем, добавьте его создание на завод, и ваш код все еще работает.Если для вашего приложения make() дорого, нет проблем, просто сделайте его и используйте его несколько раз.

0 голосов
/ 19 октября 2010

Вы приводите в качестве примера оператор переключения, но поскольку другие условные обозначения, относящиеся к переключению, не показаны, я думаю, что преждевременно предлагать конкретное решение. Вот ссылка, хотя, если вы хотите рассмотреть диапазон ответов на операторы "switch": http://books.google.com/books?id=1MsETFPD3I0C&lpg=PP1&dq=refactoring&pg=PA82#v=onepage&q&f=false

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

0 голосов
/ 19 октября 2010

Добавьте метод createC к перечислению D.

public enum D {
  ii,
  jj;

  public C createC() {
    switch (this) {
      case ii:
        return new A().createC();
      case jj:
        return new B().createC();
    }
    return null;
  }
}

Затем просто позвоните D.createC().

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