При написании программного обеспечения мы работаем на двух уровнях:
- Создание исполняемой спецификации именно того, что мы хотим, чтобы машина делала
- Создание живого документа, который описывает намерение того, что мы хотим, чтобы машина делала, чтобы ее читали люди
Первая часть — это простая часть, вторая часть требует целой жизни. Сегодня я прочитал действительно хороший пост с указанием на то, что вы плохой программист . Являетесь ли вы плохим программистом или просто неопытным, я думаю, что самым большим препятствием является возможность быстрой и точной визуализации кода. Вам нужно визуализировать, что на самом деле делает приложение , что происходит во время выполнения; но все, что показывает ваша IDE — это необработанный статический исходный код. Из этого статического представления о мире вы должны вывести поведение во время выполнения, вы должны определить реальную форму приложения и шаблоны взаимодействия; в то время как тесно связаны, оба являются отдельными . Учитывая только исходный код, вы должны иметь возможность визуализировать, какой код делает.
Что значит визуализировать код? На самом простом уровне это понимание того, что делают отдельные заявления.
string a = "Hello"; string b = "world"; a = b;
Это может звучать тривиально, но первым необходимым шагом является возможность быстро разобрать код и мысленно пройти через то, что произойдет. Сначала для базовых операторов, затем для кода, который повторяется:
while (stack.Count() > 1) { var operation = stack.Pop() as IOperation; var result = operation.Execute(stack.Pop(), stack.Pop()); stack.Push(result); }
Где вам нужно понять механику циклов и мысленно смоделировать, что происходит в целом, а не только на каждой итерации. Тогда вам нужно уметь анализировать рекурсивный код:
int Depth(ITreeNode node) { if (node == null) return 0; return 1 + Math.Max(Depth(node.Left), Depth(node.Right)); }
Что, как правило, неопытным программистам труднее понять и обдумать; даже если вы выучите шаблон, он может быть более четким и кратким.
После того, как вы освоите, как понимать, что делает один метод, вы должны понять, как методы объединяются. В мире ОО это означает понимание классов и интерфейсов; это означает понимание шаблонов дизайна ; Вы должны понимать, как код сгруппирован в связные, слабо связанные блоки с четкими обязанностями.
Например, шаблон посетителя имеет определенную ментальную структуру — он реализует нечто похожее на виртуальный метод вне иерархии классов; на мой взгляд, это делит набор классов на набор методов.
public interface IAnimal { void Accept(IAnimalVisitor visitor); } public class Dog : IAnimal { ... } public class Cat : IAnimal { ... } public class Fox : IAnimal { ... } public interface IAnimalVisitor { void VisitDog(Dog dog); void VisitCat(Cat cat); void VisitFox(Fox fox); }
Первый шаг в чтении кода — это возможность прочитать что-то вроде шаблона посетителя (при условии, что вы никогда не слышали о нем раньше) и понять, что он делает, и разработать ментальную модель того, как выглядит эта форма. Затем вы можете использовать термин «посетитель» в своем коде и в дискуссиях с коллегами. Этот общий язык имеет решающее значение, когда речь идет о коде: проектировать систему, рассматривая отдельные строки кода, непрактично, нам нужно уметь рисовать прямоугольники на доске и обсуждать формы и шаблоны. Эта общая ментальная модель является ключевой частью работы по проектированию команды; нам нужен общий язык, который отображается на общую ментальную модель, как существующей системы, так и изменений, которые мы хотели бы внести.
В больших системах здесь важен общий язык: если в реализации используются те же термины, что и в домене, становится проще понять, как взаимодействуют части системы. Присваивая вещам собственные имена, взаимодействия между классами становятся логическими аналогами реальных вещей — нам не нужно использовать технические слова или вымышленные слова, которые последующие читатели должны будут работать, чтобы понять или выучить, кто-то, знакомый с предметной областью, будет знать, каковы ожидаемые взаимодействия. Это облегчает построение ментальной модели системы.
Например, в книжном интернет-магазине у меня могут быть такие понятия (классы), как книга, клиент, корзина покупок, почтовый адрес. Это все логические вещи реального мира с очевидными взаимодействиями. Если бы я вместо этого назвал их PurchaseasableItem, RegisteredUser, OrderItemList и DeliveryIndicationStringList, вы, вероятно, изо всех сил пытались бы понять, как одно связано с другим. Называть вещи сложно, но невероятно важно — плохое именование значительно усложнит разработку хорошей ментальной модели работы вашей системы.
Чтение кода, необходимого предшественника написания кода, это все о построении ментальной модели. Мы пытаемся визуализировать то, чего не существует, читая строки текста.