Автор Анна Евкова
Преподаватель который помогает студентам и школьникам в учёбе.

Применение объектно-ориентированного подхода при проектировании информационной системы (Методы и средства)

Содержание:

ВВЕДЕНИЕ

ООП (Объектно-Ориентированное Программирование) стало неотъемлемой частью разработки многих современных проектов, но, не смотря на популярность, эта парадигма является далеко не единственной. Если вы уже умеете работать с другими парадигмами и хотели бы ознакомиться с оккультизмом ООП, то впереди вас ждет немного лонгрид и два мегабайта картинок и анимаций. В качестве примеров будут выступать трансформеры.

Объектно-ориентированный подход в последнее десятилетие стал одним из наиболее интенсивно развивающихся направлений в программировании и наиболее популярным средством разработки программного обеспечения [7].

Объектно-ориентированное программирование — это шаблон проектирования ПО, позволяющий решать задачи разработчика с точки зрения взаимодействия объектов. При этом большая часть объектно-ориентированных языков, например, Ruby, Python, Java, C++ наследуют на основе классов. Если говорить о JavaScript, то в нём ООП реализуется через прототипное наследование.

Наиболее удачное и популярное определение ООП звучит следующим образом — это методология программирования, которая основана на представлении программы в виде совокупности ряда объектов, причём каждый из этих объектов — это экземпляр определённого класса.

Начало развитию объектно-ориентированного подхода положил язык Simula 67, который был разработан в конце 60-х гг. в Норвегии. Несмотря на то, что язык намного опередил свое время, современники (программисты 60-х гг.) оказались не готовы воспринять ценности языка Simula 67, и он не выдержал конкуренции с другими языками программирования (прежде всего, с языком Fortran) [4].

Но достоинства языка Simula 67 были замечены некоторыми программистами, и в 70-е гг. было разработано большое число экспериментальных объектно-ориентированных языков программирования. В результате исследования этих языков были разработаны современные объектно-ориентированные языки программирования: C++, Ada, Smalltalk и др [9].

Вместе с развитием объектно-ориентированного программирования стали развиваться и объектно-ориентированные методы разработки программного обеспечения, охватывающие стадии анализа и проектирования. Среди общепризнанных объектно-ориентированных подходов к анализу и проектированию следует выделить методы Г. Буча [3, 4], Д. Рамбо, А. Джекобсона, Шлеера-Меллора и Коуда-Йордона. В результате объединения усилий первых трех авторов появился на свет унифицированный язык моделирования UML [2, 5, 7, 9], который в 1997 г. был принят в качестве стандарта консорциумом Object Management Group и получил широкое распространение в сфере производства программного обеспечения.

Объектно-ориентированный подход дает следующие основные преимущества:

  • уменьшение сложности программного обеспечения;
  • повышение его надежности;
  • обеспечение возможности модификации отдельных компонент программ без изменения остальных компонент;
  • обеспечение возможности повторного использования отдельных компонент программного обеспечения.

Систематическое применение объектно-ориентированного подхода позволяет разрабатывать хорошо структурированные, надежные в эксплуатации, достаточно просто модифицируемые программные системы. Этим объясняется интерес программистов к объектно-ориентированному подходу и объектно-ориентированным языкам программирования.

Целью данной работы является введение в объектно-ориентированный подход к разработке программного обеспечения.

Для достижения поставленной цели в работе рассматриваются такие понятия объектно-ориентированного программирования как классы и объекты, ассоциация, наследование, полиморфизм, инкапсуляция, абстракция, паттерны проектирования и фреймворки.

Объектом исследования является объектно-ориентированная парадигма программирования. Предметом исследования – объектно-ориентированные языки программирования.

Структурно работа состоит из введения, заключения

1. ОБЗОР ЭЛЕМЕНТОВ ОБЪЕКТНО-ОРИЕНТИРОВАННОГО ПРОГРАММИРОВАНИЯ И ИХ СВОЙСТВ

1.1 Классы и объекты

Сразу лирическое отступление: объектно-ориентированный подход возможен и без классов, но мы будем рассматривать, извиняюсь за каламбур, классическую схему, где классы — наше всё.

