Обновить
39.75

ООП *

Объектно-ориентированное программирование

Сначала показывать
Порог рейтинга
Уровень сложности

Как устроен фреймворк tiOPF для delphi/lazarus. Шаблон «Посетитель»

Время на прочтение23 мин
Количество просмотров4.8K

От переводчика


Есть две причины, по которым я взялся перевести несколько материалов по разработанному двадцать лет назад для не самой популярной ныне среды программирования фреймворку:

1. Несколько лет назад я, познав многие прелести работы с Entity Framework как ORM для платформы .Net, тщетно искал аналоги для среды Lazarus и в общем для freepascal.
Удивительно, но хорошие ORM для нее отсутствуют. Всё, что тогда удалось найти — open-source проект под названием tiOPF, разработанный еще в конце 90-х годов для delphi, позже портированный под freepascal. Однако этот фреймворк коренным образом отличается от привычного вида больших и толстых ORM.

Визуальные способы проектирования объектов (в Entity — model first) и сопоставления объектов с полями таблиц реляционной базы данных (в Entity — database first) в tiOPF отсутствуют. Разработчик сам позиционирует этот факт как один из недостатков проекта, однако в качестве достоинства предлагает полную ориентацию именно на объектную бизнес-модель, стоит лишь один раз похардкодить…
Читать дальше →

ООП мертво, да здравствует ООП

Время на прочтение18 мин
Количество просмотров61K
image

Источники вдохновения


Этот пост возник благодаря недавней публикации Араса Пранцкевичуса о докладе, предназначенном для программистов-джуниоров. В нём рассказывается о том, как адаптироваться к новым ECS-архитектурам. Арас следует привычной схеме (объяснения ниже): показывает примеры ужасного ООП-кода, а затем демонстрирует, что отличным альтернативным решением является реляционная модель (но называет её «ECS», а не реляционной). Я ни в коем случае не критикую Араса — я большой фанат его работ и хвалю его за отличную презентацию! Я выбрал именно его презентацию вместо сотен других постов про ECS из Интернета потому, что он приложил дополнительные усилия и опубликовал git-репозиторий для изучения параллельно с презентацией. В нём содержится небольшая простая «игра», используемая в качестве примера выбора разных архитектурных решений. Этот небольшой проект позволил мне на конкретном материале продемонстрировать свои замечания, так что спасибо, Арас!

Слайды Араса выложены здесь: http://aras-p.info/texts/files/2018Academy — ECS-DoD.pdf, а код находится на github: https://github.com/aras-p/dod-playground.

Я не буду (пока?) анализировать получившуюся ECS-архитектуру из этого доклада, но сосредоточусь на коде «плохого ООП» (похожего на уловку «чучело») из его начала. Я покажу, как бы он выглядел на самом деле, если бы правильно исправили все нарушения принципов OOD (object-oriented design, объектно-ориентированного проектирования).

Спойлер: устранение всех нарушений OOD приводит к улучшениям производительности, аналогичным преобразованиям Араса в ECS, к тому же использует меньше ОЗУ и требует меньше строк кода, чем ECS-версия!

TL;DR: Прежде чем прийти к выводу, что ООП отстой, а ECS рулит, сделайте паузу и изучите OOD (чтобы знать, как правильно использовать ООП), а также разберитесь в реляционной модели (чтобы знать, как правильно применять ECS).
Читать дальше →

KISS Architecture. От микросервиса до монолита

Время на прочтение3 мин
Количество просмотров8K

Андрей Копылов, наш технический директор, рассказывает, какой подход к проектированию архитектуры приложений использует команда веб-разработчиков AREALIDEA, и, чем KISS Architecture, его собственная разработка, так хороша.


Читать дальше →

Внутренние и вложенные классы java. Часть 3

Время на прочтение11 мин
Количество просмотров28K
Внутренние и вложенные классы java. Часть 3
Локальные классы

<<< Часть 1
<<< Часть 2

