Читаем Рефакторинг. Зачем? полностью

В месте использования код также становтся наглядней. Строка LineLenght:= CalculateLineLength(Line); заменится на строку: LineLenght:= Line. CalculateLineLength;, что несколько короче и куда лучше подчёркивает тот факт, что функция относится именно к линии, а не к чему–то ещё.

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

И немного из терминологии. Функцию член класса принято называть методом. В нашем случае, мы имеем класс с одним методом CalculateLineLength.

<p><strong>Приватные члены класса</strong></p>

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

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

Действительно, зачем считать длину каждый раз, если это можно сделать единожды, запомнить посчитанное значение и потом, в качестве результата функции, возвращать его.

Вот как это могло бы выглядеть:

type

TLine = class(TObject)

public

X1: Integer;

Y1: Integer;

X2: Integer;

Y2: Integer;

LengthCalculated: Boolean;

LineLength: Double;

function CalculateLineLength: Double;

end;

function TLine. CalculateLineLength: Double;

begin

if not LengthCalculated then

begin

LineLength:= Sqrt(Sqr(X2 — X1) + Sqr(Y2 — Y1));

LengthCalculated:= True;

end;

Result:= LineLength;

end;

При всей иллюзии работоспособности, в данном коде присутствует целый спектр проблем. Во–первых, тому, кто будет использовать класс снаружи, будет неочевидно, что необходимо вызывать функцию CalculateLineLength и не корректно напрямую использовать поле LineLength. Ну а во–вторых — нет механизма пересчёта длины при изменении координат точек.

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

Мы уже упоминали, да и не раз сталкивались с ключевым словом public, теперь пришло время рассказать, что оно означает. Члены класса, объявленные как public доступны как внутри класса, так и за его пределами.

Кроме public, есть ещё и ключевое слово private, которое означает, что члены класса доступны только из методов данного класса и не доступны за его пределами. В Object Pascal реализации, используемой в компиляторе Delphi, у данной функциональности есть особенность. Видимость private распространяется не только на членов класса, но и на весь модуль, в котором объявлен класс, что является неким отклонением от общих принципов, но уж так сложилось исторически, ничего не попишешь.

Так или иначе, private члены классов — это некие служебные поля и методы (переменные и функции), не предназначенные для использования за пределами класса.

Давайте посмотрим, как будет выглядеть декларация нашего класса, если мы унесём в private секцию всё лишнее:

type

TLine = class(TObject)

private

LengthCalculated: Boolean;

LineLength: Double;

public

X1: Integer;

Y1: Integer;

X2: Integer;

Y2: Integer;

function CalculateLineLength: Double;

end;

Данная реализация вполне себе красноречиво говорит, что поля LengthCalculated и LineLength трогать не надо. По крайней мере, если вы не планируете менять внутренней логики класса.

<p><strong>Свойства</strong></p>

Для того, чтобы можно было каким–то образом реагировать на изменения значений полей классов, были придуманы свойства (property). Они так же могут перекликаться с понятиями getter и setter.

Сначала я приведу пример кода, а потом поясню что происходит. Думаю так будет понятнее:

type

TLine = class(TObject)

private

LengthCalculated: Boolean;

LineLength: Double;

FX2: Integer;

FY2: Integer;

FX1: Integer;

FY1: Integer;

procedure SetX1(const Value: Integer);

procedure SetX2(const Value: Integer);

procedure SetY1(const Value: Integer);

procedure SetY2(const Value: Integer);

public

Перейти на страницу:

Похожие книги

97 этюдов для архитекторов программных систем
97 этюдов для архитекторов программных систем

Успешная карьера архитектора программного обеспечения требует хорошего владения как технической, так и деловой сторонами вопросов, связанных с проектированием архитектуры. В этой необычной книге ведущие архитекторы ПО со всего света обсуждают важные принципы разработки, выходящие далеко за пределы чисто технических вопросов.?Архитектор ПО выполняет роль посредника между командой разработчиков и бизнес-руководством компании, поэтому чтобы добиться успеха в этой профессии, необходимо не только овладеть различными технологиями, но и обеспечить работу над проектом в соответствии с бизнес-целями. В книге более 50 архитекторов рассказывают о том, что считают самым важным в своей работе, дают советы, как организовать общение с другими участниками проекта, как снизить сложность архитектуры, как оказывать поддержку разработчикам. Они щедро делятся множеством полезных идей и приемов, которые вынесли из своего многолетнего опыта. Авторы надеются, что книга станет источником вдохновения и руководством к действию для многих профессиональных программистов.

Билл де Ора , Майкл Хайгард , Нил Форд

Программирование, программы, базы данных / Базы данных / Программирование / Книги по IT
Programming with POSIX® Threads
Programming with POSIX® Threads

With this practical book, you will attain a solid understanding of threads and will discover how to put this powerful mode of programming to work in real-world applications. The primary advantage of threaded programming is that it enables your applications to accomplish more than one task at the same time by using the number-crunching power of multiprocessor parallelism and by automatically exploiting I/O concurrency in your code, even on a single processor machine. The result: applications that are faster, more responsive to users, and often easier to maintain. Threaded programming is particularly well suited to network programming where it helps alleviate the bottleneck of slow network I/O. This book offers an in-depth description of the IEEE operating system interface standard, POSIX (Portable Operating System Interface) threads, commonly called Pthreads. Written for experienced C programmers, but assuming no previous knowledge of threads, the book explains basic concepts such as asynchronous programming, the lifecycle of a thread, and synchronization. You then move to more advanced topics such as attributes objects, thread-specific data, and realtime scheduling. An entire chapter is devoted to "real code," with a look at barriers, read/write locks, the work queue manager, and how to utilize existing libraries. In addition, the book tackles one of the thorniest problems faced by thread programmers-debugging-with valuable suggestions on how to avoid code errors and performance problems from the outset. Numerous annotated examples are used to illustrate real-world concepts. A Pthreads mini-reference and a look at future standardization are also included.

David Butenhof

Программирование, программы, базы данных