Самое простое объяснение: класс — это чертеж трансформера, а экземпляры этого класса — конкретные трансформеры, например, Оптимус Прайм или Олег. И хотя они и собраны по одному чертежу, умеют одинаково ходить, трансформироваться и стрелять, они оба обладают собственным уникальным состоянием. Состояние — это ряд меняющихся свойств. Поэтому у двух разных объектов одного класса мы можем наблюдать разное имя, возраст, местоположение, уровень заряда, количество боеприпасов и т. д. Само наличие этих свойств и их типы описываются в классе.

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

Мы говорим «свойства и поведение», но звучит это как-то абстрактно и непонятно. Привычнее для программиста будет звучать так: «переменные и функции». На самом деле «свойства» — это такие же обычные переменные, просто они являются атрибутами какого-то объекта (их называют полями объекта). Аналогично «поведение» — это функции объекта (их называют методами), которые тоже являются атрибутами объекта. Разница между методом объекта и обычной функцией лишь в том, что метод имеет доступ к собственному состоянию через поля.

Итого, имеем методы и свойства, которые являются атрибутами. Как работать с атрибутами? В большинстве ЯП оператор обращения к атрибуту — это точка (кроме PHP и Perl). Выглядит это примерно вот так (псевдокод):Объектно-ориентированное программирование (сокращенно ООП) - это парадигма разработки программных систем, в которой приложения состоят из объектов [6].

Объекты - это сущности, у которых есть свойства и поведение. Обычно объекты являются экземплярами какого-нибудь класса. Например, в игре может быть класс Character (персонаж), а его экземплярами будут hero или npc.

Свойства - это данные, которые связаны с конкретным объектом:

  • здоровье;
  • очки;
  • деньги;
  • сила;
  • ловкость;
  • интеллект;
  • скорость;
  • координаты [6].

Поведение объекта определяется с помощью методов - специальных блоков кода, которые можно вызывать из разных частей программы. Например, у того же объекта Character могут быть следующие методы:

  • идти;
  • атаковать;
  • говорить;
  • подобрать;
  • выбросить;
  • использовать.

Используя эти свойства и методы, можно значительно ускорить разработку, сделать код более читаемым. К тому же самому программисту проще составлять код, если он думает с помощью объектов [6].

То есть он не пишет какую-то функцию, которая будет делать что-то для программы в целом. Вместо этого он мысленно разделяет приложение на отдельные компоненты и продумывает их свойства и поведение. Такую парадигму используют многие популярные языки: C#, Java, Python, JavaScript, PHP, Swift, C++ (таблица 1).

Таблица 1 - Плюсы и минусы объектно-ориентированного программирования

Плюсы

Минусы

Легко читается. Не нужно выискивать в коде функции и выяснять, за что они отвечают.

Потребляет больше памяти. Объекты потребляют больше оперативной памяти, чем примитивные типы данных.

Быстро пишется. Можно быстро создать сущности, с которыми должна работать программа.

Снижает производительность. Многие вещи технически реализованы иначе, поэтому они используют больше ресурсов.

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

Сложно начать. Парадигма ООП сложнее функционального программирования, поэтому на старт уходит больше времени.

Меньше повторений. Не нужно писать однотипные функции для разных сущностей

Изучая C#, разработчик в первый же день сталкивается с классами и объектами. Например, вот как выглядит первая программа любого новичка:

using System;

namespace OOPConsole

{

class Program

{

static void Main(string[5] args)

{

Console.WriteLine(«Hello World!»);

}

}

}

Здесь создается класс Program, у которого есть метод Main () - с него начинается выполнение программы, поэтому его называют точкой входа. Для вывода текста используется следующий оператор:

Console.WriteLine(«Hello, World!»);

Тут программа обращается к объекту Console и вызывает метод WriteLine (), который выводит переданное значение в консоль. Также у объекта Console есть разные свойства:

Console.ForegroundColor = ConsoleColor.Red; // Цвет шрифта - красный

Console.BackgroundColor = ConsoleColor.Blue; // Цвет фона - синий

Если бы не было объекта, было бы сложно определить, цвет какого фона и какого шрифта будет указываться, потому что их в программе может быть несколько.

Теперь можно добавить поля и свойства для класса. Поле объявляется как обычная переменная:

class Character

{

int health = 100;

int x = 50;

int y = 25;

}

Теперь у объекта есть свои поля, но к ним нельзя обратиться извне, потому что закрыт доступ (подробнее об этом - в статье про инкапсуляцию). Чтобы его открыть, нужно поставить перед каждым полем ключевое слово public. То же слово нужно поставить перед словом class.

