Рабство программиста

11.03.11

Разработка - Математика и алгоритмы

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

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

Что такое ООП?

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

 

Базовые понятия ООП

Их все знают, это:

  • инкапсуляция
  • наследование
  • полиморфизм

Сейчас также добавляют еще понятие абстракции данных. Рассмотрим их всех по порядку…

Инкапсуляция – это принцип, согласно которому любой класс должен рассматриваться как чёрный ящик — пользователь класса должен видеть и использовать только интерфейсную часть класса (т. е. список декларируемых свойств и методов класса) и не вникать в его внутреннюю реализацию. Поэтому данные принято инкапсулировать в классе таким образом, чтобы доступ к ним по чтению или записи осуществлялся не напрямую, а с помощью методов. Принцип инкапсуляции (теоретически) позволяет минимизировать число связей между классами и, соответственно, упростить независимую реализацию и модификацию классов (определение взято из Википедии «Объектно-ориентированное_программирование»). Но, инкапсуляция не ноу-хау ООП, она существовала и ранее – это обычное описание функций и процедур. Пример на Паскале:

	Function Sum (a, b: Integer): Integer;
	Begin
	Result := a+b
	End;

Чтобы использовать функцию мне не обязательно знать, как она устроена (и в ряде случаев такое знание даже противопоказано), достаточно лишь описание интерфейса Function Sum (a, b: Integer): Integer; Я должен знать, что имя функции Sum, она принимает два параметра типа Integer (важен также порядок их следования), возвращает также Integer, а вот каким образом проводится сложение это уже совершенно безразлично. Еще пример:

	Type
	TMas = record
	Data: Array of Integer;
	Count: Integer;
	End;
	Procedure Sort (var Mas: TMas);

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

Однако на этом инкапсуляция не заканчивается: cокрытие данных (взят из книги Тимоти Бадд «ООП в действии») — неотделимая часть ООП, управляющая областями видимости. Является логическим продолжением инкапсуляции. Целью сокрытия является невозможность для пользователя узнать или испортить внутреннее состояние объекта. Но это тоже существует в структурном программировании:

	Function fact(x: integer): integer;
	var
	i, n: Integer;
	begin
	n:=1;
	for i:=1 to x do
	begin
	n:=n*i;
	end;
	fact:=n;
	end;

Разве я могу получить доступ к i и n не в рамках данной функции? Также стоит еще раз внимательно почитать определение – невозможность для пользователя. Если речь идет о программисте, то он испортить может все и вся и никакое сокрытие данных Вам не поможет, по одной простой причине – раз имеются данные, то также и имеются некоторые механизмы для их использования. Поэтому область видимости не защищает данные от ошибок в методах данного класса. Пример на Дельфи:

	Type
	MyClass = class (TObject)
	Protected
	MyData: TStringList;
	Private
	Public
	Constructor Create;
	Destructor Destroy;
	End;
	Constructor MyClass.Create;
	Begin
	Inherited Create
	End;
	Destructor MyClass.Destroy;
	Begin
	Inherited Destroy
	End;

