Отношения многие ко многим

Общие вопросы программирования, алгоритмы и т.п.

Модератор: Модераторы

Re: Отношения многие ко многим

Сообщение Brainenjii » 28.06.2012 23:02:22

э не, толк есть - навигация в модуле из 700 строк куда проще чем в модуле из 5000 строк. Один класс -> один модуль. Определяющим для меня является это, а не количество строк (хотя обычно выходят те самые 700 строк). А ползать по исходникам где есть что.
Хотя ладно, согласен, паскаль станет хуже, если ему дать поддержку пространства имён. Даже не, namespace'ы - это крайне неудобная и вообще отрицательная фича, вот модульность рулит и просто опередила своё время. Да и что там, синтаксический сахар (если их можно к этому отнести) вообще зло. Тему можно закрыть, нема мне поддержки в этом вопросе >_<
Аватара пользователя
Brainenjii
энтузиаст
 
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46

Re: Отношения многие ко многим

Сообщение stikriz » 28.06.2012 23:15:30

Не оставляет ощущение, что он препод, а не профессиональный программист. Отсюда, как все преподы, полный изврат в мозгах, и желание всяческих глупостей. Может, это неполиткорректно, но уже несколько проблем обозначили, а все толку мало - для него это ерунда. А дальше разработка будет как у известных индусов. И окажется. что весь мир построен неправильно :-) Простите за чисто эмоциональную оценку, но это факт. И проект сдохнет. "Уж сколько раз твердили миру..."

Добавлено спустя 3 минуты 20 секунд:
Brainenjii писал(а):Хотя ладно, согласен, паскаль станет хуже, если ему дать поддержку пространства имён.

Мало кто знает, что такое поддержка пространства имен. На самом деле, это полностью реализовано в 1С.:
Документы.Заказы покупателей
Перечисления.ЗаказыПокупателей
РегистрСведений.ЗаказыПокупателей
и т.д. и т.п.
Вот это и есть по ОМГ пространство имен.
Аватара пользователя
stikriz
энтузиаст
 
Сообщения: 612
Зарегистрирован: 15.03.2006 09:37:47

Re: Отношения многие ко многим

Сообщение Brainenjii » 29.06.2012 08:28:18

на месте ОМГ должно быть ИМХО? ^_^ В паскале при разбитии кода по модулям создать подобное приведённым вами возможностям 1С так же легко. Я же говорю о другом:
Grade.cs:
Код: Выделить всё
using System;
using System.Collection.Generic;

namespace School{
  class Grade {
    public List<Pupil> Pupils;
  }
}

Pupil.cs:
Код: Выделить всё
using System;
using System.Collection.Generic;

namespace School{
  class Pupil {
    public Grade CurrentGrade;
  }
}

Теперь к глупостям и полному изврату в мозгах. Открываем /path/to/fpc-sources/rtl/objpas/classes/classesh.inc (даже не пытайтесь удивляться .h, не отвлекайтесь). Смотрим класс TCollection (пожалуйста, попробуйте подумать, как сюда отнести класс с учениками). Внимательно смотрим. И поражаемся глупостям и полному изврату в мозгах тех, что это написал. Уважаемый stikriz, пожалуйста, укажите, чем именно различаются эти два подхода?
Ещё раз. Забудьте обо всём написанном выше, там масса уходов в сторону от проблемы.
Unit Complex:
Код: Выделить всё
Type
  ..
  TCollection = class;

  TCollectionItem = class(TPersistent)
  private
    FCollection: TCollection;
    ..
  protected
    procedure SetCollection(Value: TCollection);virtual;
    ..
  Public
    property Collection: TCollection read FCollection write SetCollection;
    ..
End;
  ..
  TCollection = class(TPersistent)
  private
    FItems: TFpList;
    ..
  protected
    ..
    function GetItem(Index: Integer): TCollectionItem;
    procedure SetItem(Index: Integer; Value: TCollectionItem);
    ..
  public
    property Items[Index: Integer]: TCollectionItem read GetItem write SetItem;
    ..
end;

Это нормальный код? Нет изврата в мозгах? Славно.
Unit Collection:
Код: Выделить всё
Type

  TCollection = class(TPersistent)
  private
    FItems: TFpList;
    ..
  protected
    ..
    function GetItem(Index: Integer): TCollectionItem;
    procedure SetItem(Index: Integer; Value: TCollectionItem);
    ..
  public
    property Items[Index: Integer]: TCollectionItem read GetItem write SetItem;
    ..
end;