public class Character

{

public int health = 100;

public int x = 50;

public int y = 25;

}

Теперь можно вернуться к созданному объекту и обратиться к его полю здоровья:

Console.WriteLine(hero.health);

Если доступ к полям открыт, то с ними можно проводить вычисления или просто получать их значение. Это специальные конструкции, которые позволяют обращаться к полям [6]. Чтобы создать свойства, нужно сначала закрыть доступ к полям с помощью уровня доступа private - тогда они будут доступны только изнутри класса:

public class Character

{

private int health = 100;

private int x = 50;

private int y = 25;

}

Методы являются аналогами функций (возвращают значение) и процедур (не возвращают), но с той разницей, что они являются частью какого-то класса [6]. Например, можно в классе Character создать метод Move (), который будет отвечать за движение персонажа.

public void Move(string direction)

{

switch (direction)

{

case «forward»:

this.x++;

break;

case «backward»:

this.x--;

break;

case «up»:

this.y++;

break;

case «down»:

this.y--;

break;

}

}

Сначала указывается уровень доступа public, затем тип возвращаемого значения (в данном случае используется void, что говорит компилятору о том, что ничего возвращать не нужно).

Затем идет название метода и круглые скобки. Внутри скобок указываются аргументы, которые принимает метод (в данном случае направление движения), - от переданных аргументов зависит результат работы метода [6].

Таким образом, были рассмотрены классы и объекты объектно-ориентированного программирования.

1.2 Ассоциация

Ассоциация означает, что объекты двух классов могут ссылаться один на другой, иметь некоторую связь между друг другом. Например, менеджер может выписать Счет. Соответственно возникает ассоциация между Менеджером и Счетом. Еще пример - Преподаватель и Студент - т.е. какой-то Студент учится у какого-то Преподавателя.

Ассоциация и есть описание связи между двумя объектами. Студент учится у Преподавателя. Идея достаточно простая - два объекта могут быть связаны между собой и это надо как-то описать [4].

Агрегация и композиция на самом деле являются частными случаями ассоциации. Это более конкретизированные отношения между объектами. Агрегация – отношение, когда один объект является частью другого. Например, студент входит в группу любителей физики [2].

Композиция - еще более «жесткое отношение, когда объект не только является частью другого объекта, но и вообще не может принадлежат еще кому-то. Например, машина и двигатель.

Хотя двигатель может быть и без машины, но он вряд ли сможет быть в двух или трех машинах одновременно. В отличии от студента, который может входить и в другие группы тоже. Такие описания всегда несколько условны, но тем не менее [8].

Таким образом, на самом деле каких-либо сложных и высокоумных технических решений нет - все достаточно тривиально. В одном классе делается ссылка на другой и наоборот.

1.3 Наследование

Наследование (inheritance) - это процесс, посредством которого один объект может приобретать свойства другого. Точнее, объект может наследовать основные свойства другого объекта и добавлять к ним черты, характерные только для него. Наследование является важным, поскольку оно позволяет поддерживать концепцию иерархии классов (hierarchical classification). Применение иерархии классов делает управляемыми большие потоки информации [1].

Например, подумайте об описании жилого дома. Дом - это часть общего класса, называемого строением. С другой стороны, строение - это часть более общего класса - конструкции, который является частью ещё более общего класса объектов, который можно назвать созданием рук человека.

В каждом случае порождённый класс наследует все, связанные с родителем, качества и добавляет к ним свои собственные определяющие характеристики. Без использования иерархии классов, для каждого объекта пришлось бы задать все характеристики, которые бы исчерпывающи его определяли.

Таким образом, при использовании наследования можно описать объект путём определения того общего класса (или классов), к которому он относится, с теми специальными чертами, которые делают объект уникальным. Наследование играет очень важную роль в OOP.

2. ОСНОВНЫЕ ПОНЯТИЯ ОБЪЕКТНО-ОРИЕНТИРОВАННОГО ПРОГРАММИРОВАНИЯ

2.1 Полиморфизм

Полиморфизм (polymorphism) (от греческого polymorphos) - это свойство, которое позволяет одно и то же имя использовать для решения двух или более схожих, но технически разных задач.