Опытный программист уже догадался, о чем идет речь – любое обращение к MyData вызовет ошибку, поскольку перед использованием такие объекты нуждаются в инициализации (между прочим одна из распространенных ошибок начинающих программистов). Так что же дают игры с областями видимости? Если же говорить о методах других объектов, то доступа к MyData они не получат, но согласно принципам ООП они и не должны его получать. Иными словами MyData никогда не должен находиться в секции Public (кстати, Дельфи это позволяет). Доступ к полям класса всегда должен осуществляться через методы либо свойства. То есть здесь должна быть аналогия с функциями и процедурами структурного программирования – объявление структур данных должно осуществляться аналогично секции var. Это очень важный момент – сокрытие данных в рамках ООП предназначено для программирования программиста, а не реализации алгоритма. Я говорю о сокрытии данных, потому что я боюсь допустить ошибку, которая в рамках структурного программирования не может возникнуть в принципе. Компилятору безразлично, в какой секции находится поле, он выдаст код в любом случае (речь идет о Дельфи версии 7), все ограничения видимости введены для программиста. Если Вы думаете, что в С++ это невозможно, то сильно ошибаетесь и виной тому указатели (а в С++ указатели не менее важный механизм, нежели механизмы ООП). Имея указатель на класс, можно не только прочесть его приватные поля, но и модифицировать их.

	Class Sneaky
	{
	private:
	int safe;
	public:
	// инициализировать поле safe значением 10
	Sneaky () { safe = 10; }
	Int &sorry() { return safe; }
	}
	И далее:
	Sneaky x;
	x.sorry () = 17;

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

	unit Unit1;
	interface
	uses
	Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
	Dialogs, Unit2, StdCtrls;
	type
	TForm1 = class(TForm)
	Button1: TButton;
	procedure Button1Click(Sender: TObject);
	procedure FormCreate(Sender: TObject);
	private
	{ Private declarations }
	public
	{ Public declarations }
	end;
	var
	Form1: TForm1;
	implementation
	{$R *.dfm}
	procedure TForm1.Button1Click(Sender: TObject);
	begin
	AddX();
	Button1.Caption:=IntToStr(GetX());
	end;
	////////////////////////////////////////////////////////////////////////////////
	procedure TForm1.FormCreate(Sender: TObject);
	begin
	Init();
	end;
	////////////////////////////////////////////////////////////////////////////////
	end.

И подключите второй модуль:

	unit Unit2;
	interface
	procedure Init();
	procedure AddX();
	function GetX(): Integer;
	implementation
	var
	x: Integer;
	procedure Init();
	begin
	x:=0;
	end;
	////////////////////////////////////////////////////////////////////////////////
	procedure AddX();
	begin
	x:=x+1;
	end;
	////////////////////////////////////////////////////////////////////////////////
	function GetX(): Integer;
	begin
	result:=x;
	end;
	////////////////////////////////////////////////////////////////////////////////
	end.

Выполните программу, понажимайте на кнопку. Теперь попробуйте получить доступ к Х без использования функций и процедур из Unit2. Модуль хранит в себе данные, скрывает их представление и ограничивает к ним доступ. При этом в Unit2 нет и намека на класс (и не думайте, что Вы сможете прочесть или изменить Х обычными процедурами и функциями Unit1 (не из формы)). Наследование один из четырёх важнейших механизмов объектно-ориентированного программирования, позволяющий описать новый класс на основе уже существующего (родительского), при этом свойства и функциональность родительского класса заимствуются новым классом. Не то чтобы я не согласен с таким определением, но давайте посмотрим очередной пример:

	Type
	TMas = record
	Data: Array of Integer;
	Count: Integer;
	End;
	Type
	TGroupMas = record
	Data: Array of TMas;
	Count: Integer;
	End;
	Procedure Sort (var Mas: TMas);

Разве для построения TGroupMas я не опираюсь на TMas? Я ведь мог написать определение TGroupMas с нуля, но в моем случае каждый элемент массива Data структуры TGroupMas является ни кем иным как TMas. Более того, мне ничего не стоит написать процедуру сортировки указанного элемента TGroupMas. Все что требуется это лишь правильно передать параметры процедуре Sort. Таким образом, я описываю новую структуру TGroupMas данных на основании существующей TMas и я мог создать процедуру сортировки элемента массива на основании Sort:

	Procedure SortItem (var GropuMas: TGroupMas; Index: Integer);
	Begin
	Sort (GroupMas.Data[Index]);
	End;

При этом согласно определению наследования, я заимствую все свойства TMas и функциональность Sort; и все это в рамках структурного программирования, никакого ООП для этого не требуется. Вот пример, который часто любят давать в учебниках ООП (язык программирования Дельфи):

	Type
	TMaterial = record
	Massa: Integer;
	End;
	Type
	TAnimal = record
	Material: TMaterial;
	Sort: String;
	End;
	Type
	TMamal = record
	Animal: TAnimal;
	Family: String;
	End;
	Type
	THuman = record
	Mamal: TMamal;
	Race: String;
	Floor: String;
	Name: String;
	Family: String;
	End;
	Type
	TProgrammer = record
	Human: THuman;
	Sertificate: String;
	End;
	Type
	TProgrammer_of_Pascal = record
	Programmer: TProgrammer;
	IDE: String;
	End;

