Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
Перечень схожих черт Аристотель назвал типом. А объект, обладающий этими чертами, — экземпляром данного типа.
Поэтому в ООП нет даже простейших операций над классами (сложение и вычитание множеств)Эту задачу в терминах ООП можно решить при помощи костылей, но если хочется красивого решения, то почитайте про ADT. Они позволяют то, что вы хотите: создавать типы из других типов используя операции логического сложения и произведения. О том как это реазиловать в ООП можно почитать тут
Кроме того, в бизнес-анализе сейчас распространены другие некорректные пары терминов: событие и экземпляр этого события, процесс и экземпляр этого процесса, договор и экземпляр этого договора. В русском языке нет такого понятия как объект и экземпляр этого объекта. Есть термины тип объекта и экземпляр этого типа объекта.
Возможно, ошибочное употребление терминов возникло из-за неверного перевода термина instance с английского языка. Instance переводится как пример, или как случай, но он не переводится как экземпляр.
Деление на классы и объекты классов позволяет мне рассматривать любые объекты исследуемого класса, например, класса слонов (изучать продолжительность жизни любого из слонов, длину его бивней на различных этапах его жизни), а также — класс слонов (изучать среднюю длительность жизни слонов, средний рост и средний вес). Понятно, что любой слон класса не может «знать» информацию о средней длительности жизни всех слонов. Эту информацию «знает» только класс слонов. Попробуйте в парадигме Аристотеля придумать тот объект, который «знает» о среднем количестве событий в год, не используя при этом термин множество! Навряд ли у вас это получится.
Простите, но кому и зачем нужно использовать в программировании термины на русском языке
Возможно вы удивитесь, но это называется статические поля и методы класса
Я не говорил про программирование. Я говорил про моделирование предметной области.
Мне, как программисту, было бы проще работать, если бы концепции программирования были возможно ближе к концепциям описания модели.
Дело не в русском языке.
Вы правы, проблема не новая, но есть общеупотребительные термины, собственно, — это даже не термины, а какие-то глубоко устоявшиеся понятия.
Я не зря привел как пример именно «метод», так как это что-то более широкое в восприятии любого человека независимо от специальности.
Мы часто, когда говорим об ООП, употребляем слово «модель»
Т.е. в общем и целом мы в праве говорить и говорим, что ООП — это метод программирования.
И теперь конкретный пример: человек открывает учебник по ООП и видит функцию обёрнутую в класс, а ему говорят, что это метод. А почему метод?
Почему не функция класса?
А во-вторых, потому что придут математики и тоже скажут «какая же это функция?» — и чем их мнение отличается от вашего?
Так что вопрос о терминологии для нас уже пройден и закрыт.
Да, терминология ООП вредна, она вводит в заблуждение.
И в конце концов она вредна для самих программистов, потому что через некоторое время у них возникает деформация, в которой они начинают в реальном мире видеть «инстансы» вместо объектов.