Целью полиморфизма, применительно к объектно-ориентированному программированию, является использование одного имени для задания общих для класса действий. Выполнение каждого конкретного действия будет определяться типом данных [1].

Например для языка Си, в котором полиморфизм поддерживается недостаточно, нахождение абсолютной величины числа требует трёх различных функций: abs(), labs() и fabs(). Эти функции подсчитывают и возвращают абсолютную величину целых, длинных целых и чисел с плавающей точкой соответственно. В С++ каждая из этих функций может быть названа abs().

Тип данных, который используется при вызове функции, определяет, какая конкретная версия функции действительно выполняется. В С++ можно использовать одно имя функции для множества различных действий. Это называется перегрузкой функций (function overloading) [4].

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

Преимуществом полиморфизма является то, что он помогает мнижать сложность программ, разрешая использование того же интерфейса для задания единого класса действий.

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

Полиморфизм может применяться также и к операторам. Фактически во всех языках программирования ограниченно применяется полиморфизм, например, в арифметических операторах.

Так, в Си, символ + используется для складывания целых, длинных целых, символьных переменных и чисел с плавающей точкой [3]. В этом случае компилятор автоматически определяет, какой тип арифметики требуется. В С++ можно применить эту концепцию и к другим, заданным типам данных. Такой тип полиморфизма называется перегрузкой операторов (operator overloading).

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

2.2 Инкапсуляция

Инкапсуляция (encapsulation) - это механизм, который объединяет данные и код, манипулирующий этими данными, а также защищает и то, и другое от внешнего вмешательства или неправильного использования.

В объектно-ориентированном программировании код и данные могут быть объединены вместе; в этом случае говорят, что создаётся так называемый «чёрный ящик» [4].

Когда коды и данные объединяются таким способом, создаётся объект (object). Другими словами, объект - это то, что поддерживает инкапсуляцию.

Внутри объекта коды и данные могут быть закрытыми (private). Закрытые коды или данные доступны только для других частей этого объекта. Таким образом, закрытые коды и данные недоступны для тех частей программы, которые существуют вне объекта. Если коды и данные являются открытыми, то, несмотря на то, что они заданы внутри объекта, они доступны и для других частей программы [5]. Характерной является ситуация, когда открытая часть объекта используется для того, чтобы обеспечить контролируемый интерфейс закрытых элементов объекта.

Таким образом, объект является переменной определённого пользователем типа. Может показаться странным, что объект, который объединяет коды и данные, можно рассматривать как переменную. Однако применительно к объектно-ориентированному программированию это именно так. Каждый элемент данных такого типа является составной переменной.

2.3 Абстракция

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

Абстракция данных - это метод программирования (и проектирования), который основан на разделении интерфейса и реализации [2]. Возьмем один реальный пример телевизора, который можно включить и выключить, изменить канал, отрегулировать громкость и добавить внешние компоненты, такие как динамики, видеомагнитофоны и проигрыватели DVD,

Но, не известны его внутренние детали, не известно как он получает сигналы по воздуху или по кабелю, как он их переводит, и, наконец, отображает их на экране.

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

В C ++ классы обеспечивают отличный уровень абстракции данных. Они обеспечивают достаточные общественные методы внешнему миру, чтобы играть с функциональностью объекта и манипулировать объектными данными, то есть состоянием, не зная, каким образом класс был реализован внутри страны [7].

Например, программа может сделать вызов функции sort (), не зная, какой алгоритм фактически использует функция для сортировки данных значений. Фактически, базовая реализация функции сортировки может меняться между версиями библиотеки, и пока интерфейс остается прежним, ваш вызов функции будет работать. В C ++ используем классы для определения наших собственных абстрактных типов данных (ADT). Можно использовать объект cout класса ostream для потоковой передачи данных на стандартный вывод следующим образом:

#include <iostream>

using namespace std;

int main() {

cout << «Hello C++»<<endl;

return 0;

}

Здесь не нужно понимать, как cout отображает текст на экране пользователя. Нужно знать только открытый интерфейс, а базовая реализация «cout»может быть изменена.

В C ++ используем метки доступа для определения абстрактного интерфейса для класса. Класс может содержать ноль или более ярлыков доступа. Члены, определенные с помощью общедоступного ярлыка, доступны для всех частей программы.