Локальный класс — это вложенный класс, объявленный внутри другого класса и некоторого блока кода этого класса, то есть объявленный между фигурными скобками {}. Этот блок может быть статическим блоком, циклом, телом if и т.д.

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

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

Напишем пример:

/*Учебный пример №12 */
package localclasses;

/**
 *
 * @author Ar20L80
 */
public class OuterStaticInit {
     static 
     { 
         class LocalInit{
         LocalInit(){
         System.out.println("From static iniz"); 
         }
         }
     LocalInit localInit = new LocalInit();
     System.exit(0); 
     } 
     public static void main(String[] args) {
        System.out.println("From main"); 
    }
}




В нашем примере локальный класс «просуществовал» только в области локальной статичной инициализации. Тело «main» не было вызвано. Единственный модификатор, который допускается применять в объявлении локального класса, – это final, предотвращающий, как обычно, возможность расширения класса. Члены локального класса могут быть объявлены как закрытыми, так и открытыми. К ним применяются модификаторы, которые применимы к обычному классу.( java 8)

Еще раз повторим коротко: Локальный класс – это класс, объявленный в блоке Java кода.

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

/**
 * Учебный пример №13
 * @author Ar20L80
 */
public class OuterLocal {
    OuterLocal(){
        // начало блока конструктора

        /*объявление локального класса в конструкторе OuterLocal*/
        class LocalInnerClass {
            LocalInnerClass(){}
        }
    /* создаем экземпляр в том же блоке*/
        LocalInnerClass localObj = new LocalInnerClass();
      // окончание блока конструктора
    }



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

 
 /**
 * Учебный пример №14
 * @author Ar20L80
 */
public class OuterLocal {
    OuterLocal(){
        
        /*объявление локального класса в конструкторе OuterLocal*/
        class LocalInnerClass {
            LocalInnerClass(){}
        }
    /* создаем экземпляр в том же блоке*/
        LocalInnerClass localObj = new LocalInnerClass();
    }
    
    
    public static void main(String[] args) {
       //  LocalInnerClass localObj = new LocalInnerClass(); не можем создать объект локального класса 
	   // вне области видимости содержащего его блока
    }
}
 
 



Свойства локального класса:
Подобно вложенным нестатическим классам, локальные классы связаны с окружающим экземпляром и имеют доступ ко всем членам, включая private члены окружающего класса. Локальный класс нельзя объявить с каким-либо модификатором доступа, кроме как static final.

 /*Учебный пример пример №15 */
public class OuterStaticLocal {
    
	OuterStaticLocal(){
	   // static class Local{}  ошибка не может быть статичным
	}
} 



Потому что, модификаторы доступа для членов класса мы можем применять только к членам класса. Эти модификаторы не доступны для объявления локальных переменных или классов, находящихся в блоке и не являющиеся членами класса.

  /**
 * Учебный пример №16 
 * @author Ar20L80
 */
public class OuterLocal2 {
    OuterLocal2(){
      final  class LocalInnerClass {
            LocalInnerClass(){}
        }
    }
} 


Как и нестатические вложенные классы, и по тем же причинам, локальные классы не могут иметь static поля, исключение составляют константы, объявленные как static final.

 /**
 *  Учебный пример №17
 
 * @author Ar20L80
 * тут я вернул переменную локального класса через iTemp внешнего класса
 */
public class OuterClass {
     
    private int iTemp;
    OuterClass(){
    // объявим внутри конструктора класс
    
    /* здесь мы не можем использовать private, public
    применительно к локальному классу*/
     final  class LocalInnerClass01{ 
      /* сам локальный класс может содержать 
         как private, так и public */
      private static final int INT_FIN = 10;
      LocalInnerClass01(){
       iTemp = Return_INT_FIN();
      }
      int Return_INT_FIN(){
      return INT_FIN;
      }
      
     }
    
     class LocalInnerClass02{
      // public static int i=11; ошибка не может быть не константой внутри 
     // локального вложенного класса
     }
     
     /* создаем локальные объекты  локальных классов в том же конструкторе*/
     LocalInnerClass01 localInnerClass1 = new LocalInnerClass01();
     LocalInnerClass02 localInnerClass2 = new LocalInnerClass02();
     
     
    }
     