И пусть в меня «кинут камнем», если программист в данной иерархии не является млекопитающим и не обладает его свойствами (имеет массу, принадлежит к определенному виду).

TMaterial
|
TAnimal
|
TMamal
|
THuman
|
TProgrammer
|
TProgrammer_of_Pascal
Для использования механизма наследования не требуется использование объектно-ориентированного программирования. Достаточно, чтобы язык имел возможность организации структур данных определяемых программистом. Множественное наследование полностью аналогично – я могу определить новую структуру – цвет глаз и включить ее в TMamal и тогда программист обретет новые свойства. Кстати, множественное наследование одна из самых известных мозолей ООП, но именно поэтому о ней мы больше упоминать не будем. Цель данной статьи как раз показать те, моменты, о которых говорить не любят. Полиморфизм взаимозаменяемость объектов с одинаковым интерфейсом. Язык программирования поддерживает полиморфизм, если классы с одинаковой спецификацией могут иметь различную реализацию — например, реализация класса может быть изменена в процессе наследования. Кратко смысл полиморфизма можно выразить фразой: «Один интерфейс, множество реализаций». Можно сказать, что полиморфизм одна из самых загадочных концепций ООП. Итак, в некотором роде полиморфизм тесно связан с наследованием. Вы получаете некоторые методы от родительского класса и можете переопределить их функциональность. Адекватного механизма в структурном программировании не существует, но какие собственно выгоды дает полиморфизм? Итак, это выглядит следующим образом – некий класс (допустим программист) имеет в своем составе метод (допустим, пить чай). Программист на Яве переопределяет метод и пьет чай марки Ява под именем метода пить чай. То есть мы подразумеваем, что когда программист на Ява пьют чай, то он пьет чай марки Ява. Стандартно, формально, но теперь вопрос, какие в этом плюсы?

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

Не густо, ну что, рассмотрим каждый пункт:

  1. честно говоря, так и не увидел, в чем это выражается (хотя упоминается об этом практически везде), концепция структур и модулей достаточна для решения всех задач, которые могут быть решены полиморфизмом. С другой стороны, многочисленные одноименные методы усложняют программу. Результатом полиморфизма являются объекты, которые имеют и одноименные методы и могут работать с разными типами данных. Использование одноименных методов в таком случае не так тривиально, как хотелось бы. Пришлось срочно создавать новую концепцию (вернее сказать, воровать концепцию, поскольку ООП суть ряда заимствований от других парадигм) – RTTI. Проще всего ее можно представить как информацию о типе объекта во время выполнения программы. То есть перед запуском нужного метода используется явное определение того типа данных, с которым предстоит работать. Обычно такая ситуация возникает только в сложных программных объектах, но и полиморфизм в объектах с несложным поведением не имеет смысла и может быть заменен даже обычными операторами селекторами (например case в Дельфи) и введением дополнительных переменных. Более того, RTTI перечеркивает абстрагирование – для решения задачи динамически знать тип данных противопоказано, это увеличивает сцепляемость объектов – их сложней заменять, переносить, модернизировать. RTTI также уменьшает такую возможность полиморфизма, как использование обобщенных алгоритмов (о параметризации речь ниже).
  2. об этом уже упоминалось:

 

