Форум: "Основная";
Текущий архив: 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.53 MB
Время: 0.009 c