Как правильно использовать императивную и декларативную парадигмы при разработке проекта?
Прочитав множество ответов о разнице между этими двумя парадигмами, я пришел к выводу, что эти две парадигмы сосуществуют, не могут существовать одна без другой. Например, если я напишу это:
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>
и так далее.