Procedure SortItem (var GropuMas: TGroupMas; Index: Integer);
			Begin
			Sort (GroupMas.Data[Index]);
			End;

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

  • Я тоже могу написать кучу модулей для решения каждой задачи (все равно в классах каждое решение надо описывать явно) и вызывать их одноименные функции также через точечный синтаксис (в Дельфи), только в обратном порядке – имя_функции.имя_модуля. И я бы не сказал, что сильно путаюсь в программе, если однотипные действия названы по-разному (причем без разницы два у меня метода или десяток). Если имеется достаточно полное описание методов (те самые интерфейсы, которые ООП также считает своим достижением), и они имеют осмысленные имена, то никаких проблем между вызовом метода ProgrammTea и ProgrammJavaTea не возникает. ООП полностью игнорирует такие подходы как правильное оформление кода и правила именования объектов (хотя в нем же использование одноименных методов считается плюсом).

 

 

Организация тысячи то же что и организация одного. Это вопрос организации (Конфуций).

Кроме того, я не считаю, что выбор нужного метода осуществляется компилятором – все действия жестко прописаны в каждом классе, а поскольку любой класс является еще и типом, то он ничего не выбирает, выбирает программист в каком классе, какой чай должен пить объект-программист на этапе переопределения родительского метода. Вот я бы задал список методов вообще без привязки к конкретному классу, просто как набор функций и процедур в отдельном модуле, а уж компилятор сам вызывал бы соответствующий метод, тогда я бы согласился с этим утверждением на все 100. Далее в современные библиотеки классов, обычно содержат более 100 классов, которые могут содержать десятки методов, и все их держать в голове никакой полиморфизм еще никогда не помогал… Без разницы сколько мне надо знать 1000 методов или 10 000, все равно их все помнить в любой момент времени нет необходимости. Что касается параметризации это действительно мощный механизм, но с теми же симптомами – это не универсальный рецепт, то есть имеет смысл его применять только в ряде случаев (часть из которых может быть решена комбинаторными алгоритмами) и преимущественно к простым типам. Вот пример алгоритма (С++):

 

	// Описание шаблонной функции
	template <typename T> T max(T x, T y)
	{
	if (x < y)
	return y;
	else
	return x;
	}

Не трудно догадаться, что она возвращает максимальный элемент из двух указанных, но только в том случае, если программист сможет описать строгое и однозначное сравнение объектов, то есть удобно для типов, которые по умолчанию поддерживаются транслятором. Для сложных типов, определяемых программистом параметризация не дает никаких преимуществ в сравнении с традиционными подходами. Весьма проблематична параметризация, когда в качестве типа выступают объекты классов, хотя, казалось бы, их строгая иерархия, наследование полей и полиморфизм должны как раз способствовать написанию обобщенных алгоритмов для работы с такими типами. Да это возможно, но требует тщательного продумывания иерархии и написание индивидуальных методов для каждого класса может оказаться предпочтительней.… Здесь решение аналогично RTTI, но проблема не в ООП, это попытка перешагнуть через строгое ограничение типов (наряду с типом Variant в Дельфи). Можно провести следующую аналогию – сначала перед бегуном понаставили барьеров и сказали, что теперь он будет учувствовать в беге с препятствиями, а потом пытаются научить его прыгать, выдают ему специальные кроссовки, рекомендуют методики тренировки…

Также не все гладко с перегрузкой операторов – трансляторы языков программирования часто не могут предоставить нужные средства идентификации перегруженных операторов (а те, что могут, сложны и не так эффективны, порождают большой и медлительный код), что вызывает двусмысленность в толковании всего выражения. Самый простой пример операция – (вычитание), дело в том, что она существует как минимум в двух видах это унарная операция и бинарная - -х и х-y (а в некоторых языках есть еще ее различные формы – инфиксная, постфиксная и т.д.). Далее, необходимо определить приоритет операции, скажем, для строк определение подобных операций может быть не так очевидно, как для чисел. Не думайте что сложение в этом случае лучше. Например, сложение строк x + y не эквивалентно y + x.

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

Что еще, не так как надо

