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

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

      let list = [1, 2, 3, 4, 5];
let odds = [];
for i in list:
  if (i % 2 == 1)
     odds.push(i);
return odds;

большинство людей скажут, что это императивное программирование, но оно обязательно только в контексте языка программирования, который они используют. В контексте компилятора указание for i in list:

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

Если я напишу:

      public drawPainting{
   const square = new Shape("square");
   square.move(0, 0);
   square.draw();
   const circle = new Shape("circle");
   circle.move(square.x + square.width / 2, 0);
   circle.draw();
}

он декларативен только в контексте Shape

, потому что не знает, как формы собираются move или же draw сами по себе, но это обязательно в контексте drawPainting сам метод, так как порядок рисования фигур имеет значение для конечного результата.

Что меня больше всего беспокоит, так это то, как правильно использовать эти два стиля в большом проекте, и, возможно, некоторые подводные камни. Например, есть ли какое-нибудь практическое правило для введения нового абстрактного слоя? Следует ли на уровне абстракции использовать только те методы, которые предоставляет предыдущий уровень? Если какой-либо уровень абстракции начинает использовать методы из большего количества предыдущих уровней, тогда рефакторинг станет головной болью, вы не знаете, где провести грань между реализацией и тем, что вы на самом деле пытаетесь реализовать. Что должно различать разные уровни абстракций? Каждый уровень абстракции должен знать только методы предыдущего уровня и ничего больше?

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

      Layer_n method:
   <imperative in context of Layer_n>
   Layer_n-1 method_1(); // method_1 declarative in context of Layer_n
   Layer_n-1 method_2();
    ...
   Layer_n-1 method_k();
   </imperative>

...

Layer_n-1 method_1:
   <imperative in context of Layer_n-1>
   Layer_n-2 method_1(); // method_1 declarative in context of Layer_n-1
   Layer_n-2 method_2();
    ...
   Layer_n-2 method_k();
   </imperative>

и так далее.

0 ответов

Другие вопросы по тегам