    public static void main(String[] args) {
     OuterClass outerClass = new OuterClass();
     
     System.out.println(outerClass.iTemp ); // = 10
    //OuterClass.LocalInnerClass1 innerObject = outerClass.new LocalInnerClass1(); ошибка - это не 
   // внутренний класс, а локальный. И мы не имеем к нему доступа.
    }

    
    
}



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

Если класс определяется в теле метода, то его называют локальным внутренним классом. Пример доступа к переменным внешнего класса из локального внутреннего класса:
Читать дальше →

Внутренние и вложенные классы java. Часть 2

Время на прочтение4 мин
Количество просмотров27K
Внутренние и вложенные классы java. Часть 2

02.03.2017 — 2019 год

<<< Часть 1
Часть 3 >>>

Часть 2

Внутренние классы

Inner Classes — Внутренние классы

Внутренний класс связан с экземпляром его обрамляющего класса (из документации).

Пример внутреннего класса есть в документации.

Создадим класс:

/* Пример №7 */
 
class OuterClass {
    ...
    class InnerClass {
        ...
    }
}
 

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

Чтобы создать экземпляр внутреннего класса, нам нужно сначала создать экземпляр внешнего класса. Затем создать внутренний объект, в пределах внешнего объекта, таким образом:

 OuterClass.InnerClass innerObject = outerObject.new InnerClass(); 


Пример:


 /* Пример №8 файл Outer.java*/
package inner;

/**
 *
 * @author Ar20L80
 */
public class Outer {
    
   
    class InnerClass {
        
    }
    Outer(){}
    
    public static void main(String[] args) {
    Outer outerObject = new Outer();
    Outer.InnerClass innerObject = outerObject.new InnerClass(); // создание экземпляра 
 внутреннего класса
    }
}
 


По-другому мы можем написать так:
Читать дальше →

Внутренние и вложенные классы java. Часть 1

Уровень сложностиСредний
Время на прочтение8 мин
Количество просмотров107K

Внутренние и вложенные классы java. Часть 1


02.03.2017 — 2019 год


Часть 1. Начало



Цель статьи: Рассказать о внутренних, вложенных, локальных, анонимных классах. Показать примеры их использования. Написать и протестировать классы в коде на java. Рассказать о свойствах этих классов. Материал предназначен для лучшего понимания безымянных классов, лямбда выражений, адаптеров и многопоточности. Авторское осмысление материала, позволяет посмотреть на уже известные вещи немного иначе. Такой взгляд помогает лучшему понимаю и большей ясности, того что уже известно.


Читать дальше →

9 альтернатив плохой команде (шаблону проектирования)

Время на прочтение5 мин
Количество просмотров5.1K
image

Что это и зачем?


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

Паттерн Интерактор (Interactor, Operation)

Время на прочтение9 мин
Количество просмотров33K

Данный текст представляет собой адаптацию части руководства фрэймворка Hanami под фрэймфорк Laravel. Чем вызван интерес именно к этому материалу? В нём даётся пошаговое описание с демонстрацией таких общих для языков программирования и фрэймворков вещей как:


  • Использование паттерна "Интеракторы".
  • Демонстрация TDD\BDD.

Сразу стоит отметить, что это не только разные фрэймворки с разной идеологией (в частности, что касается ORM), но и разные языки программирования, каждый из которых имеет свою специфическую культуру и сложившиеся "bests practics" в силу исторических причин. Разные языки программирования и фрэймворки тяготеют к заимствованию друг у друга наиболее удачных решений, поэтому несмотря на различия в деталях, фундаментальные вещи не различаются, если мы конечно не берём ЯП с изначально разной парадигмой. Достаточно интересно сравнить, как одну и туже задачу решают в разных экосистемах.


Итак, исходно мы имеем фрэймворк Hanami (ruby) — достаточно новый фрэймворк, идеологически больше тяготеющий к Symfony, с ORM "на репозиториях". И целевой фрэймворк Laravel\Lumen (php) с Active Record.

Читать дальше →

JavaScript: Публичные и приватные поля классов

Время на прочтение3 мин
Количество просмотров47K

Несколько предложений расширяют существующий синтаксис классов в JavaScript новой функциональностью. Эта статья объясняет новый синтаксис публичных полей классов в V8 v7.2 и Chrome 72, а также грядущих приватных полей.


Вот пример кода, который создает экземпляр класса IncreasingCounter:


const counter = new IncreasingCounter();
counter.value;
// logs 'Getting the current value!'
// → 0
counter.increment();
counter.value;
// logs 'Getting the current value!'
// → 1

Отметим, что обращение к value выполняет некоторый код (вывод сообщения в лог) перед тем, как вернуть значение. Теперь спросите себя: как бы Вы реализовали этот класс на JavaScript?

Читать дальше →

Композиция против наследования, паттерн Команда и разработка игр в целом

Время на прочтение8 мин
Количество просмотров19K

Дисклеймер: По-моему, статья об архитектуре ПО не должна и не может быть идеальной. Любое описанное решение может покрывать необходимый одному программисту уровень недостаточно, а другому программисту — слишком усложнит архитектуру без надобности. Но она должна давать решение тем задачам, которые поставила перед собой. И этот опыт, вместе со всем остальным багажом знаний программиста, который обучается, систематизирует информацию, оттачивает новыки, и критикует сам себя и окружающих — этот опыт превращается в отличные програмные продукты. Статья будет переключаться между художественой и технической частью. Это небольшой эксперимент и я надеюсь, что он будет интересным.
— Слушай, я тут придумал отличную идею игры! — гейм-дизайнер Вася был взъерошен, а глаза — красные. Я ещё попивал кофе и холиварил на Хабре, чтобы убить время перед стенд-апом. Он выжидательно посмотрел на меня, пока я закончу писать в комментариях человеку, в чем он не прав. Вася знал, что пока справедливость не восторжествует, а правда не будет защищена — смысла продолжать со мной разговор нету. Я дописал последнее предложение и перевел на него взгляд.

— В двух словах — маги с маной могут кастовать заклинания, а воины могут сражаться в близком бою и тратить выносливость. И маги и воины могут двигаться. Да, там ещё можно будет грабить корованы, но это уже следующей версии сделаем, короче. Покажешь прототип после стенд-апа, окей?

Он убежал по своим гейм-дизайнерским делам, а я — открыл IDE.
Читать дальше →

Цена композиции в Javascript-мире

Время на прочтение7 мин
Количество просмотров15K
Мысль о том, что в разработке любой более-менее сложной бизнес-логики приоритет должен отдаваться композиции объектов, нежели наследованию популярна в среде разработчиков программных продуктов самых разных типов. На очередной волне популярности функциональной парадигмы программирования, запущенной состоявшимся успехом ReactJS, разговоры о преимуществах композиционных решений пришли и во фронтенд. В данном посте есть немного раскладки по полкам теории о композиции объектов в Javascript, конкретный пример, его разбор и ответ на вопрос сколько стоит смысловая элегантность для пользователя (спойлер: немало).

В.Кандинский - Композиция X
Василий Кандинский — «Композиция X»
Читать дальше →

Архитектурный шаблон «Итератор» («Iterator») во вселенной «Swift»

Время на прочтение5 мин
Количество просмотров9.2K
«Итератор» – один из шаблонов проектирования, которые программисты чаще всего не замечают, потому что его реализация, как правило, встроена непосредственно в стандартные средства языка программирования. Тем не менее, это тоже один из поведенческих шаблонов, описанных в книге «Банды четырех» (“Gang of Four”, “GoF”) “Шаблоны проектирования” (“Design Patterns: Elements of Reusable Object-Oriented Software”), и понимать его устройство никогда не помешает, а иногда даже может в чем-то помочь.
Читать дальше →

«Свет мой — зеркальце! — скажи, да дуал мой покажи...»: спроектируй один хороший фреймворк и получи второй в подарок

Время на прочтение3 мин
Количество просмотров1.9K
Камни древних храмов умеют разговаривать, но мало кто им внемлет. Вселенная наполнена звуками, которые мы, люди, не слышим; цветами, которые не видим: иногда дело в объективных ограничениях тела и духа, но бывают также и субъективные причины — недостаток знаний и навыков или неумение ими пользоваться в повседневной практике. Яркий пример второго в мире программирования — сигнатуры функций. Дети ОО-мира в лучшем случае мыслят интерфейсами — это близко, но «не совсем то» и чем внимательнее становишься, тем больше это превращается в «совсем не то». А сигнатуры функций тоже умеют разговаривать.
Читать дальше →

Ближайшие события

Изоморфизм спешит на помощь

Время на прочтение4 мин
Количество просмотров18K

«Изоморфизм» — одно из базовых понятий современной математики. На конкретных примерах на Haskell и C# я не только растолкую теорию для нематематиков (не используя при этом никаких непонятных математических символов и терминов), но и покажу как этим можно пользоваться в повседневной практике.

Читать дальше →

Приватные классы. Сокрытие в php

Время на прочтение3 мин
Количество просмотров8.8K

В php как и в большинстве других ООП языков существуют модификаторы видимости. Это ключевые слова public, protected и private. Но они применимы исключительно к свойствам, методам или константам. Данные модификаторы тесно связаны с возможностью инкапсуляции данных. Стоит заметить, что в таких языках как java, C#, go (https://golang.org/doc/go1.4#internalpackages), ruby (https://habr.com/post/419969/), crystal (https://crystal-lang.org/reference/syntax_and_semantics/visibility.html) есть возможность ограничивать область видимость пакетов (packages) или классов\типов. В php нет возможности ограничивать область видимости для классов — любой подключенный класс доступен из любого другого класса. Однако можно эмулировать данную возможность с применением нескольких трюков.

Читать дальше →

Новый язык программирования Mash

Время на прочтение6 мин
Количество просмотров49K
На протяжении нескольких лет я пробовал свои силы в разработке своего языка программирования. Мне хотелось создать на мой взгляд максимально простой, полнофункциональный и удобный язык.

В этой статье я хочу осветить основные этапы своей работы и для начала описать созданный концепт языка и его первую реализацию над которой сейчас работаю.
Читать дальше →

Архитектурный шаблон «Посетитель» (“Visitor”) во вселенной «iOS» и «Swift»

Время на прочтение6 мин
Количество просмотров5.8K
«Посетитель» (“Visitor”) – это один из поведенческих шаблонов, описанных в хрестоматийной книге «банды четырех» (“Gang of Four”, “GoF”) “Шаблоны проектирования” (“Design Patterns: Elements of Reusable Object-Oriented Software”).
Читать дальше →

Работа с базой данных из приложения

Время на прочтение6 мин
Количество просмотров6.9K

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


Предполагается, что читатель немного знаком с паттернами Active Record, Data Maper, Identity Map и Unit of Work.


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

Читать дальше →

Сериализация в Java. Не все так просто

Время на прочтение9 мин
Количество просмотров146K


Сериализация (Serialization) — это процесс, который переводит объект в последовательность байтов, по которой затем его можно полностью восстановить. Зачем это нужно?
Читать дальше →

Проектирование типами: Как сделать некорректные состояния невыразимыми на C#

Время на прочтение9 мин
Количество просмотров7.2K

Как правило статьи, рассказывающие о проектировании типами, содержат примеры на функциональных языках — Haskell, F# и других. Может показаться, что эта концепция неприменима к объектно-ориентированным языкам, но это не так.


В этой статье я переведу примеры из статьи Скотта Власчина Проектирование типами: Как сделать некорректные состояния невыразимыми на идиоматический C#. Также я постараюсь показать, что этот подход применим не только в качестве эксперимента, но и в рабочем коде.

Читать дальше →

Вклад авторов