ООП «вещь в себе», и оно не вписывается в ряд задач – например механизм подключения DLL. Да, функция или процедура возвращает значение, но какого типа? Это отследить невозможно (и RTTI Вам не помощник). ООП очень плохо подходит для парсинга структурированных текстов (например, программ) в сравнении с функциональным программированием. ООП не дружит с рекурсией (не то чтобы она там не возможна, просто не эффективна в сравнении с тем же функциональным программированием), которая позволяет упростить представление многих задач. Также нужно учитывать, что программа, составленная без ООП, как правило, быстрей, чем с ним. ООП официально не поддерживает концепцию ленивых вычислений (вообще это черта языков функционального программирования) – потенциальное увеличение производительности, упрощение решения ряда задач.

Итоги

Данная статья вовсе не призывает отказываться от принципов ООП, задача дать более полное представление об некоторых аспектах ООП. Без понимания этих моментов программисты уверены, что ООП существенный шаг вперед (на самом деле существенный шаг вперед — обширные библиотеки, которые в свете новых веяний написаны в стиле ООП), хотя возможно, всего лишь шаг в сторону… Возьмите параметризацию – не стоит возлагать на нее большие надежды, она существует уже давно в том или ином виде в функциональном программировании (как и весь полиморфизм во всех его проявлениях) и пока не принесла кардинальных изменений в деле создания программ.

См. также

Метод Дугласа-Пойкера для эффективного хранения метрик

Математика и алгоритмы Платформа 1C v8.2 Конфигурации 1cv8 Россия Абонемент ($m)

На написание данной работы меня вдохновила работа @glassman «Переход на ClickHouse для анализа метрик». Автор анализирует большой объем данных, много миллионов строк, и убедительно доказывает, что ClickHouse справляется лучше PostgreSQL. Я же покажу как можно сократить объем данных в 49.9 раз при этом: 1. Сохранить значения локальных экстремумов 2. Отклонения от реальных значений имеют наперед заданную допустимую погрешность.

1 стартмани

30.01.2024    1754    stopa85    12    

33

Алгоритм симплекс-метода для решения задачи раскроя

Математика и алгоритмы Бесплатно (free)

Разработка алгоритма, построенного на модели симплекс-метода, для нахождения оптимального раскроя.

19.10.2023    4421    user1959478    50    

34

Регулярные выражения на 1С

Математика и алгоритмы Инструментарий разработчика Платформа 1С v8.3 Мобильная платформа Россия Абонемент ($m)

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

1 стартмани

09.06.2023    7464    4    SpaceOfMyHead    17    

56

Модель распределения суммы по базе

Математика и алгоритмы Платформа 1С v8.3 Россия Абонемент ($m)

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

1 стартмани

21.03.2022    7855    7    kalyaka    11    

44

Изменения формата файлов конфигурации (CF) в 8.3.16

Математика и алгоритмы Платформа 1С v8.3 Бесплатно (free)

Дополнение по формату файлов конфигурации (*.cf) в версии 8.3.16.

16.12.2021    4446    fishca    13    

36

Интересная задача на Yandex cup 2021

Математика и алгоритмы Бесплатно (free)

Мое решение задачи на Yandex cup 2021 (frontend). Лабиринт. JavaScript.

12.10.2021    8840    John_d    73    

46

Механизм анализа данных. Кластеризация.

Математика и алгоритмы Анализ учета Платформа 1С v8.3 Анализ и прогнозирование Бесплатно (free)

Подробный разбор, с примером использования, встроенного механизма кластеризации 1С.

31.08.2021    7806    dusha0020    8    

