Когда речь заходит о классических паттернах проектирования, нельзя не вспомнить о самом объектно-ориентированном программировании. Ведь паттерны GoF являются паттернами именно объектно-ориентированного программирования. В функциональном же программировании есть свои собственные паттерны.
Вообще устроено все следующим образом: есть само объектно-ориентированное программирование. У него есть принципы. Из принципов объектно-ориентированного программирования следуют разобранные нам шаблоны GRASP (как вариант — SOLID принципы), из которых, в свою очередь, следуют шаблоны GoF. Из них же следует ряд интересных вещей, например, enterprise паттерны.
Объектно-ориентированная парадигма
Определение гласит, что «Объектно-ориентированное программирование – это парадигма программирования, в которой основной концепцией является понятие объекта, который отождествляется с предметной областью.»
Таким образом, система представляется в виде набора объектов предметной области, которые взаимодействуют между собой некоторым образом. Каждый объект обладает тремя cоставляющими: идентичность (identity), состояние (state) и поведение (behaviour).
Почему нужно понимать ООП Python и как это упрощает разработку
Состояние объекта — это набор всех его полей и их значений.
Поведение объекта — это набор всех методов класса объекта.
Идентичность объекта — это то, что отличает один объект класса от другого объекта класса. С точки зрения Java, именно по идентичности определяется метод equals.
Принципы объектно-ориентированного программирования
Объектно-ориентированное программирование обладает рядом принципов. Представление об их количестве расходится. Кто-то утверждает, что их три (старая школа программистов), кто-то, что их четыре (новая школа программистов):
- Абстрация
- Инкапсуляция
- Наследование
- Полиморфизм
Инкапсуляция
Вопреки мнению многих собеседующихся (а иногда и собеседуемых), инкапсуляция это не «когда все поля приватные». Инкапсуляция является фундаментальнейшим принципом проектирования ПО, ее следы наблюдаются на только на уровне микро-, но и на уровне макропроектирования.
Научное определение гласит, что «Инкапсуляция – это принцип, согласно которому любой класс и в более широком смысле – любая часть системы должны рассматриваться как «черный ящик»: пользователь класса или подсистемы должен видеть только интерфейс (т.е. список декларируемых свойств и методов) и не вникать во внутреннюю реализацию.»
Таким образом, получается, что если класс A обращается к полям класса B напрямую, это приводит не к тому, что «нарушается информационная безопасность», а к тому, что класс A завязывается на внутренне устройство класса B, и попытка изменить внутреннее устройство класса B приведет к изменению класса А. Более того, класс A не просто так работает с полями класса B, он работает по некоторой бизнес-логике. То есть логика по работе с состоянием класса В лежит в классе А, и когда мы захотим переиспользовать класс В, это не удастся сделать, ведь без кусочка класса А класс В может быть бесполезным, что приведет к тому, что класс В придется отдавать вместе с классом А. Экстраполируя это на всю систему, получается, что переиспользовать можно будет только всю систему целиком.
Что такое ООП? Часть #1 ★ Подробно об основных принципах
Инкапсуляция является самым недооцененным принципом, который, к сожалению, мало кем интерпретируется правильно. Она позволяет минимизировать число связей между классами и подсистемами и, соответственно, упростить независимую реализацию и модификацию классов и подсистем.
Наследование
Наследование — это возможность порождать один класс от другого с сохранением всех свойств и методов класса-предка (суперкласса), добавляя при необходимости новые свойства и
методы.
Наследование является самым переоцененным принципом. Когда-то считалось, что «У идеального программиста дерево наследования уходит в бесконечность и заканчивается абсолютно пустым объектом», потому как когда-то люди не очень хорошо понимали то, что наследование — это способ выразить такое свойство реального мира как иерархичность, а не способ переиспользовать код, отнаследовав машину от холодильника, потому что у обоих предметов есть ручка. Наследования желательно по возможности избегать, потому что наследование является очень сильной связью. Для уменьшения количества уровней наследования рекомендуется строить дерево «снизу-вверх».
Полиморфизм
Полиморфизм — это возможность использовать классы – потомки в контексте, который был предназначен для класса – предка.
За самым садистским определением кроется возможность языка программирования для декомпозиции задачи и рефакторинга if’ов и switch’ей.
Источник: habr.com
Объектно-ориентированное программирование
Эта глава посвящена изучению объектно-ориентированного программирования ( ООП ). ООП — это методика разработки программ, в основе которой лежит понятие объекта, как некоторой структуры, описывающей объект реального мира, его поведение и взаимодействие с другими объектами.
9.1 Основные понятия
Основой объектно-ориентированного программирования является объект . Объект состоит из трёх основных частей:
- Имя (например, автомобиль);
- Состояние, или переменные состояния (например, марка автомобиля, цвет, масса, число мест и т. д.);
- Методы, или операции, которые выполняют некоторые действия над объектами и определяют, как объект взаимодействует с окружающим миром.
Для работы с объектами во FreePascal введено понятие класса. Класс — сложная структура, включающая в себя описание данных, процедуры и функции, которые могут быть выполнены над объектом.
Классом называется составной тип данных , членами (элементами) которого являются функции и переменные (поля). В основу понятия класс положен тот факт, что «над объектами можно совершать различные операции «. Свойства объектов описываются с помощью переменных (полей) классов, а действия над объектами описываются с помощью подпрограмм, которые называются методами класса. Объекты называются экземплярами класса.
Объектно-ориентированное программирование ( ООП ) представляет собой технологию разработки программ с использованием объектов. В объектноори-ентированных языках есть три основных понятия: инкапсуляция , наследование и полиморфизм . Инкапсуляцией называется объединение в классе данных и подпрограмм для их обработки. Наследование — это когда любой класс может быть порождён другим классом. Порождённый класс (наследник) автоматически наследует все поля, методы, свойства и события. Полиморфизм позволяет использовать одинаковые имена для методов, входящих в различные классы.
Для объявления класса используется конструкция:
= class ( имя класса родителя>)
В качестве имени класса можно использовать любой допустимый в FreePascal идентификатор . Имя класса родителя — имя класса , наследником которого является данный класс , это необязательный параметр , если он не указывается, то это означает, что данный класс является наследником общего из предопределённого класса TObject .
Структуры отличаются от классов тем, что поля структуры доступны всегда. При использовании классов могут быть члены, доступные везде — публичные (описатель public ), и приватные (описатель private ), доступ к которым возможен только с помощью публичных методов. Это также относится и к методам класса. Поля, свойства и методы секции public не имеют ограничений на видимость.
Они доступны из других функций и методов объектов как в данном модуле, так и во всех прочих, ссылающихся на него. При обращении к публичным полям вне класса используется оператор «.» (точка).
Поля, свойства и методы, находящиеся в секции private , доступны только в методах класса и в функциях, содержащихся в том же модуле, что и описываемый класс . Это позволяет полностью скрыть детали внутренней реализации класса. Вызов приватных методов осуществляется из публичных.
Публикуемый (published ) — это раздел, содержащий свойства, которые пользователь может устанавливать на этапе проектирования и которые доступны для редактирования в инспекторе объектов.
Защищенный ( protected ) — это раздел, содержащий поля и методы, которые доступны внутри класса, а также любым его классам-потомкам, в том числе и в других модулях.
Поля и методы, описанные до указания имени секции, являются публичными ( public ).
При программировании с использованием классов, программист должен решить, какие члены и методы должны быть объявлены публичными, а какие приватными. Общим принципом является следующее: «Чем меньше публичных данных о классе используется в программе, тем лучше». Уменьшение количества публичных членов и методов позволит минимизировать количество ошибок.
Поля могут быть любого типа, в том числе и классами. Объявление полей осуществляется так же, как и объявление обычных переменных:
Методы в классе объявляются так же, как и обычные подпрограммы:
function метод1 ( список параметров ) : тип результата;
procedure метод2 ( список параметров );
Описание процедур и функций, реализующих методы, помещается после слова implementation того модуля, где объявлен класс , и выглядит так:
function имя_класса.метод1( список параметров ) : тип результата;
procedure имя_класса.метод2( список параметров );
Объявление переменной типа class называется созданием (инициализацией) объекта (экземпляра класса). Экземпляр класса объявляется в блоке описания переменных:
var имя_переменной : имя_класса;
После описания переменной в программе можно обращаться к полям и методам класса аналогично обращению к полям структуры, используя оператор «.». Например:
имя_переменной.метод1( список параметров );
Также можно использовать оператор With :
With имя_переменной do
метод1( список параметров );
В Free Pascal имеется большое количество классов, с помощью которых описывается форма приложения и её компоненты (кнопки, поля, флажки и т. п.). В процессе конструирования формы в текст программы автоматически добавляются программные объекты. Например, при добавлении на форму компонента формируется описание класса для этого компонента, а при создании подпрограмм обработки событий в описание класса добавляется объявление методов. Рассмотрим это на примере проекта с формой, на которой есть кнопка Button1 .
unit Unit1; interface uses Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls; type < TForm1 >//объявление класса формы TForm1 TForm1 = class (TForm) //объявление компонента кнопки Button1 Button1 : TButton; //объявление метода обработки события -//щелчка по кнопке Button1 procedure Button1Click ( Sender : TObject ); private < private declarations >public < public declarations >end; var //описание переменной класса формы TForm1 Form1 : TForm1; implementation < TForm1 >//описание метода обработки события — щелчка по кнопке Button1 procedure TForm1. Button1Click ( Sender : TObject ); begin //Текст процедуры обработки события end; initialization end.
Во Free Pascal класс ( объект ) — это динамическая структура. В отличие от статической она содержит не сами данные, а ссылку на них. Поэтому программист должен сам позаботиться о выделении памяти для этих данных.
Конструктор — это специальный метод, создающий и инициализирующий объект . Объявление конструктора имеет вид:
Описывают конструктор так же, как и другие методы, после ключевого слова implemention того модуля, в котором объявлен класс .
constructor имя_класса. Create ;
В результате работы конструктора инициализируются все поля класса , при этом порядковым типам в качестве начальных значений задаётся 0, а строки задаются пустыми.
Деструктор — это специальный метод, уничтожающий объект и освобождающий занимаемую им память . Объявляется деструктор следующим образом:
Если в программе какой-либо объект больше не используется, то оператор
с помощью метода free вызывает деструктор и освобождает память , занимаемую полями объекта имя_переменной_типа_класс .
Рассмотрим всё описанное на примере класса «комплексное число» 1 С комплексными числами мы уже сталкивались в предыдущих главах, подробнее о работе с ними можно прочитать на странице http://kvant.mccme.ru./1982/03/komplesnye_chisla.htm . . Назовём этот класс Tcomplex . В нём будут члены класса: x — действительная часть комплексного числа — и y — мнимая часть комплексного числа. Также в классе будут методы:
- конструктор Create , который будет записывать в действительную и мнимую части значение 0;
- Modul() — функция вычисления модуля комплексного числа;
- Argument() — функция вычисления аргумента комплексного числа;
- ComplexToStr() — функция, представляющая комплексное число в виде строки для вывода.
Создадим новый проект, на форму поместим кнопку Button1 , два поля — Edit1 и Edit2 — для ввода действительной и мнимой частей, для вывода результатов разместим компонент Memo1 . При щелчке по кнопке будет создаваться экземпляр класса » Комплексное число «, затем будет вычисляться его модуль и аргумент . В компонент Memo1 выведем результаты: число в алгебраической форме, его аргумент и модуль . Ниже приведём текст модуля с комментариями, который демонстрирует работу с этим классом.
unit Unit1; interface uses Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls; type < TForm1 >TForm1 = class (TForm) Button1 : TButton; Edit1 : TEdit; Edit2 : TEdit; Label1 : TLabel; Label2 : TLabel; Label3 : TLabel; Memo1 : TMemo; procedure Button1Click ( Sender : TObject ); private < private declarations >public < public declarations >end; type //описание класса — комплексное число TComplex = class private x : real; //действительная часть y : real; //мнимая часть public constructor Create; //конструктор function Modul ( ) : real; //метод вычисления модуля function Argument ( ) : real; //метод вычисления аргумента //метод записи комплексного числа в виде строки function ComplexToStr ( ) : String; end; var Form1 : TForm1; //объявление переменной типа класс «комплексное число» chislo : TComplex; implementation //описание конструктора constructor TComplex. Create; begin x : = 0; y : = 0; //Вызов родительского конструктора inherited Create; end; //Описание метода вычисления //модуля комплексного числа. function TComplex.
Modul ( ) : real; begin modul:= sqrt ( x * x+y * y ); end; //Описание метода вычисления //аргумента комплексного числа. function TComplex. Argument ( ) : real; begin argument := arctan ( y/x ) * 180/ pi; end; //Описание метода записи комплексного //числа в виде строки. function TComplex. ComplexToStr ( ) : String; begin if y>=0 then ComplexToStr := FloatToStrF ( x, ffFixed,5,2)+ ’+ ’ + FloatTostrF ( y, ffFixed,5,2)+ ’ i ’ else ComplexToStr := FloatTostrF ( x, ffFixed,5,2)+ FloatTostrF ( y, ffFixed,5,2)+ ’ i ’ end; procedure TForm1.
Button1Click ( Sender : TObject ); var Str1 : String; begin //создание объекта (экземпляра класса) типа «комплексное число» chislo :=TComplex. Create; //ввод действительной и мнимой частей комплексного числа chislo. x:= StrToFloat ( Edit1. Text ); chislo. y:= StrToFloat ( Edit2. Text ); Str1 := ’ Kompleksnoe chislo ’+c h i s l o. ComplexToStr ( ); //вывод на форму в поле Memo1 построчно комплексного числа, Memo1. Lines. Add( Str1 ); //его модуля Str1 := ’ Modul chisla ’+ FloatToStrF ( chislo. Modul ( ), ffFixed, 5, 2 ); Memo1. Lines.
Add( Str1 ); //и аргумента Str1 := ’ Argument chisla ’+ FloatToStrF ( chislo. Argument ( ), ffFixed, 5, 2 ); Memo1. Lines. Add( Str1 ); //уничтожение объекта chislo. Free; end; initialization end.
Результат работы программы приведён на рис.
9.1.
Рис. 9.1. Результаты работы программы работы с классом «Комплексное число»
В этом примере был написан конструктор для класса » комплексное число » без параметров. В FreePascal можно писать конструктор с параметрами, который принимает входные значения и инициализирует поля класса этими значениями. Перепишем предыдущий пример следующим образом. Действительную и мнимую часть будем считывать из полей ввода формы и передавать в конструктор для инициализации объекта типа » комплексное число «. Листинг программы приведён ниже.
unit Unit1; interface uses Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls; type < TForm1 >TForm1 = class (TForm) Button1 : TButton; Edit1 : TEdit; Edit2 : TEdit; Label1 : TLabel; Label2 : TLabel; Label3 : TLabel; Memo1 : TMemo; procedure Button1Click ( Sender : TObject ); procedure Memo1Change ( Sender : TObject ); private < private declarations >public < public declarations >end; type TComplex = class private x, y : real; public //объявление конструктора constructor Create ( a, b : real ); function Modul ( ) : real; function Argument ( ) : real; function ComplexToStr ( ) : String; end; var Form1 : TForm1; chislo : TComplex; implementation //Конструктор, который получает в качестве //входных параметров два вещественных числа и записывает их //в действительную и мнимую часть комплексного числа constructor TComplex. Create ( a, b : real ); begin x:=a; y:=b; inherited Create; end; function TComplex.
Modul ( ) : real; begin modul:= sqrt ( x * x+y * y ); end; function TComplex. Argument ( ) : real; begin argument := arctan ( y/x ) * 180/ pi; end; function TComplex. ComplexToStr ( ) : String; begin if y>=0 then ComplexToStr := FloatToStrF ( x, ffFixed,5,2)+ ’+ ’ + FloatTostrF ( y, ffFixed,5,2)+ ’ i ’ else ComplexToStr := FloatTostrF ( x, ffFixed,5,2)+ FloatTostrF ( y, ffFixed,5,2)+ ’ i ’ end; procedure TForm1. Button1Click ( Sender : TObject ); var Str1 : String; x1, x2 : real; begin x1:= StrToFloat ( Edit1. Text ); x2:= StrToFloat ( Edit2. Text ); chislo :=TComplex.
Create ( x1, x2 ); chislo. x:= StrToFloat ( Edit1. Text ); chislo. y:= StrToFloat ( Edit2. Text ); Str1 := ’ Kompleksnoe _ c h i s l o _ ’+c h i s l o. ComplexToStr ( ); Memo1. Lines. Add( Str1 ); Str1 := ’ Modul chisla ’+ FloatToStrF ( chislo. Modul ( ), ffFixed, 5, 2 ); Memo1. Lines.
Add( Str1 ); Str1 := ’ Argument chisla ’+ FloatToStrF ( chislo. Argument ( ), ffFixed, 5, 2 ); Memo1. Lines. Add( Str1 ); chislo. Free; end; initialization end.
Источник: intuit.ru
Введение в объектно-ориентированное программирование
Объектно-ориентированное программирование (ООП) — это методика разработки программ, в основе которой лежит понятие объект. Объект — это некоторая структура, соответствующая объекту реального мира, его поведению. Задача, решаемая с использованием методики ООП, описывается в терминах объектов и операций над ними, а программа при таком подходе представляет собой набор объектов и связей между ними.
Строго говоря, для разработки приложения в Delphi на базе компонентов, предоставляемых средой разработки, знание концепции ООП не является необходимым. Однако материал данной главы будет весьма полезен для более глубокого понимания того, как программа взаимодействует с компонентами, что и почему Delphi добавляет в текст программы.
Знаете ли Вы, что, как не тужатся релятивисты, CMB (космическое микроволновое излучение) — прямое доказательство существования эфира, системы абсолютного отсчета в космосе, и, следовательно, опровержение Пуанкаре-эйнштейновского релятивизма, утверждающего, что все ИСО равноправны, а эфира нет. Это фоновое излучение пространства имеет свою абсолютную систему отсчета, а значит никакого релятивизма быть не может. Подробнее читайте в FAQ по эфирной физике.
Источник: www.bourabai.ru