Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.07.21;
Скачать: CL | DM;

Вниз

Помогите разорвать замкнутый круг, не нарушив при этом основ ООП!   Найти похожие ветки 

 
MaXie ©   (2003-07-08 10:50) [0]

Есть четыре переменные: A, B, C и D. Первые три из них объединены в запись, т.е. сгруппированы по функциональному предназначению (, в реальной задаче - это есть ни что иное, как A - день, B - месяц и C - год). Главная цель - это определение всех четырех переменных.
Т.к. переменные разбиты на две группы (группа №1: A, B и C; группа №2: D), для их определения необходимы две функции, каждая из которых определяла бы свою группу переменных. Пусть функция func1 в результате выполнения определяет первую группу переменных, т.е. - A, B и C. Соответственно, функция func2 будет определять вторую группу - переменную D. Такой подход к решению задачи целиком и полностью следует концепции ООП!
Но вот, что получается на практике (Речь идет о взаимодействии клиентского приложения с БД)!
Функция func1, определяющая переменные A, B и C, способна определить только первые две переменные A и B. Определение переменной C не представляется возможным без определенной переменной D!
Функция func2, определяющая переменную D, может определить свою переменную только при определенных переменных A и B!
В результате получается, что для определения всех переменных необходимо:
1. Выполнить "часть" функции func1, которая вернет переменные A и B;
2. Выполнить функцию func2, которая по определенным на первом этапе переменным A и B, вернет переменную D;
3. Выполнить второй раз функцию func2, которая по определенной переменной D, доопределить переменную C.

Как разорвать этот замкнутый круг, не нарушив основ ООП?


 
Th ©   (2003-07-08 10:55) [1]

Вызвать func2 внутри func1


 
MaXie ©   (2003-07-08 11:03) [2]

Хорошое предложение! Но тут все дело в этом пресловутом ООП!
У нас есть два объекта - две группы переменных! Как в этом случае обеспечить взаимонезависимость друг от друга?
Как быть в случае, если требуется определить только переменную D?
Да! Так же, не пройдет вариант и с разбиением функции func1 на две подфункции, т.к. в этом случае так же будет нарушение ООП - достаточно расмотреть вариант с первоначальной стадией определения переменных!

Подкиньте, плз., еще какую нибудь идею!


 
default ©   (2003-07-08 11:25) [3]

procedure Proc1(var A, B: Byte; var C: Word; f: Char = "1");
var
D: Word;
begin

A := 10;
B := 12;
if f = "2" then Exit;
Proc2(A, B, D, "1");
C := not D;

end;

procedure Proc2(var A, B: Byte; var D: Word; f: Char = "2");
begin

if f = "2" then Proc1(A, B, "2");
D := A + B

end;


 
ЮЮ ©   (2003-07-08 11:29) [4]

При чем здесь ООП, если речь идет о переменных и функциях?

>У нас есть два объекта - две группы переменных! Как в этом случае обеспечить взаимонезависимость друг от друга?

??? Если объекта два, то как они могут быть зависимы ?


 
Jeer ©   (2003-07-08 11:36) [5]

Не вполне ясно при чем тут ООП.
Во всяком случае, раз есть взаимозависимость, возможно не совсем верно сделано разбиение.

Методы:
SetAB - устанавливает значения A,B.
SetD - .. D на основе A,B.
SetC - .. C на jcyjdt В.
SetABC -> SetAB,SetD,SetC - начальная установка


 
MaXie ©   (2003-07-08 11:48) [6]

> default
Буквально в двух словах, опиши вызов двух представленных тобой процедур (хотя речь шла о функциях и это достаточно принципиальный момент!) при начальном условии, т.е. значение всех переменных равно NULL.