70
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. orefkov 1152 12.03.11 00:17 Сейчас в теме
В основном в статье понаписан бред, человеком, мало понимающем, о чем он пишет.
kuzyara; inkko; OVG78; wolfsoft; artbear; +5 Ответить
2. hogik 443 12.03.11 00:49 Сейчас в теме
(1)
Часто путают два понятия "НЕпонимание" и "НЕсогласие". Считается, что если человек понял, то и согласился. Думаю, автор статьи понимает предмет, но не соглашается. Так тоже бывает... ;-)
davay2000; +1 Ответить
3. orefkov 1152 12.03.11 01:18 Сейчас в теме
(2)
Ну, если человек в первых же абзацах начинает сравнивать инкапсуляцию в ООП с недоступностью извне локальных переменных в функции - трудно подумать, что он понимает.
4. hogik 443 12.03.11 01:29 Сейчас в теме
(3)
Александр.
Я не буду спорить.
Но, автор утверждает, что "Никаких преимуществ, в сравнении с теми же структурным или функциональным программированиями, инкапсуляция в ООП не несет."(с)
Это, думаю, не сравнение. Это "разбор" преимуществ. ;-)
18. orefkov 1152 14.03.11 09:30 Сейчас в теме
(4)
Тоже не буду спорить, но автор, сравнивая сыр с пятницей, пытается доказать, что топор не имеет преимуществ перед астрономией.
Арчибальд; +1 Ответить
6. artbear 1448 12.03.11 10:09 Сейчас в теме
(1) Прав.
Автор путает элементарные понятия.
19. Арчибальд 2706 14.03.11 09:36 Сейчас в теме
(1) (2)
Состав статьи:
1) Тезис о том, что определения ООП нет - не устоялось.
2) Авторское определение ООП. Должно было быть, но автором пропущено.
3) Сравнение концепций ООП и каких-нибудь других. Либо критика ООП.

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

А автору публикации - плюс за демонстрацию "лика врага".
5. DrAku1a 1679 12.03.11 04:53 Сейчас в теме
Фигня. В современном учебнике информатики дается представление и об объектах и о классах, не привязанное к языку программирования.
Лично я всегда проводил аналогию между классом и объектом, как между указательным типом данных и конкретным указателам.
Есть конечно и отличия:
  • описание класса, включая процедуры, хранится в программе, описание структуры указательного типа - это информация для компилятора и отладчика
  • классы, в отличие от указателей могут наследоваться - тогда нужно описывать только отличия поведения потомка от родителя
  • процедуры выделения памяти под объект - экземпляр класса являются частью этого класса, также существуют процедуры класса (class procedure TMyClass.Calculate), которые можно вызывать, обращаясь к классу как к объекту (все переменные класса в такой процедуре недоступны).

Только вот... а зачем все это программисту 1С-нику? В 1С, что в 7.7, что в 8.x все классы определены системой, мы только работаем с объектами того или иного класса. Своих классов не определить. Да и зачем? Наследование классов отсутствует, ввиду ненужности.
Лично мое ИМХО - все правильно. Без классов все-же код более читабелен.