Unit TCollectionItem:
Код: Выделить всё
Type

  TCollectionItem = class(TPersistent)
  private
    FCollection: TCollection;
    ..
  protected
    procedure SetCollection(Value: TCollection);virtual;
    ..
  Public
    property Collection: TCollection read FCollection write SetCollection;
    ..
End;

Всё? Появился изврат в мозгах? Пора приводить всё к 3 нормальной форме (правда при чем она тут, ну да ладно). Будет ведь люто-бешено некорректно разрешить на уровне языка создавать такие конструкции, разбитые по разным модулям? Ведь неудобно же! Правда?
Я все правильно сказал?
А если серьёзно - посмотрите модель пакетов в Java. Почитайте. Подумайте! И попробуйте ответить себе на два вопроса - чем продвинутая модель пространства имён в форме джава-пакетов или в реализации С# в паскале может быть неудобна, и чем она может помочь. И, пожалуйста, не бросайтесь отвечать, не ответив себе на эти два вопроса.
Аватара пользователя
Brainenjii
энтузиаст
 
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46

Re: Отношения многие ко многим

Сообщение stikriz » 29.06.2012 08:42:20

Brainenjii писал(а):Я все правильно сказал?

Нет. Зачем нужны колекции знаем? Посмотрите как устроена какая-нибудь грида, например.
Brainenjii писал(а):И попробуйте ответить себе на два вопроса - чем продвинутая модель пространства имён в форме джава-пакетов или в реализации С# в паскале может быть неудобна, и чем она может помочь.

Кто-то тут об удобстве говорит? Работать вообще неудобно - надо сидеть и думать, глаза напрягать... Да, и модули все длинные - все больше 700 строк :-). Вот, пиво с сордельками на пляже под зонтиком - вот это удобство :-) Я привел два аргумента, почему Ваш подход - это изврат. Если Вы считаете, что это не аргументы, то что я могу поделать. Остается только пожелать удачи.
Аватара пользователя
stikriz
энтузиаст
 
Сообщения: 612
Зарегистрирован: 15.03.2006 09:37:47

Re: Отношения многие ко многим

Сообщение Brainenjii » 29.06.2012 08:49:30

stikriz, Вы точно прочитали предыдущий пост?
Аватара пользователя
Brainenjii
энтузиаст
 
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46

Re: Отношения многие ко многим

Сообщение stikriz » 29.06.2012 08:56:13

Brainenjii писал(а):stikriz, Вы точно прочитали предыдущий пост?

Точно.
Аватара пользователя
stikriz
энтузиаст
 
Сообщения: 612
Зарегистрирован: 15.03.2006 09:37:47

Re: Отношения многие ко многим

Сообщение Brainenjii » 29.06.2012 09:06:33