Представление абстракции данных типа определяется его публичными членами. Члены, определенные с помощью частного ярлыка, недоступны для кода, который использует класс. Частные разделы скрывают реализацию от кода, который использует этот тип. Нет ограничений на то, как часто может появляться метка доступа [9]. Каждая метка доступа указывает уровень доступа следующих определений элементов. Указанный уровень доступа остается в силе до тех пор, пока не встретится следующая метка доступа или не увидит закрытие правой скобки тела класса.

Абстракция данных обеспечивает два важных преимущества -

  1. Внутренние элементы класса защищены от непреднамеренных ошибок на уровне пользователя, что может привести к повреждению состояния объекта.
  2. Реализация класса может развиваться со временем в ответ на изменение требований или отчетов об ошибках без изменения кода пользователя.

Определяя члены данных только в приватном разделе класса, автор класса может вносить изменения в данные. Если реализация меняется, необходимо изучить только код класса, чтобы увидеть, что может повлиять на изменение.

Если данные общедоступны, то любая функция, которая напрямую обращается к элементам данных старого представления, может быть нарушена. Любая программа на C++, где реализуется класс с общедоступными и частными членами, является примером абстракции данных [6].

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

3. РАЗРАБОТКА ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ С ПРИМЕНЕНИЕМ ОБЪЕКТНО-ОРИЕНТИРОВАННОГО ПРОГРАММИРОВАНИЯ

3.1 Паттерны проектирования

Паттерн (от англ. Pattern) - образец, шаблон. Шаблоны не связаны с каким-либо конкретным языком программирования. Это просто подход к проектированию чего-то. Если заглянуть глубже, то многие ООП-паттерны были созданы на основе реальных жизненных ситуаций при проектировании вполне осязаемых объектов в нашем мире [5]. Именно на таких метафорах и описаниях будет построена следующая экспозиция.

1. Порождающие паттерны

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

Singleton (одиночка)

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

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

Соответственно, чтобы добавить нового резидента, вам нужно будет только изменить записи на самой телефонной станции. Как только вы создадите телефонную станцию, ею сможет пользоваться каждый и только один из нее, в свою очередь, эта станция помнит все, что с ней произошло с момента ее создания и каждый может воспользоваться этой информацией, даже если он только что прибыл в город.

Registry (реестр, журнал записей)

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

Multiton (пул «одиночек»)

Как следует из названия паттерна, он по существу является «реестром», содержащим несколько «одиночек», каждая из которых имеет свое собственное «имя», по которому к ней можно получить доступ.

Object pool (пул объектов)

По аналогии с «пулом одиночек» данный паттерн также позволяет хранить уже готовые объекты, однако они не обязаны быть «одиночками».

Factory (фабрика)

Суть паттерна почти полностью описана его названием. Когда вам нужно получить некоторые предметы, такие как пакеты сока, вам не нужно знать, как они сделаны на заводе. Дается команда «сделай мне пакет апельсинового сока», и «фабрика» возвращает нужный пакет. Главное назначение «фабрики»- иметь возможность при необходимости изменить процесс «внешнего вида» упаковки сока, а самому потребителю не нужно было об этом сообщать, чтобы он запросил ее, как и раньше.

Builder (строитель)

Этот паттерн очень тесно переплетается с «фабричным» паттерном. Главное отличие заключается в том, что «конструктор »внутри себя обычно содержит все сложные операции по созданию объекта (сок-пакет). Дается команда «я хочу сок», и строитель начинает целую цепочку различных операций (создание пакета, печать на нем изображений, наполнение его соком, учет количества созданных пакетов и т. д.).). Если вам нужен другой сок, например ананасовый, то точно так же это как раз то, что вам нужно, и «Строитель» позаботится об остальном (некоторые процессы повторятся, некоторые сделают снова и т. д.). В свою очередь процесс в «Строителе» можно легко изменить (например, изменить рисунок на упаковке), но потребители знают, что сок не требуется, легко требовать пакет сока по тому же запросу.

Prototype (прототип)

Этот паттерн чем-то похож на «фабрику», он также служит для создания объектов, но с несколько иным подходом. Представьте себе, что у вас есть пустой пакет (из-под сока), а вам нужен полный с апельсиновым соком. На пакет дается команда «я хочу пакет апельсинового сока», он в свою очередь создает свою собственную копию и наполняет ее тем соком, который был запрошен. Немного «сказочный пример», но в программировании это часто случается. В этом случае пустой пакет является «прототипом», и в зависимости от того, что требуется, он создает на его основе необходимые объекты (пакеты сока). Клонирование не обязательно должно выполняться на самом «пакете», это также может быть какой-то другой объект, главное, что этот прототип «позволяет получить его экземпляры.