Кстати, пример наследования: посмотрите в УТ - УниверсальныйОтчет и производные от него отчеты ВзаиморасчетыСКонтрагентами, Продажи, (которые представляют свой интерфейс, но по-сути являются частными случаями этого Универсального отчета, и вызывают его механизмы).
8. artbear 1448 12.03.11 10:27 Сейчас в теме
(5) ты сам себе противоречишь :( уж определись, есть наследование в 8-ке или нет?
Экспортные методы в любом модуле прикладного объекты - это уже определение/описание соответствующего класса.
Общие неглобальные модули - это фактически те же классы, только сильно урезанные.
В 8-ке ООП не полностью сделан - инкапсуляция есть/возможна, наследования в чистом виде нет, полиморфизм возможно организовать.
14. DrAku1a 1679 12.03.11 18:05 Сейчас в теме
(8) Есть попытка реализации "наследования" на языке самой 1С (тот же Универсальный отчет). Можно еще счтать например "Справочник.Номенклатура" потомком общего объекта "Справочник", получающего от предка поля "Код" и "Наименование", механизм автоматического отображения форм (который может быть изменён). Вот, вроде и все, что есть.
Но создать справочник "Номенклатура2", который был бы потомком справочника "Номенклатура", но содержал еще несколько дополнительных полей и была бы другая форма элемента нельзя. Можно только копированием. Но копия - это не потомок. Изменения в первом справочнике надо дублировать во втором вручную, в то время, как при наследовании любые изменения родителя автоматически влияют на всех потомков. Не говоря уже, что справочники содержат две копии одного и того же кода.

Кстати, вот интересно - как именно возможно организовать полиморфизм? Вот тот же справочник "Номенклатура" к примеру?

Что касается читабельности 7-ки, то тут мне намного удобнее - например в отчете вся реализация собрана в процедуре "Сформировать", а не раскидана по модулю программы в десяток процедур, вызывающих еще с десяток процедур из общих модулей, откуда ваызываются другие процедуры Общих модулей, и глобального модуля, откуда... и так далее... В общем, без отладчика концов не сыщешь... И это только разбиение кода на процедуры и модули. Если бы было введено "наследование" (именно в коде) - бардак был бы вообще неразберимый.
7. artbear 1448 12.03.11 10:24 Сейчас в теме
Ну-ну "Без классов все-же код более читабелен."
Попробуй в 8-ке все закинуть в общий глобальный модуль, ничего не добавляя ни в один модуль объектов (спр, доки, отчеты, обработки). Вот это и будет без классов.
посмотрим, насколько твой код будет читабельнее :)
9. Поручик 4670 12.03.11 14:14 Сейчас в теме
(7) Открыть глобальный модуль в типовой конфе 7.7. после многочисленных доработок и бахтёрт пример читабельности обеспечен.
11. artbear 1448 12.03.11 14:36 Сейчас в теме
(9) Ну да, забыл добавить, что получаем очень читабельную 7-ку :)
10. Поручик 4670 12.03.11 14:16 Сейчас в теме
В основном верно, не стоит тратить время на данное чтиво.
12. cool.vlad4 2 12.03.11 15:00 Сейчас в теме
:D Ну, что вы все прям всерьез...надо было ссылку на молодой ресурс скинуть, вот и (0)...а так треп да и только...
13. MaxDavid 127 12.03.11 17:45 Сейчас в теме
(12) К ресурсу не имею никакого отношения, честно. Просто тема статьи показалась небезынтересной.
15. Поручик 4670 12.03.11 18:11 Сейчас в теме
(13) Эти споры тупо/остроконечников длятся ровно столько, сколько существует активное использование ООП. Руководствоваться надо простым принципом: всё хорошо в меру. Так и с ООП, которое имеет своё предназначение и область применения.

зы Но в статье феерический бред, честно. Долго пытался понять, есть ли между её словами какая-либо лексико-семантическая связь или это рандомизированный поток сознания, порождённый употреблением веществ, изготовленных с отклонениями от НТД.
16. cool.vlad4 2 12.03.11 19:14 Сейчас в теме
(15) быть может шизофазия?
17. DrAku1a 1679 14.03.11 02:55 Сейчас в теме
(15) Согласен. Добавлю лишь, что разработчики платформы 1С эту меру соблюдали лучше всего.
20. Flashback1979SE 14.03.11 09:50 Сейчас в теме
Минус блин.
PS: Время зря потратил, итить. Как-будто здесь народ не знает когда ООП юзать, а когда процедурное программирование.
PS2: Название статьи - .... "Осталось узнать только какую вы там траву курите." (С) AVATAR, Selfridge
PS3: А можно узнать, какая цель преследовалась выкладыванием этой статьи?
21. artbear 1448 14.03.11 14:02 Сейчас в теме
Да, за название нужно ставить отдельный минус.
22. wolfsoft 2421 16.03.11 13:56 Сейчас в теме
Н-да... минус ставить не буду - не люблю... Лучше orefkov-у плюсану... в знак протеста :D
23. d0dger 82 16.03.11 20:47 Сейчас в теме
Кто-то объяснит причем тут рабство?
24. RustIG 1351 17.03.11 13:17 Сейчас в теме
(0) ставлю минус за то,
- что не разместили статью на ИС, а предоставили ссылку на нее
- название статьи неадекватно содержанию
- не согласен с автором
25. DrAgrO 18.03.11 16:30 Сейчас в теме
12 лет говнокодю ... ЕНТО БРЕДЪ!!!
26. kurator1C 24.03.11 15:01 Сейчас в теме
Статья, имхо, не дает ни какой полезной инфы и тупо убивает время читающих.
Оставьте свое сообщение