> ЮЮ
Объясню. Чтобы описать реальную задачу здесь в форуме, мне бы не хватило и двух дней - поэтому я до предела упростил ее постановку! На практике, речь конечно же идет об объектах, каждый из которых имеет свой собственный метод для определения своих полей (или свойств). Понятно, что вызывать чужой метод в составе метода другого объекта это ... - по-меньшей мере, безграммотно! Поэтому предложение уже высказанное здесь (пусть одна функция участвует в составе другой) не подходит - это противоречит ООП!
Что же касается переменных и функций - это лишь формальный способ представить специфику стоящей задачи (проблему алгоритма ее решения)!
Просто все выглядит тривиально и просто, но вот решение не получается простым и очевидным, а "городить огород" не хотелось бы!



 
MaXie ©   (2003-07-08 11:54) [7]

> Jeer
Я чуть выше сделал оговорку на то, что функцию func1 недопустимо разбить на две подфункции!

> Не вполне ясно при чем тут ООП.
Дело в том, что говоря не о функциях и переменных, а об объектах (, а на практике это именно так и является), ты предлагаешь определить сначала "часть" (кусок) первого объекта, затем определить второй объект, и лишь после этого, доопределить первый объект - как то сложно получается! А если рассмотреть ситуацию, что нам не нужно пока определять первого объекта, а необходим только второй (, т.е. func2), как ты будешь действовать в этом случае?
Вот причем тут ООП и откуда появляется неразрывная взаимосвясь между двумя объектами!


 
Jeer ©   (2003-07-08 11:56) [8]

Ничто не мешает объявить общий предок и в нем метод начальной инициализации, определяемый в child_объектах


 
MaXie ©   (2003-07-08 12:01) [9]

> Jeer
Т.е. ты предлагаешь, чтобы оба объекта произошли от одного предка?
Если несложно чуть-чуть по подробней описать свое предложение...


 
Anatoly Podgoretsky ©   (2003-07-08 12:02) [10]

MaXie © (08.07.03 11:54)
Это ты сейчас говоришь об объектах, методах и полях, а до этого о функциях и пока о переменных


 
default ©   (2003-07-08 12:10) [11]

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


 
Jeer ©   (2003-07-08 12:12) [12]

Есть объект КОРАБЛЬ, состоящий из множества субобъктов, в частности, ДВИГАТЕЛЬ и РУЛЬ.
Для того, чтобы выполнить метод КОРАБЛЬ.ПОВОРОТ надо выполнить последовательно методы ДВИГАТЕЛЬ.ХОД_ТИХИЙ, РУЛЬ.ВПРАВО_45,
КОРАБЛЬ.ВЫДЕРЖКА_ВРЕМЕНИ, РУЛЬ.ПРЯМО, ДВИГАТЕЛЬ.ХОД_ПОЛНЫЙ.

Это будет всего одним методом КОРАБЛЯ


 
MaXie ©   (2003-07-08 12:15) [13]

> Anatoly Podgoretsky
Это не принципиально. Переменная типа объект!


 
NickBat ©   (2003-07-08 12:21) [14]

Не вдаваясь в подробности:

Если необходимо разорвать замкнутый круг, то не лучше ли нарушить кое-какие принципы, пусть даже и ООП? :)))


 
Anatoly Podgoretsky ©   (2003-07-08 12:32) [15]

А может не надо нарушать принципы ООП, может лучше правильно сделать?


 
MaXie ©   (2003-07-08 12:41) [16]

> Jeer
Окей! Есть БД, состоящая из двух таблиц: tbDay и tbMonth. Первая содержит набор строк с числовой информацией, разбитой по суткам! Вторая таблица содержит набор строк с числовой информацией разбитой по месяцам (в этой же таблице отражен и год месяца). Чтобы однозначно сопоставить какой день к какому месяцу относится, в таблице tbDay есть поле идентификаторов keyMonth, которое имеет связь один-ко-многим с таблицей tbMonth!
Чтобы определить дату последнего заведенного в БД дня, необходимо:
1. Определить максимальные Год, Месяц в таблице tbMonth.
2. По их комбинации определить ключ keyMonth.
3. По этому ключу сформировать набор строк в таблице tbDay.
4. В сформированном наборе строк определить максимальный День.

