Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2003.07.21;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.54 MB
Время: 0.008 c
8-67916
MrN
2003-03-29 19:44
2003.07.21
Open(Close)GL


6-67947
paul_77
2003-05-15 17:51
2003.07.21
передача файла из html на сервер


14-67976
Феликс
2003-07-06 16:17
2003.07.21
Опять пугают


1-67878
Tornado
2003-07-08 09:33
2003.07.21
Форма в DLL


1-67798
jiura1
2003-07-09 13:23
2003.07.21
Как корректно скопировать русский шрифт из Stringgrid в Буфер?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский