Чтобы было яснее

ОГЛАВЛЕНИЕ

Программное обеспечение - это необычная среда для конструирования. Поскольку существует множество физических факторов, которые заставляют нас проектировать тем или иным образом, то большинство проектировочных решений не поддается объективному анализу. Как правило, речь о дизайне заходит не тогда, когда мы определяем, как работает программа, а тогда, когда мы хотим внести в нее изменения. Разумеется, работа программы очень важна, но все же о ее качестве, в первую очередь, говорит то, насколько просто внести в нее изменения. Именно стремление к изменчивости является причиной, по которой дизайн системы должен четко показывать, что и как она делает. В конце концов, довольно трудно внести изменения в программу, если ты даже не понимаешь, как она работает. Интересным следствием этого является случай, когда разработчики создают специальный легко изменяемый дизайн, который при этом затрудняет понимание кода. Тогда, естественно, эффект оказывается прямо противоположным.

Атрибуты и отображения

Допустим, нам нужна структура данных для описания человека. Мы можем реализовать ее, используя некоторые поля, как показано на рисунке 1. Разумеется, для этого нужно определить ряд переменных в классе Person. С другой стороны, язык Ruby, как и многие другие современные языки программирования, поддерживает отображения (известные также под именем ассоциативных массивов или хэш-таблиц). Мы могли бы определить структуру данных для класса Person, воспользовавшись отображением, как показано на рисунке 2 (это будет работать медленнее, но предположим, что производительность этой части кода не так уж важна).

Использование отображения - весьма привлекательный способ, так как он позволяет менять набор полей, сохраняемых в классе Person, не изменяя сам класс. Если вы захотите добавить сюда номер телефона, вам не придется менять для этого начальный код.

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

Основной принцип ясного кода в том, что его проще понимать (и, как следствие, проще модифицировать). Как говорит Кент Бек, такой код представляет собой ясное выражение изначальных намерений.

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

Рисунок 1. Использование полей класса (язык Ruby)

class Person
attr_accessor :lastName,:firstName,:numberOfDependents
end
def frag1
martin =Person.new
martin.firstName =“Martin ”
martin.lastName =“Fowler ”
martin.numberOfDependents =1
print (martin.firstName,““,martin.lastName,“has “,
martin.numberOfDependents,“dependents ”)
end

Рисунок 2. Использование отображения для хранения полей (язык Ruby)

class Person
attr_accessor :data
def initialize()
@data = {}
end
end

def frag2
martin = Person.new
martin.data [“firstName ”] = “Martin”
martin.data [“lastName ”] = “Fowler”
martin.data [“numberOfDependents ”] = 1
print (martin.data [“firstName ”],““,
martin.data [“lastName ”],“has “,
martin.data [“numberOfDependents ”],
“dependents ”)
end