Как гарантировать, что методы будут выполняться в правильном порядке?

У меня всегда есть проблема с разработкой класса, в котором правильный вызов метода будет понятен программисту, и не будет опасности выполнения какого-либо метода до того, как данные, переменные будут установлены другим методом. Поэтому я обычно использую флаги и операторы If, чтобы быть в безопасности:

class foo {
    boolean isInitialised = FALSE;
    boolean isSthDone = FALSE;
    float importantData;

    public void initialise {

        ...

        isInitialised = TRUE;
    }

    public void doSth1 { 

      if (isInitialised) {

         importantData = 2134234; 

         }   ...

          isSthDone = TRUE;

    }

    public void doSth2 { 

        if (isInitialised && isSthDone1) {

            ...

          }
    }
}

Такой дизайн не дает никакой подсказки, как следует использовать алгоритм - какой метод должен выполняться первым, существует ли какой-либо шаблон проектирования для этой проблемы?


person Damian    schedule 10.03.2011    source источник
comment
Это называется шаблоном Design Your Objects to to be a Valid State After Construction.   -  person ChaosPandion    schedule 10.03.2011
comment
@featon - Что это за беспорядок в коде? Если вы ожидаете, что кто-то будет уважать вас, по крайней мере, сделайте так, чтобы ваш пример следовал одному и тому же базовому синтаксису. Также не мешало бы проверить орфографию.   -  person ChaosPandion    schedule 10.03.2011
comment
Неужели так важно, на каком это языке? Если бы вы знали только Java, а это был C#, смогли бы вы его понять? А как насчет наоборот?   -  person Patrick McDonald    schedule 10.03.2011
comment
@Patrick - Скорее всего, это Java, но откуда мы могли это знать? Что, если это новый язык X, в котором отсутствуют конструкторы, но есть волшебная функция, помогающая вам вызывать методы по порядку?   -  person ChaosPandion    schedule 10.03.2011
comment
@ Патрик, я полагаю, в Java есть ключевое слово then? (Проверьте историю изменений...)   -  person ChaosPandion    schedule 10.03.2011
comment
@Patrick, @featon - Как вы, наверное, знаете, я сегодня немного сварлив, за что прошу прощения.   -  person ChaosPandion    schedule 10.03.2011
comment
Извините за это, я понятия не имел, что это затруднит понимание кода. В короткие сроки мне нужно использовать C, C++, C#, Java, Unix shell, Matlab, язык CUDA, я даже не всегда помню, какой синтаксис привязан к какому языку :( . Надеюсь, завтра будет лучше для вас: ).   -  person Damian    schedule 10.03.2011


Ответы (4)


Вам следует рассмотреть возможность использования здесь State. Для меня ваш код выглядит так:

  • "Я нахожусь в состоянии, которое позволяет мне только инициализировать"
  • "Я в инициализированном состоянии, поэтому могу выполнить необходимую логику - Sth1"
  • Наконец: «Я в последнем состоянии, поэтому я могу сделать сейчас Sth2

http://sourcemaking.com/design_patterns/state

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

person dantuch    schedule 10.03.2011

Подумайте, действительно ли имеет смысл независимое выполнение этих шагов. Если потребителю этого класса действительно нужно выполнить шаг 1, шаг 2 и шаг 3 именно в таком порядке, просто сверните их в один общедоступный метод и инкапсулируйте шаги в вашем классе.

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

person D. Lambert    schedule 10.03.2011

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

Class foo{

  public: 
  foo(){
    a = 1;
    b = "something";
  }

   int a;
   string b;

}
person David    schedule 10.03.2011
comment
Бывают случаи, когда неуместно инициализировать в конструкторе. - person Chris Pfohl; 10.03.2011
comment
Бывают случаи, когда любой стандартный подход неуместен. В контексте его вопроса (то есть почти всегда) конструктор находится там, где он должен выполнять инициализацию. - person David; 10.03.2011

@Д. Ламберт и @David дают хорошие советы.

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

person TrueWill    schedule 10.03.2011