Factory method (фабричный метод)

Данный паттерн довольно сложно объяснить в метафорах, но всё же попробую.

Ключевой сложностью объяснения данного паттерна является то, что это «метод», поэтому метафора метода будет использовано как действие, то есть например слово «Хочу!». Соответственно, паттерн описывает то, как должно выполнятся это «Хочу!».

Допустим ваша фабрика производит пакеты с разными соками. Теоретически мы можем на каждый вид сока делать свою производственную линию, но это не эффективно. Удобнее сделать одну линию по производству пакетов-основ, а разделение ввести только на этапе заливки сока, который мы можем определять просто по названию сока. Однако откуда взять название?

Для этого мы создаем основной отдел по производству пакетов-основ и предупреждаем все под-отделы, что они должны производить нужный пакет с соком про простому «Хочу!» (т.е. каждый под-отдел должен реализовать паттерн «фабричный метод»). Поэтому каждый под-отдел заведует только своим типом сока и реагирует на слово «Хочу!».

Таким образом если нам потребуется пакет апельсинового сока, то мы просто скажем отделу по производству апельсинового сока «Хочу!», а он в свою очередь скажет основному отделу по созданию пакетов сока, «Сделай ка свой обычный пакет и вот сок, который туда нужно залить».

Lazy initialization (отложенная инициализация)

Иногда требуется что-то иметь под рукой, на всякий случай, но не всегда хочется прилагать каждый раз усилия, чтобы это каждый раз получать/создавать. Для таких случаев используется паттерн «отложенная инициализация». Допустим вы работаете в бухгалтерии и для каждого сотрудника вы должны подготавливать «отчет о выплатах». Вы можете в начале каждого месяца делать этот отчет на всех сотрудников, но некоторые отчеты могут не понадобиться, и тогда скорее всего вы примените «отложенную инициализацию», то есть вы будете подготавливать этот отчет только тогда, когда он будет запрошен начальством (вышестоящим объектом), однако начальство по сути в каждый момент времени может сказать что у него этот отчет уже есть, однако готов он уже или нет, оно не знает и знать не должно. Как вы уже поняли, данный паттерн служит для оптимизации ресурсов.

Dependency injection (внедрение зависимости)

Внедрение зависимости позволяет переложить часть ответственности за какой-то функционал на другие объекты. Например если нам требуется нанять новый персонал, то мы можем не создавать свой отдел кадров, а внедрить зависимость от компании по подбору персонала, которая свою очередь по первому нашему требованию «нам нужен человек», будет либо сама работать как отдел кадров, либо же найдет другую компанию (при помощи «локатора служб»), которая предоставит данные услуги.

«Внедрение зависимости» позволяет перекладывать и взаимозаменять отдельные части компании без потери общей функциональности.

Service Locator (локатор служб)

«Локатор служб» является методом реализации «внедрения зависимости». Он возвращает разные типы объектов (компаний) в зависимости от кода инициализации. Пускай задача стоит доставить наш пакет сока, созданный строителем, фабрикой или ещё чем, куда захотел покупатель. Мы спрашиваем у локатора «дай нам службу доставки», и он нам соединяет на со службой доставки по номеру телефона, который директор ему дал (потому что получает откат они нам дают скидку как постоянным клиентам), а мы уже просим службу доставить сок по нужному адресу. Сегодня одна служба, а завтра может быть другая. Нам без разницы какая это конкретно служба, решение принимает директор и сообщает об этом локатору служб, нам важно знать лишь что они могут доставлять то, что мы им скажем туда, куда скажем, то есть службы реализуют интерфейс «Доставить <предмет> на <адрес>».

2. Структурирующие паттерны

Эти паттерны помогают навести порядок и научить различные объекты более правильно взаимодействовать друг с другом.

Adapter или wrapper (адаптер, обертка)

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

Composite (компоновщик)