Т.е. на вопрос - почему паскаль мне запрещает разносить перекрестно ссылающиеся друг на друга классы по разным файлам на примере коллекций Вы мне предложили изучить назначение коллекций? Браво! Если я открою какой-нибудь controls.pp - Вы мне начнёте предлагать изучать назначение TWinControl, TControl, TDragObject, TDragDockObject... Продолжать? Может ещё какой исходник открыть?
Блин... Прекратите привязываться к примерам! Проблема в структуре пространства имён в паскале сейчас. Почему проблема? Потому что заставляет держать в одном файле описания десятков классов! Про различия в Strict Private и Private и ещё нескольких появляющихся после обновления текущей системы пространства имён в паскале до уровня более новых языков (при всей всеобщей нелюбви к C#/Java эти языки были созданы позже паскаля, хоть с этим спорить не будете? И некоторые, определённо удачные, идеи оттуда было бы очень замечательно позаимстовать). Вопрос, блин, элементарного УДОБСТВА программирования!
А "сордельки" придержите при себе.

Добавлено спустя 7 минут 35 секунд:
отдельно и специально для товарща stikriz'a. Надеюсь так он не проигнорирует.
Код: Выделить всё
Type TPupil = Class;
Type TPupils = Specialize TFPGList<TPupil>;
Type TGrade = Class
  Private
    fPupils: TPupils;
    Function GetPupils: TPupils
  Public
    Property Pupils: TPupils Read GetPupils;
End;
Type TPupil = Class
  Private
    Function GetGrade: TGrade;
  Public
    Property Grade: TGrade Read GetGrade;
End;

GetPupils и GetGrade обращаются к приватному классу TTableAssociations, содержащему таблицу соответствий классов и их учеников и методы работы с ней. Решил первую проблему? Что удобнее использовать
Код: Выделить всё
Var
  aPupil: TPupil;
  aGrade: TGrade;
Begin
  ..
  If aGrade.Pupils.IndexOf(aPupil) = -1 Then
    ..
  Else
    ..;
  ..
End;

или

Код: Выделить всё
Var
  aPupil: TPupil;
  aGrade: TGrade;
  aTableAssociations: TTableAssociations;
Begin
  If aTableAssociations.CheckPupilInGrade(aGrade, aPupil) Then
    ..
  Else
    ..;
  ..
End;

Угадайте, какой из двух вариантов более инкапсулирован? Какой наглядней? Какой очевидней? При том что с функциональной точки зрения они идентичны!
И, напомните, о второй проблеме? Хотя, если верить что тот пост вы читали, я просил забыть обо всём что было сказано выше. Или Вы меня обманули, или проигнорировали.
Аватара пользователя
Brainenjii
энтузиаст
 
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46

Re: Отношения многие ко многим

Сообщение stikriz » 29.06.2012 09:19:51

Brainenjii писал(а):Т.е. на вопрос - почему паскаль мне запрещает разносить перекрестно ссылающиеся друг на друга классы по разным файлам на примере коллекций Вы мне предложили изучить назначение коллекций?

Вам сразу сказали, что можно сделать два класса, а потом в третьем модуле от них отнаследоваться, используя для ссылок предков, и это паскаль не запрещает. Смысл не в этом. Смысл в том, что в конкретно Вашей программе, в том случае, как Вы описали, делать изврат ненужно. Коллекции нужны, чтобы не писать самому ридеры-райтеры. И таких извратов в компонентном программировании много, и не надо их плодить дополнительно.
Brainenjii писал(а):А "сордельки" придержите при себе.

А я и не собирался делиться:-) Понимаете, есть язык программирования, и он такой. И это хорошо. Если Вы считаете, что так плохо, то есть варианты: написать новый компилятор самому, пусть и на основе исходников FPC, уйти на другие правильные удобные языки. Лично я не вижу никакого неудобства. Наоборот, это неплохо дисциплинирует и разминает мозг. Мне, вот, тоже иногда хочется, например, чтобы все операторы стали операциями, даже интерпретатор паскаля свой так и написал. Но, сам же и не пользуюсь - выразительнее два раза присвоить в двух операторах. И таких хотелок тут можно насобирать вагон и маленькую тележку.

Добавлено спустя 14 минут 59 секунд:
AGrade:=AScool.Grade[APupil];
Вот так удобнее и нагляднее всего.
Аватара пользователя
stikriz
энтузиаст
 
Сообщения: 612
Зарегистрирован: 15.03.2006 09:37:47

Re: Отношения многие ко многим

Сообщение Brainenjii » 29.06.2012 09:41:08

Вам сразу сказали, что можно сделать два класса, а потом в третьем модуле от них отнаследоваться, используя для ссылок предков, и это паскаль не запрещает. Смысл не в этом. Смысл в том, что в конкретно Вашей программе, в том случае, как Вы описали, делать изврат ненужно. Коллекции нужны, чтобы не писать самому ридеры-райтеры. И таких извратов в компонентном программировании много, и не надо их плодить дополнительно.
А я сразу согласился, но указал, что изврат и костыль как раз это. Забудьте о каких либо примерах, вернёмся к чистой абстракции.
Один класс имеет ссылку на второй класс, второй - на первый. И я должен или держать их в одном модуле, или создавать совершенно не нужный мне промежуточный класс.
Есть такой замечательный принцип открытия-закрытия. Не изменяя текущего положения вещей в паскале мы можем дополнить его возможности, добавив поддержку более развитой системы пространства имён, в форме тех же Java'овских пакетов. stikriz, зайдём с другой стороны - а в чем плюсы того, что мне запрещено разбивать связанные классы на разные модули, связанные одним пространством имён?
Вам сразу сказали, что можно сделать два класса, а потом в третьем модуле от них отнаследоваться, используя для ссылок предков, и это паскаль не запрещает. Смысл не в этом. Смысл в том, что в конкретно Вашей программе, в том случае, как Вы описали, делать изврат ненужно. Коллекции нужны, чтобы не писать самому ридеры-райтеры. И таких извратов в компонентном программировании много, и не надо их плодить дополнительно.
Гораздо проще написать собственный препроцессор, который будет исправлять некоторые косяки паскаля. Но он будет работать медленней и костыльней, чем реализация правильных методик в самом компиляторе. На патчи к самому компилятору знаний и времени не хватит :-(
Но, сам же и не пользуюсь - выразительнее два раза присвоить в двух операторах
А чем плохо использовать свойства в качестве Var/Out аргуметов методов? Или это тоже "он такой. И это хорошо."?

Предпоследний вопрос. stikriz, Вы считаете, что перекрестная связь между классами - зло (вида <ClassName> = Class;)?
И если нет (повторение мать учения), в чем плюсы того, что я не могу классы с перекрестными ссылками друг на друга разнести на разные модули без создания дополнительных родительских классов (при том что при замещении в одном модуле они не нужны)?

Добавлено спустя 1 минуту 20 секунд:
AGrade := APupil.Grade; - ну вот вообще ненаглядно и неудобно :-D Всё правильно, с точки зрения АТД ученик и не должен знать в каком классе он учится. Не с точки зрения алгебры множеств, а с точки зрения здравого смысла.
Аватара пользователя
Brainenjii
энтузиаст
 
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46

Re: Отношения многие ко многим

Сообщение stikriz » 29.06.2012 09:59:25

Brainenjii писал(а):Один класс имеет ссылку на второй класс, второй - на первый.

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

Вы можете? Ну, дополните его возможностями. А мы посмотрим, может и хорошо будет. Или вы не можете? Вы, в смысле Вы и еще кто-то с Вами :-)
Brainenjii писал(а):А чем плохо использовать свойства в качестве Var/Out аргуметов методов?

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

