Все потоки
Поиск
Написать публикацию
Обновить
5.54

ООП *

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

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

Объектно ориентированное програмирование в графических языках

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

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




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

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

«Фабричный метод» и «Абстрактная фабрика» во вселенной «Swift» и «iOS»

Время на прочтение9 мин
Количество просмотров18K
Слово «фабрика» – безусловно одно из самых часто употребляемых программистами при обсуждении своих (или чужих) программ. Но смысл в него вкладываемый бывает очень разным: это может быть и класс, порождающий объекты (полиморфно или нет); и метод, создающий экземпляры какого-либо типа (статический или нет); бывает, и даже просто любой порождающий метод (включая, конструкторы).

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

Джо Армстронг об Elixir, Erlang, ФП и ООП

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

В последние несколько дней на Хабре был опубликован ряд статей, общим лейтмотивом которых (особенно в комментариях) стало противостояние тупоконечников с остроконечниками – адепты ФП против ООП, хотя их и призывали не спорить. Иногда обсуждали Erlang, в связи с чем мне вспомнился короткий пост на тему от Джо Армстронга, одного из создателей этого языка, написанный им в конце 2018 года на форуме по Elixir в ответ на вопрос о парадигме языка. Думаю, его комментарий будет интересен.

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

Интерфейсы как абстрактные типы данных в Go

Время на прочтение7 мин
Количество просмотров12K
Не так давно коллега ретвитнул отличный пост How to Use Go Interfaces. В нем рассматриваются некоторые ошибки при использовании интерфейсов в Go, а также даются некоторые рекомендации по поводу того, как их все-таки стоит использовать.

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

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

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

Хватит спорить про функциональное программирование и ООП

Время на прочтение5 мин
Количество просмотров34K
Пост содержит некоторое количество стёба, минздрав убедительно просит неподготовленного читателя воздержаться от прочтения.

Статьи на тему «ФП лучше» или «ООП лучше» напоминают дебаты, что же лучше для обеда, вилка или ложка. Традиционно джуны начинали с ложки, но кто-то очень авторитетный однажды поведал, что ест только мясо и использует вилку, поэтому зародилась новая мода — есть вилкой. Ей едят и каши, и супы, и даже умудряются лакать смузи. Интернет завален статьями, какие мы молодцы, что научились есть смузи вилкой и преодолели все грабли. Это и смешно и грустно, с одной стороны, даёт конкурентное преимущество бывалым ребятам, которые показывают сверхрезультаты просто игнорируя этот хайп, с другой, приходится переучивать коллег и сотрудников, вычищая из их головы нанесённый ветром мусор. В этой статье я постараюсь рассказать своё видение, которое не претендует на абсолютную истину, но очень хорошо работает на практике
Читать дальше →

Наука логики в программировании

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

Georg Friedrich Wilhelm Hegel


Данная статья посвящена сравнительному анализу логических сущностей из произведения немецкого философа Георга Вильгельма Фридриха Гегеля "Науки логики" с их аналогами или их отсутствием в программировании.

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

Знакомые незнакомцы или еще раз об использовании паттернов проектирования

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

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


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

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

Эволюция программного проекта и ООП

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

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


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


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


image

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

Код живой и мёртвый. Часть третья. Код как текст

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

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


В прошлых двух статьях я показал, что тщательно выбранные слова помогают лучше понимать суть написанного, но думать только о них недостаточно, ведь всякое слово существует в двух формах: как само по себе и как часть предложения. Повтор CurrentThread ещё не повтор, пока мы не читаем его в контексте Thread.CurrentThread.


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

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

Код живой и мёртвый. Часть вторая. Действия и свойства

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

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


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


Об этом — в статье.

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

Код живой и мёртвый. Часть первая. Объекты

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

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


И вместе с этим мы видим повсеместную эпидемию менеджеров, хелперов, сервисов, контроллеров, селекторов, адаптеров, геттеров, сеттеров и другой нечисти: всё это мёртвый код. Он сковывает и загромождает.


Бороться предлагаю вот как: нужно представлять программы как текст на естественном языке и оценивать их соответственно. Как это и что получается — в статье.

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

Язык программирования, помещающийся на почтовой открытке

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

image
Источник


Ральф Джонсон, один из членов "Банды четырёх", однажды показал, как синтаксис языка Smalltalk-80 можно уместить на почтовой открытке. Сейчас, спустя почти 30 лет после появления первой версии Smalltalk, самым быстроразвивающимся диалектом Smalltalk является Pharo, почтовую открытку которого далее и разберём.

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

Наследование в C++: beginner, intermediate, advanced

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

В этой статье наследование описано на трех уровнях: beginner, intermediate и advanced. Expert нет. И ни слова про SOLID. Честно.


Beginner


Что такое наследование?


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


Класс, который наследует данные, называется подклассом (subclass), производным классом (derived class) или дочерним классом (child). Класс, от которого наследуются данные или методы, называется суперклассом (super class), базовым классом (base class) или родительским классом (parent). Термины “родительский” и “дочерний” чрезвычайно полезны для понимания наследования. Как ребенок получает характеристики своих родителей, производный класс получает методы и переменные базового класса.


Наследование полезно, поскольку оно позволяет структурировать и повторно использовать код, что, в свою очередь,

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

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

Инкапсуляция для настоящих самураев, или нюансы, связанные с ключевым словом internal в C#

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

Пролог: internal is new public


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


image

Случился такой проект и в моей жизни. Очередной. Причём делаю я его под добровольным надзором, где за каждой моей строчкой следят. Соответственно, уже не только хотелось, но и надо было делать всё правильно. Одним из «правильно» было «чти инкапсуляцию и закрывайся по максимуму, потому что открыться всегда успеешь, а закрыться обратно потом будет поздно». И поэтому я везде, где только мог, стал использовать для классов модификатор доступа internal вместо public. И, естественно, когда ты начинаешь активно использовать новую для тебя фичу языка, возникают некоторые нюансы. О них по порядку и хочу рассказать.

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

Три дзена reactive extensions

Время на прочтение2 мин
Количество просмотров2.5K
"Reactive Extensions" — это больше, чем фреймворк. Хотя бы потому, что существует практически идентичная реализация (с поправкой на особенности конкретного языка и соответствующих практик оптимизации) под каждый популярный ЯП. Есенин утверждает, что «большое видится на расстояньи». В этой записке я буду отходить на разные «расстоянья» и описывать то, что видится мне.
Читать дальше →

Как устроен фреймворк 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 мин
Количество просмотров60K
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(); // создание экземпляра 
 внутреннего класса
    }
}
 


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

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