Говоря об ООП, я пологал (, ну опять же образно!), что необходимы два объекта-переменных, значения которых будут использоваться в приложении:
1. Дата (запись состоящая из трех полей: Год, Месяц и День);
2. Ключ (keyMonth - по нему устанавливается принадлежность дня или группы дней к тому или иному месяцу)

Как определить методы инициализации, каждого из этих двух объектов? Или ошибка в выборе объектов?


 
MaXie ©   (2003-07-08 13:00) [17]

Приложение работает в следующем режиме:
1. Открытие дня (Инициализация объекта Дата)
- при этом происходит формирование новой строки в таблице tbDay с нулевыми значениями;
2. Работа в течении дня (Объект Дата используется как никогда, т.к. все операции, совершаемые пользователем, должны быть отнесены к заранее (стадия Открытие дня) определенному числу)
3. Закрытие дня (пересчет информации в таблице tbMonth, по ключу keyMonth)

Упрощеный вариант описания работы приложения!

Перекроить БД, значить нарушить принцип построения реляционных СУБД!
Перекроить приложение, значит нарушить принципы ООП!
Дилема: Delphi vs. реляционные БД!


 
ЮЮ ©   (2003-07-08 13:15) [18]

И где здесь проблема, описанная в Subj ?

> т.к. все операции, совершаемые пользователем, должны быть отнесены к заранее (стадия Открытие дня) определенному числу)

а сами операции в базу заносятся? Режим к базе многопользовательский или многопользовательский доступ к объектам?


 
Jeer ©   (2003-07-08 13:23) [19]

Похоже запущено-с..

Ну а если так ?
/*
* TABLE: tbValue
*/

CREATE TABLE tbValue(
ID int NOT NULL,
DateRec datetime NOT NULL,
Value int NULL
)

И, если очень хочется, то сделать итоговую таблицу

/*
* TABLE: tbMonth
*/

CREATE TABLE tbMonth(
ID int NOT NULL,
Month int NOT NULL,
Value int NULL
)

Хотя проще делать выборку за месяц из первой по запросу, но согласен, медленнее.


 
default ©   (2003-07-08 13:26) [20]

причём здесь ООП, объекты(это были и не объекты оказывается...)?


 
Jeer ©   (2003-07-08 14:05) [21]

Вот так всегда с ними..:)


 
Jeer ©   (2003-07-08 14:08) [22]

А, вообще-то, действительно, "подружить" реляцию и ООП на традиционных СУБД непросто..


 
MaXie ©   (2003-07-08 14:11) [23]

> Jeer
Давай ничего не будем создавать, а предположим, что за нас уже все создано!
Возвращаясь к "нашим баранам" - как в приложении определить Число (Год, Месяц, День) и ключ keyMonth?
Есть два поля формы Form1: Число (recData) и ключ keyMonth. Их необходимо определить! Вопрос: возможно ли их определить при помощи двух методов (функций, процедур): prGetData для определения переменной recData, и prGetkeyMonth для определения переменной keyMonth?
Если да, то как должны выглядеть эти два метода? Нужен не код, а алгоритм определения!
Постановка задачи предельно ясно описана в самом первом сообщении этой темы!

P.S. >причём здесь ООП, объекты(это были и не объекты оказывается...)?

Господа откройте любой проект в Delphi! Структура любого Unit"a - описание класса, а после сакраментальное:

var
Form1: TForm1;

Что мы делаем этой строчкой?! Создаем объект?! Правильно, но строка var означает, что мы создаем переменную, потому как в этом же разделе и с таким же успехом мы могли бы записать:

var
Form1: TForm1;
intValue: Integer;

Согласен, что не любая переменая является объектом, но ни кто не сможет утверждать обратное любой объект является переменной!



 
MaXie ©   (2003-07-08 14:15) [24]