В том, что если подумать, то Вам само собой прийдет правильная структура. Вам нужен некий объект, который объединит классы с учениками. И это правильно.
Brainenjii писал(а):AGrade := APupil.Grade; - ну вот вообще ненаглядно и неудобно :-D

School.Grade[Pupil] или School.Grade(Pupil) нагляднее. Тут я вижу, что есть школа, в которой классы, а в них есть ученики. Фактически, так и есть в реальном мире. А в Вашем случае, есть какой-то сферический ученик, у которого есть класс. И непонятно, у каждого ученика есть свой отдельный класс, или у некоторый один на двоих-троих... Разговор ни о чем, как на Болотной - "Хочу всего хорошего, и не хочу плохого!!!!" :-)
Аватара пользователя
stikriz
энтузиаст
 
Сообщения: 612
Зарегистрирован: 15.03.2006 09:37:47

Re: Отношения многие ко многим

Сообщение Brainenjii » 29.06.2012 10:17:11

Да Боже ж ты мой. Вы про геттеры читали вообще? Пускай ученик спрашивает школу, в каком классе он учится. Но что AGrade := APupil.Grade; менее наглядно чем School.Grade[Pupil] или School.Grade(Pupil) - ну слов нет. Всякий раз, когда мне нужно получить класс от ученика, вы предлагаете обращаться к школе, напрочь разрушая инкапсуляцию, выводя работу между учеником и его классом прямо на всю школу. Вы действительно верите что это лучше, чем когда пользователь класса TPupil просто запросит у него текущий класс и ему (пользователю) совершенно не нужно знать, что на самом деле ученик спрашивает школу - а в каком же классе он учится. Вы действительно верите, что держать постоянно в голове, что связь я могу получить только из школы, явным образом к ней обратившись - удобнее и нагляднее? В таком случае я, кажется, наконец нашёл в чём наши представления об удобстве, инкапусляции и ООП в общем, расходятся.
Аватара пользователя
Brainenjii
энтузиаст
 
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46

Re: Отношения многие ко многим

Сообщение stikriz » 29.06.2012 10:34:55

Brainenjii писал(а):Вы действительно верите что это лучше, чем когда пользователь класса TPupil просто запросит у него текущий класс и ему (пользователю) совершенно не нужно знать, что на самом деле ученик спрашивает школу - а в каком же классе он учится.

Мы плавно переключились на пользовательский интерфейс?
Brainenjii писал(а):Вы действительно верите, что держать постоянно в голове, что связь я могу получить только из школы, явным образом к ней обратившись - удобнее и нагляднее?

Да. Все равно нужен объект школа, ну не в листе же Вы будете хранить ссылки на классы? Так, почему бы не сделать такой метод у того класса, который владеет и теми и теми? Кому как не школе лучше знать? Кстати, а в музыкальной школе... Вы сделаете еще один класс, типа, класс музыкальной школы? А в художке? Чтобы понять отношения объектов, нужно немного шире смотреть на проблемы.
Brainenjii писал(а):напрочь разрушая инкапсуляцию

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