Я говорил про ту машину, что стоит у меня под окнами. У нее есть колеса, у нее есть класс колес,
мы классифицируем, то есть относим к классу колес.
При создании класса слонов сохраняем кол-во всех слонов, сумму длительности жизни, роста, веса всех слонов в статические поля и после получаем все средние величины.
В случае, если мы заводим в одном типе данных «Слон» статические поля «общее кол-во», какие-то средние величины, то даже говорить не хочется что будет с вашими этими полями при работе с многопотоком, с сопровождением кода двумя-тремя и более «поколениями» программистов, и т.д.
private static AtomicInteger sumWidth = new AtomicInteger();
private static AtomicInteger countWidth = new AtomicInteger();
private Integer width;
public setWidth(int width) {
this.width = width;
sumWidth.addAndGet(width);
countWidth.incrementAndGet();
}
public double static synchronized getAverageWidth(){
double sumWidth = this.sumWidth.get();
double countWidth = this.countWidth.get();
return sumWidth / countWidth;
}
Ничего не будет, если поля потокобезопасные и приватные.
Объясните зачем тогда вообще нужны статические поля, если не для хранение общих для всех классов данных?
Это, очевидно, неправильно.
Я занимаюсь построением моделей.
Как решаются задачи построения промышленных моделей, надо спросить у Агроскина. Он знает, потому что работает именно над этим.
Я же не строю эти модели, потому что в той области, в которой я работаю, ИСО не дает мне нужных классов сущностей. Их приходится думать самому. Вот о процессе выделения в сущем таких классов я и веду речь на хабре.
У Вас очень ограниченное представление о целях этого процесса. Мы можем обмениваться моделями с разными, совершенно неожиданными целями. Я даже боюсь взяться классифицировать эти цели.
Я не ставлю задачу решать конкретные примеры. Я ставлю задачу объяснить конкретный тип мышления, который позволит строить конкретные модели. А те, кто объясняют, как стоить конкретные модели, — я указал на них.
Я не могу построить модель примитивного процесса, потому что, чтобы объяснить Вам что я построил, понадобится еще 10 статей на хабре.
Если МОЖЕТ, то ООП нарушает логику.
// Класс "Слон"
class Elephant
{
// Имя слона - характеристика экземпляра
private string name;
// Конструктор экземпляра
public Elephant(
string name // имя слона - входной параметр
)
{
this.name = name;
}
// Имя слона - открытое экземплярное свойство только для чтения
public string Name
{
get { return this.name; }
}
// Экземплярный метод "Бежать" - заставляет слона бежать
public void Run(
int speed // скорость
)
{
// Здесь пишем код, который как-то обозначает, что слон бежит
}
}
// Класс "Слоны" (фабрика слонов)
class Elephants
{
// "Список слонов" - для упрощения его реализации используем готовый класс List<T>:
private System.Collections.Generic.List<Elephant> elephantList;
// Конструктор класса
public Elephants()
{
this.elephantList = new List<Elephant>();
}
// Добавить нового слона в множество слонов
public void AddNewElephant(
string name // Имя слона
)
{
this.elephantList.Add(new Elephant(name));
}
// Общее число слонов
public int TotalElephantCount
{
get { return this.elephantList.Count; }
}
// Метод Run - завставляет бежать слона с индексом "elephantIndex" со скоростью "speed"
public void Run(int elephantIndex, int speed)
{
this.elephantList[elephantIndex].Run(speed);
}
}Т.е., в идеальной парадигме/платформе разработке первый пример не должен компилироваться
И еще второй пример должен реализоваться проще, короче, «нативнее», чтобы не пришлось каждый раз плодить такой паттерн.
Аргументы? Должно быть запрещено любое обращение к статикам?
Какой именно?
(ну а вообще, второй пример в .net нативно реализуется через Set. Причем с семантикой множества.)
Про аргументы я уже не раз писал,
а вот насчет статиков, на мой взгляд, статик-поля должны быть разрешены только в таком качестве: readonly & immmutable.
О котором не раз писал, и который сейчас привел — назовем его Метасущность (Объект — Список Объектов — Объекты).
Вы про HashSet(T)?
Поэтому хотелось бы решения проблемы можно и должно, и реализации парадигмы множества не через класс HashSet (пусть и стандартный), а через синтаксис языка.
Во-первых, вы только что запретили стандартную реализацию синглтона
А вот неправда, у вас сейчас есть только объект и список объектов, причем для второй части паттерн встроен в любую разумную библиотеку — следовательно, поддержка уже есть.
Именно поэтому когда вы хотите новую парадигму, не надо обрезать существующий язык, надо брать новый, и строить его с нуля. При этом у вас получится именно то, что нужно в вашей парадигме
О синглтоне я думал, но ведь вокруг него всегда столько споров, про него говорят даже «антипаттерн».
И вы получите класс, вполне подпадающей под определение «Слоны» («Стадо слонов»).
А в качестве «списка» (или «множества»?), кстати, действительно можно использовать не только List(T), но и тот же HashSet(T).
Изначально речь шла о недостатках моделирования предметной области с помощью ООП.
Считаю, что недостатки ООП здесь очевидны.
Именно поэтому когда вы хотите новую парадигму, не надо обрезать существующий язык, надо брать новый, и строить его с нуля. При этом у вас получится именно то, что нужно в вашей парадигме
Нет, не очевидны. Есть недостатки вашей реализации неизвестной задачи. А по мере конкретизации задачи (как можно видеть буквально в вашем примере) ООП обратно отыгрывает свои позиции.
List(T) нельзя использовать в качестве множества, потому что он позволяет многократное включение одного и того же элемента.
Об этом я говорил с самого начала: необходимость строить такую (мета)сущность считаю недостатком парадигм ООП и E-R.
классу «Слоны» («Стадо слонов»).
Это не метасущность! У нее есть свои собственные атрибуты, собственная идентичность.С точки зрения теории множеств — да.
Слоны и стадо слонов — это две разные вещи.У нас есть три сущности: «Слон», «Список слонов» (точнее, множество слонов — Set) и «Стадо слонов».
Наличие самой метасущности — есть как раз тот камень, на который натыкаешься при проектировании данных при помощи ООП.
С точки зрения теории множеств — да.
С точки зрения ООП и E-R моделирования — формально и вне контекста обсуждаемой статьи — тоже да.
Я уже писал, почему в контексте «моделируем сущность средствами ООП и реляционной модели непротиворечивым образом» мы получаем конструкцию, которую можно назвать (мета)сущностью.
достаточно сложной реализации в текущей парадигме непротиворечивой модели
самой возможности реализации противоречивой модели
У нас есть три сущности: «Слон», «Список слонов» (точнее, множество слонов — Set) и «Стадо слонов».
По вашему, какую роль выполняет сущность «Слоны»?
И знать тоже не должен.
Если мы моделируем войсковое соединение, то при таком подходе программист может так запрограммировать бойца (любого экземпляра типа данных «боец»), что тот будет знать о всем количестве войск.
Это, очевидно, неправильно
Слон понятия не имеет о среднем по слонам?
Однако, при наличии соответствующего статического поля у ООП-класса — знает.
Отсюда, статическое поле «среднее по слонам» в классе Слон не должно быть, так как не является свойством экземпляра класса (среднее по слонам логически не может быть свойством объекта слон).
Статическое поле — это поле, назначение которого заключается в обеспечении наличия единого значения для всех экземпляров класса.
Таким образом, в классе ООП не нужны статические поля, а значит, если мы хотим непротиворечивой модели, то их не должно быть, т.е. компилятор их не должен допускать
Да, это я имел ввиду — нельзя завести такое поля. Точнее выражаясь, технически завести-то можно, а логически нет.
Аристотель считал, что у субъекта есть идея существования машин. Эта идея выражена в виде абстрактного типа объектов (машин), существующего в сознании у субъектов. Когда субъект смотрит на объект, он сравнивает то, что он видит, с тем образом, который есть у него в воображении (с типом машин), и, если находит схожие черты, то объект называет машиной, или экземпляром машины. Перечень схожих черт Аристотель назвал типом.
я не вижу смысла тащить термины тип и экземпляр в современные модели.
но в модели термин тип не будет участвовать никогда
Потому что он из той логики, которая дает сбой
Вместо термина тип документа я использую термин класс документов и это будет равносильное утверждение.
Это доказано математиками и неизбежно как воздух
У криса строгое математическое доказательство от противного. Его, кстати, мой сын рассказывал на докладе по математике и получил первое место. так что математики проверили.
ответить
Я говорю не о том, как нам хотелось бы, а о том, как будет непротиворечиво.
Если Вы строите модели которые не подлежат расширению, то нет и проблем — стройте себе типы.
Это доказано математиками
Они не могут ввести два множества «цвет» — это невозможно.
Они отличаются объектами, их составляющими.
надо понимать, что мы имеем дело не с моделью в системе? я много раз об этом говорил. Это понятно?
Не могу найти в дискуссии о какой предметной области идет речь, но от слов есть объекты учета как-то повеяло скучными вещами типа ERP-систем.
На одном классе написано: 15, на другом 20.
Читайте стандарт, он переведен на русский.
Нет смысла писать то, что уже описано [...] Поэтому идите к ним, читайте, что они пишут, смотрите видео и постепенно Вы начнете понимать.
Нет, я не могу применить логическую парадигму к другой отрасли
Я работаю в отрасли.ю которая описывает активность.
A class_of_information_representation is a class_of_arranged_individual that defines a pattern that represents information.
EXAMPLE The texts formed with the pattern of characters 's' concatenated with 'u' concatenated with 'n' are members of the 'sun' сlass_of_information_representation.
То есть в этой онтологии числа и информация — понятия существенно разные, число как абстрактная идея может быть по разному представлена.
Нет, откуда такой вывод? Символ — это такой же паттерн, как и строка символов. Класс.
A class_of_information_representation is a class_of_arranged_individual
class_of_individual is a class whose members are instances of possible_individual.
я не программист и код не изучаю
я представляю код как предметную область, затем произвожу его анализ и могу переводить термины программиста в термины логической парадигмы. Это нормальная практика. И я могу это делать
ООП вообще не опирается на парадигму
В своих изложениях я опираюсь на логическую парадигму, в которой есть объект и есть множество объектов, называемое классом объектов, но нет терминов экземпляр, тип и термина класс в смысле ООП.
Идея ООП в том, что есть тип данных, и экземпляры этих данных.
метод все же начнет пользоваться экземплярными данными класса
экземпляры этих типов данных
Использование статических методов в нестатических классах — тоже опасная вещь, и лучше выносить их в хеплер (статический класс), т.к. наличие в нестатическом классе статического метода имеет подводный камень: что если, в будущем этот метод все же начнет пользоваться экземплярными данными класса (состоянием объекта)? придется объявлять метод экземплярным, а ведь есть уже куча кода, которая его вызывает и считает статическим; если вы четко видите, что метод не вынести в хелпер, значит, понимаете, что метод неразрывно связан с классом и потенциально может стать экземплярным.
Более того, класс, создание экземпляров которого предусмотрено через фабрику, без фабрики, видимо, лучше вообще не употреблять и его конструктор сделать internal, и положить класс в одну сборку с фабрикой. Тогда создание только через статик-метод фабрики.
Более того, я являюсь сторонником известной концепции «конструктор не должен порождать исключений» (по причине того, чтобы не получить экземпляр класса — объект с несогласованным внутренним состоянием, т.к. уж очень многие любят подавлять исключения).
Мы не можем полагаться на реализацию «экземплярный конструктор реализован через статический метод». К экземплярным полям он имеет доступ как-то?
А тогда, если конструктор получает на вход параметры, значения (сочетания значений) которых могут оказаться недопустимыми, остается только идти путь:
ArgumentException в конструкторе — прекрасная вещь. Чтобы далеко не ходить: конструктор FileStream может кинуть девять разных искключений.Настаиваю на том, что их нельзя применять «концептуально» — например, для реализации теории множеств.
Есть языки, в которых исключение, порожденное в конструкторе, приведет к тому, что объект не будет создан вообще (например, C#).
Вы усложняете. ArgumentException в конструкторе — прекрасная вещь. Чтобы далеко не ходить: конструктор FileStream может кинуть девять разных искключений.
Ээээ, а в чем проблема? Прелесть статического метода (по крайней мере, в C#) в том, что можно создать объект, а потом обращаться к любым его полям, потому что область видимости — внутренняя.
Понятно, но в общем случае (берять за какой-то язык или его версию) нужно смотреть спецификацию — такое поведение это детали реализации конкретной версии компилятора, или же нам спецификация гарантирует это.
Т.е., экземплярный конструктор, будучи реализованным как статик-метод, что вначале делает?
А ведь, в т.ч, именно это провоцирует программистов на ложное представление, что, заведя статик-поля, можно использовать их не просто как часть типа данных, а как данные, общие для множества объектов — всех экземпляров данного класса (экземпляров типа данных).
Это представление не ложное, а истинное. Статические поля действительно можно использовать как данные, общие для конкретного множества объектов (всех экземпляров этого типа в рамках application domain, если мы говорим о .net).
Так и в нашем случае — что вы имеете в виду под словом «можно»? Компилятор допускает это, или «можно» вы понимаете как «нужно» (по крайней мере, в для определенных случаев)?
не является все же ли MaxValue характеристикой типа данных
тем более, что технически это не поле, а константа
если же нет, то (это не характеристика типа данных, а данные общие для всех экземпляров типа данных.
когда механизм статиков из-за неверного понимания используется, когда нельзя?
Так ли необходимо, чтобы они имели доступ ко внутреннему состоянию объекта?
XmlReader.Create возвращает экземпляр некоего неизвестного пользователю типа, наследующегося от XmlReader (который абстрактный). Собственно, поэтому это фабричный метод, а не конструктор.Дело в том, что ООП подменил понятия. В ООП под классом понимается не множество, как обычно принято в математике, или лингвистике.
Хорошо было бы понимать аналитику, что имел ввиду программист, когда сказал, что создал класс.
Но, если аналитик сидит с программистом и решает задачу описания предметной области, используя термин создадим класс, то я усомнюсь в том, что аналитик обсуждает сейчас предметную область.

Как устроено сущее никто и никогда понять не сможет.
ОНТОЛОГИЯ – учение о бытии как таковом; раздел философии, изучающий фундаментальные принципы бытия, наиболее общие сущности и категории сущего.
Эпистемоло́гия — теория познания, раздел философии.
И хочу, чтобы программисты осознавали сам процесс переноса модели в код.
Хотелось бы иметь такие язык программирования, платформу разработки, теорию БД, СУБД, которые позволили бы в „нативных“ для себя терминах реализовывать модель предметной области в терминах именно теории множеств.
Мне кажется, необходимость появления таких инструментов в мейнстриме давно уже назрела.
Но вот почему тип был назван классом, не раскрывают.
Дальше — вопрос жонглирования терминами, является структура классом.
В терминах C# — нет, не является. У них существенные отличия в поведении.Можете ли вы назвать такие отличия, которые вывели бы структуры C# из обсуждения «Классы как тип данных — Классы как множество объектов», или наоборот, ввели бы в формате «Классы как тип данных — Структуры как тип данных — Классы как множество объектов»?
В C# достаточно строго выдерживается подход «все есть объект», поэтому с value-типами тоже можно работать как с объектами. Однако это не делает все типы данных классами.
public abstract class ValueType
Предоставляет базовый класс для типов значений.
Provides the base class for value types.
public struct Int32
All structs inherit directly from System.ValueType, which inherits from System.Object.
Within a struct declaration, fields cannot be initialized unless they are declared as const or static.
A struct cannot declare a default constructor (a constructor without parameters) or a destructor.
Structs are copied on assignment. When a struct is assigned to a new variable, all the data is copied, and any modification to the new copy does not change the data for the original copy. This is important to remember when working with collections of value types such as Dictionary<string, myStruct>.
Structs are value types and classes are reference types.
Unlike classes, structs can be instantiated without using a new operator.
Structs can declare constructors that have parameters.
A struct cannot inherit from another struct or class, and it cannot be the base of a class. All structs inherit directly from System.ValueType, which inherits from System.Object.
A struct can implement interfaces.
A struct can be used as a nullable type and can be assigned a null value.
Можете ли вы назвать такие отличия, которые вывели бы структуры C# из обсуждения «Классы как тип данных — Классы как множество объектов», или наоборот, ввели бы в формате «Классы как тип данных — Структуры как тип данных — Классы как множество объектов»?
Точно так же, как статический класс есть синтаксический сахар — когда мы пишем «static class» компилятор генерирует sealed class с закрытым (private) конструктором. Если не ошибаюсь, Рихтер писал об этом в CLR via C# 2.0?
Не находите, что в некоем воображаемом новом языке программирование было бы неплохо ввести ключевое слово type (или datatype) для обозначения типа данных, а ссылочность/значимость, запечатанность, статичность задавать всегда клювевыми словами модификаторами?
Статический класс — это вообще костыль, не имеющий отношения к ООП. Но формально класс.
Если вы хотите другую терминологию, вам придется найти другую парадигму.
в ООП мы определяем класс, полностью его описываем, а потом объекты создаем
Первый — это класс заданный перечислением его объектов. Второй — правилом, по которому объекты попадают в класс.Я бы не стал разделять на эти типы, поскольку «перечисление» — это то же правило по которому объект попадает в класс. )))
Не всякому классу мы приписываем типКак классу приписывается тип?
А когда у нас может возникнуть ситуация, в которой мы хотим приписать новый атрибут классу, к которому новых атрибутов приписывать нельзя?А откуда мы, а лучше сказать, программа, знает, что можно, а что нельзя? Вы при при создании класса решили, что это класс вида «атрибут», а как я узнаю про это, если заменю вас после вашего увольнения )))
В случае с классом красных предметов мы можем добавить атрибут оттенок. и тогда класс красных предметов можно будет поделитьЕсли класс создан по единству «атрибута» (красный), то да, добавление нового атрибута (оттенок) разбивает его на подклассы. А если класс объединяет объекты некоторого типа (автомобили), то добавление, скажем, такого атрибута как «длина», разбивает его на подклассы? Или мы просто имеем дело с атрибутом всех элементов класса «машины»?
. Возможно, тогда станет ясно, что наше мышление навыворот. Нет континуума в природе. Это наша мысленная конструкция. На самом деле есть только попарное сравнение. Больше ничего. Шкала всегда имеет дискрету. Даже самая точная.А вот пересечение классов вида «тип», должны быть пустыми: «самолет» и «кошка», «колесо» и «дерево»
Поэтому представление типа — это набор атрибутов. И запись типа, на мой взгляд, может состоять из одного атрибута.Еще раз здесь поясню: вот и получается, что класс из объектов одного типа формально отличается от класса объектов с совпадающим атрибутом (атрибуты не представляются набором атрибутов). Вопрос: это надо игнорировать или как-то формально учитывать?
Кстати, наверное, не стоит приравнивать группы объектов и классы.
нельзя покрасить машину, можно покрасить только каждую деталь
Я говорил, что группу колес нельзя снять, потому что не определен термин «снять» для группы объектов.Расскажите это Васе в гараже. ))) Я же несколько раз повторил, что говорю не о модели, а о реальном гараже, реальной машине, реальных колесах и реальном Васе, который возьмет «вот эти четыре колеса» и прикрутит их к машине даже не задумываясь как переопределить термин «прикрутить».
Особенности моделирования предметной области с помощью ООП