Да не осыпят мою бедную голову пеплом спецы Visual C++, но сдается мне, что без множественного наследования здесь не обойтись... :(((


 
Smithson ©   (2003-07-08 14:26) [25]

Ты побредил.
Делаешь два метода. Один определяет ВСЕ (A, B, C, D в твоей терминологии), второй только D (остальное отбрасывает). Тебя волнует быстродействие, излишний код или принципиальная возможность?


 
MaXie ©   (2003-07-08 14:50) [26]

> Smithson
Хороший вопрос! С этого собственно все и начиналось! Как сделать так, чтобы и с ресурсами, и с объемом и с ООП - было все в порядке?!


 
Jeer ©   (2003-07-08 15:15) [27]

Объект LOG

Метод ОТКРЫТИЕ_ДНЯ {
1. Определить текущие день, месяц, год.
2. Вставить запись в tbDay, если нет.
}

Метод ОБНОВЛЕНИЕ {
1. Обновить запись в tbDay }

Метод ЗАКРЫТИЕ {
1. Расчет ключа.
2. Если его нет в tbMonth, то вставить.
3. Обновить запись в tbMoth }


P.S. Не надо отождествлять напрямую таблицы и объекты.


 
default ©   (2003-07-08 19:29) [28]

MaXie © (08.07.03 14:15)
var
Form1: TForm1;
никакого объекта этой строкой не создаётся


 
default ©   (2003-07-08 19:40) [29]

MaXie © (08.07.03 14:15)
объект - это не переменная


 
ЮЮ ©   (2003-07-09 05:03) [30]

Например так. Но я так и не вижу проблем, описанных в Subj

unit Unit1;

interface

type
TDay = class;
TMonth = class;

TAllDays = class
private
FMonths: array of TMonth; // кэш объектов TMonth
protected
function GetDay(AYear, AMonth, ADay: integer): TDay;
end;

TMonth = class
private
FDays: array of TDay; // кэш объектов TDay
Fid: Variant;
FMonth: integer;
FYear: integer;
protected
function GetDay(ADay: integer): TDay;
end;

TDay = class
private
FDay: integer;
Fid: Variant;
FMonth: TMonth;
end;

implementation

{ TAllDays }

function TAllDays.GetDay(AYear, AMonth, ADay: integer): TDay;
var
i: integer;
m: TMonth;
begin
m := nil;
i := 0;
While (m = nil) and (i < High(FMonths)) do
if (FMonths[i].FYear = AYear) and (FMonths[i].FMonth = AMonth) then
m := FMonths[i]
else
inc(i);
if m = nil then begin
m := TMonth.Create;
m.FYear := AYear;
m.FMonth := AMonth;
m.Fid := <запрос из БД>
if VarIsNull(m.Fid) then begin
<создать запись>
m.Fid := <запрос из БД>
end;
end;
Result := m.GetDay(ADay);
end;

{ TMonth }

function TMonth.GetDay(ADay: integer): TDay;
var
i: integer;
begin
Result := nil;
i := 0;
While (Result = nil) and (i < High(FDays)) do
if (FDays[i].FDay = ADay) then Result := FDays[i] else inc(i);
if Result = nil then begin
Result := TDay.Create;
Result.FDay := ADay;
Result.FMonth := self;
Result.Fid := <запрос из БД, используюший Result.FMonth.Fid и Result.FDay>
if VarIsNull(Result.Fid) then begin
<создать запись>
Result.Fid := <запрос из БД>
end;
end;
end;

end.



Страницы: 1 вся ветка

Текущий архив: 2003.07.21;
Скачать: CL | DM;

Наверх




Память: 0.56 MB
Время: 0.02 c
8-67920
Sword-Fish
2003-03-31 17:00
2003.07.21
Ресурсы !!!


14-68050
dimodim
2003-07-04 12:57
2003.07.21
Как установить GlSCENE под 5-й делфи СРОЧНО!


4-68124
cain
2003-05-21 09:54
2003.07.21
мышь над компонентом


4-68110
e!dGe.
2003-05-19 19:26
2003.07.21
Кнопка диалога нажата - как словить?


14-68067
Makhanev A.S.
2003-07-06 01:50
2003.07.21
WinXP...жуть какая-то...