Добавлено спустя 3 минуты 9 секунд:
Инкапсуляция - это только лишь создание интерфейса класса, и сокрытие конкретной реализации - не более того. Вопросы кто именно чем владеет - это к инкапсуляции не имеет никакого отношения.
Аватара пользователя
stikriz
энтузиаст
 
Сообщения: 612
Зарегистрирован: 15.03.2006 09:37:47

Re: Отношения многие ко многим

Сообщение Brainenjii » 29.06.2012 10:43:21

ВОТ ОНО! Пришли! Я не могу инкапсулирвать мой способ через вызовы метода школы (то о чем я Вам твержу начиная с viewtopic.php?p=63350#p63350 и раскрывая в viewtopic.php?p=63367#p63367)! Почему не могу? Потому что паскаль не разрешает мне содержать упоминание о классе в интерфейсе ученика, если в интерфейсе класса есть упоминания об учениках! Вы упорно пытаетесь помочь мне решить не ту проблему о которой я говорю!
а. Все равно нужен объект школа, ну не в листе же Вы будете хранить ссылки на классы? Так, почему бы не сделать такой метод у того класса, который владеет и теми и теми? Кому как не школе лучше знать? Кстати, а в музыкальной школе... Вы сделаете еще один класс, типа, класс музыкальной школы? А в художке? Чтобы понять отношения объектов, нужно немного шире смотреть на проблемы
Спасибо за пояснения в ООП.
Надо сесть за учебники, и еще разок прочитать про инкапсуляцию. По моему, Вы что-то тут недопонимаете.
Не знаю, совет это, или озвученное желание ^_^ Если вдруг по какой-то причине не читали Совершенный код - крайне рекомендую. Основы ООП там разобраны прекрасно.
Мы плавно переключились на пользовательский интерфейс?
Пользователь - это любой класс, который пользуется TPupil'ом.
Аватара пользователя
Brainenjii
энтузиаст
 
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46

Re: Отношения многие ко многим

Сообщение stikriz » 29.06.2012 10:45:23

Brainenjii писал(а):ВОТ ОНО! Пришли!

stikriz писал(а):Можно и делегированием метода.
Аватара пользователя
stikriz
энтузиаст
 
Сообщения: 612
Зарегистрирован: 15.03.2006 09:37:47

Re: Отношения многие ко многим

Сообщение Brainenjii » 29.06.2012 10:47:09

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

Я не говорю сейчас о том кто кем владеет. Я хочу спрятать от всех тех, кто хочет узнать, в каком классе учится ученик всю сложную систему, которая позволяет узнать это наверняка. Утрированный и не имеющий отношения к предмету пример, пожалуйста, не упоминайте его далее, он просто для иллюстрации - когда вы заходите в школу и спрашивает первого попавшегося ученика - в каком классе он учится - он бежит узнавать это в школе? Или у него есть собственный кеш этой информации, которая в over99,(9)% случаев верна? Но то что школа знает наверняка, и что правильный ученик обязательно сбегает в учебную часть уточнить, я не отрицаю. Просто Вам это должно быть не нужно знать...

Добавлено спустя 7 минут 24 секунды:
Unit School:
Код: Выделить всё
Type TSchool = Class
  ..
    Public
      Function GetGradeOfPupil(Const aPupil: TPupil): TGrade;
      Function GetPupilsOfGrade(Const aGrade): TPupils;
      ..
End;

Unit Grade:
Код: Выделить всё
Type TGrade = Class
  Private
    fSchool: TSchool;
    ..
    Function GetPupils: TPupils;
  Public
    Property School: TSchool Read fSchool; // приехали
    Property Pupils: TPupils Read GetPupils;
  ..
End;
..
Function TGrade.GetPupils: TPupils;
Begin
  Result := fSchool.GetPupilsOfGrade(Self);
End;

Unit Pupil:
Код: Выделить всё
[code]
Type TPupil = Class
  Private
    fSchool: TSchool;
    ..
    Function GetGrade: TGrade;
  Public
    Property School: TSchool Read fSchool; // приехали
    Property Grade: TGrade Read GetGrade;
  ..
End;
..
Function TPupil.GetGrade: TGrade;
Begin
  Result := fSchool.GetGradeOfPupil(Self)
End;

Всё, приехали. Не может ученик знать, в какой школе он учится. Или ему надо в гороно сбегать, уточнить? Хватит бредить! Перекрестные ссылки - это хорошо и правильно! Косяк в том что я не могу их реализовать в разных модулях!
Аватара пользователя
Brainenjii
энтузиаст
 
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46

Пред.След.

Вернуться в Общее

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 6

Рейтинг@Mail.ru