Довольно интересная закономерность, которая сводит к минимуму различия в управлении как группами объектов, так и отдельными объектами. Например, можно рассмотреть управление солдатами в строю. Существует Строевой устав, который определяет, как управлять формированием и согласно этому уставу, не имеет значения, кому отдается приказ (например, «шаг Марш») одному солдату или целому взводу. Соответственно, Устав (если его рассматривать в чистом виде как образец «линкера») не может включать команду, которая может быть выполнена только одним солдатом, но не может быть выполнена группой или наоборот.

Decorator (декоратор, оформитель)

Как следует из названия, этот шаблон чаще всего используется для расширения исходного объекта до желаемого внешнего вида. Например, мы можем условно считать человека с кистью и красной краской «декоратором». Таким образом, какой бы объект (или определенный тип объекта) мы ни передали в руки «декоратора», на выходе мы получим красные объекты.

3. Паттерны поведения

Эта группа паттернов позволяет структурировать подходы к обработке поведения и взаимодействия объектов. Проще говоря, как должны проходить процессы в которых существует несколько вариантов протекания событий.

Command или action (команда, действие)

Шаблон «команда» очень похож в реальной жизни на кнопки на выключателях света в наших квартирах и домах. Каждый коммутатор по существу выполняет одно простое действие-разъединяет или соединяет два провода, но что находится за этими проводами, коммутатор не знает. Что связано, то и произойдет. Шаблон «команда» также работает таким же образом. Он определяет только общие правила для объектов (устройств), в виде соединения двух проводов для выполнения команды, а то, что именно будет выполнено, уже определяется самим устройством (объектом).

Servant (слуга)

Как следует из названия, этот шаблон используется для предоставления группе объектов некоторой общей функциональности. Например, телефонная станция является «слугой» для жителей города, когда дело доходит до выяснения точного времени.

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

3.2 Фреймворки

Фреймворк (фреймворк, «фреймворк», «конструкция») - это динамически пополняемая библиотека языка программирования, содержащая его основные модули. Фреймворки создаются для упрощения разработки приложений, сайтов и сервисов. Чтобы избежать написания модуля в приложении с нуля, гораздо проще обратиться к готовым шаблонам фреймворка, которые формируют рабочую среду разработчика [9].

Каждый язык программирования имеет фреймворки-Java, JavaScript, Python, Ruby и PHP. Но именно PHP-фреймворки занимают почетное место в качестве основного инструмента для разработки бэкенда.

Преимущества фреймворков [4]

1. Представление. Фреймворки ускоряют развитие. Например, фреймворк PHP избавляет вас от необходимости писать запросы к базам данных. Фреймворки реализуют базовые функции CRUD, необходимые для работы с базами данных.

2. Масштабируемость. Приложения, написанные на фреймворках, легко масштабируются.

3. Удобство. Код фреймворка лаконичен, поэтому с ним легко работать. Проще поддерживать проект в рамках фреймворка, чем на родном языке.

4. Простота. Фреймворки используют шаблоны проектирования. Это значительно упрощает разработку, делая процесс более быстрым.

5. Безопасность. Приложения на фреймворках лучше защищены.

6. Эффективность. Каркас реализует сухой принцип. Это позволяет разработчикам писать меньше кода.

Какой фреймворк PHP является наиболее подходящим, зависит от объема и целей проекта. При выборе такой платформы следует обратить внимание на ряд базовых показателей.

1. Насколько широка и гибка функциональность фреймворка. Содержит ли он все, что может потребоваться для текущего проекта.

2. Легко ли выучить фреймворк? Исходя из уровня штатного (внештатного) разработчика.

3. Скорость и современность-насколько фреймворк ориентирован на прогрессивные методы программирования. Например, существует ли поддержка объектно-ориентированного метода.

4. Как масштабируется проект, созданный на фреймворке. Возможно ли написать структурированный код для масштабируемых приложений.

5. Как часто выпускаются обновления и есть ли у платформы активное сообщество.

6. Имеет ли фреймворк гарантированную долгосрочную службу поддержки релизов (LTS)?

7. Есть ли поддержка архитектуры MVC (Model ViewController / Model-view-controller).

Фреймворк Laravel

Эта бесплатная платформа является одним из самых популярных фреймворков PHP, благодаря своей активной разработке и простоте разработки. Новичкам, решившим освоить его впервые, предоставляются комфортные условия для постепенного погружения в область веб-разработки по широкому спектру задач: от обычных рутинных задач до сложных интеграционных проектов и масштабирования приложений. Благодаря этой расширенной функциональности Laravel может помочь вам решить целый ряд бэкенд-задач даже без большого опыта работы [7].

Yii

Объектно-ориентированный PHP-фреймворк Yii считается лидером по производительности и часто выбирается для высоконагруженных приложений. С момента своего первого выпуска в 2008 году эта структура постоянно развивалась на протяжении многих лет. Yii часто входит в топ PHP фреймворков, благодаря высокоразвитому сообществу пользователей, значительная часть которых являются русскоязычными.

CodeIgniter

Этот фреймворк с открытым исходным кодом отличается элегантностью кода и простотой написания. Простота обучения и свобода разработки кода обеспечивают отличные условия для быстрого старта проекта. CodeIgniter отлично подходит для создания небольших PHP-приложений, которые можно легко масштабировать.

Фреймворк symfony

В дополнение к своему звучному названию, этот фреймворк обладает гибкой функциональностью, основанной на модульном подходе к построению системы. Это позволяет выбрать необходимые функции языка PHP или управлять всей инфраструктурой.

Эта структура будет сбалансированным решением для разработчика, который ценит модульность и преимущество использования отдельных компонентов. Веб-приложения Symfony отличаются впечатляющей производительностью, поэтому они используются для решения сложных задач на уровне предприятия [6].

Фреймворк Zend

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

SlimCarcass

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

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

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

ЗАКЛЮЧЕНИЕ

Основные идеи объектно-ориентированного подхода опираются на следующие положения:

  • программа представляет собой модель некоторого реального процесса, части реального мира; модель содержит не все признаки и свойства представляемой ею части реального мира, а только те, которые существенны для разрабатываемой программной системы;
  • модель реального мира или его части может быть описана как совокупность взаимодействующих между собой объектов;
  • объект описывается набором атрибутов (свойств), значения которых определяют состояние объекта, и набором операций (действий), которые может выполнять объект;
  • взаимодействие между объектами осуществляется посылкой специальных сообщений от одного объекта к другому; сообщение, полученное объектом, может потребовать выполнения определенных действий, например изменения состояния объекта;
  • объекты, описанные одним и тем же набором атрибутов и способные выполнять один и тот же набор операций, представляют собой класс однотипных объектов.

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

СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ

  1. Бретт, Маклафлин Объектно-ориентированный анализ и проектирование / Маклафлин Бретт. - М.: Питер, 2018. - 324 c.
  2. Вайсфельд, Мэтт Объектно-ориентированное мышление / Мэтт Вайсфельд. - М.: Питер, 2019. - 387 c.
  3. Джонсон, Ральф Приемы объектно-ориентированного проектирования. Паттерны проектирования / Ральф Джонсон. - М.: Питер, 2017. - 122 c.
  4. Зандстра, Мэтт PHP. Объекты, шаблоны и методики программирования / Мэтт Зандстра. - М.: Вильямс, 2020. - 576 c.
  5. Йордон, Эдвард Объектно-ориентированный анализ и проектирование систем / Эдвард Йордон , Карл Аргила. - М.: ЛОРИ, 2020. - 264 c.
  6. Колесов, Ю. Б. Объектно-ориентированное моделирование в среде Rand Model Designer 7 / Ю.Б. Колесов, Ю.Б. Сениченков. - М.: Проспект, 2019. - 256 c.
  7. Комлев, Николай Юрьевич Объектно Ориентированное Программирование. Хорошая книга для Хороших Людей / Комлев Николай Юрьевич. - М.: Солон-Пресс, 2019. - 499 c.
  8. Лафоре, Роберт Объектно-ориентированное программирование в С++ / Роберт Лафоре. - М.: Питер, 2019. - 928 c.
  9. Маклафлин, Б. Объектно-ориентированный анализ и проектирование / Б. Маклафлин, Г. Поллайс, Д. Уэст. - М.: Питер, 2020. - 891 c.
  10. Приемы объектно-ориентированного проектирования: Паттерны проектирования / Э. Гамма и др. - М.: Addison Wesley Longman, Inc., 2019. - 368 c.
  11. Фридман, А. Л. Объектно-ориентированное программирование на языке Си++ / А.Л. Фридман. - Москва: Наука, 2017. - 234 c.
  12. Эллайн, Алекс C++. От ламера до программера / Алекс Эллайн. - М.: Питер, 2019. - 935 c.