private vs protected
попробуй перепиши данный пример с помощью private тогда разговор будт более предметным :
{
public:
Krolik( int x, int y )
{
while ( ... ) if ( krolik_left ) _Nogi.StepLeft();
else if ( krolik_right ) _Nogi.StepRight();
_Chelusti.Zaxvat();
}
protected:
Nogi _Nogi;
Chelusti _Chelusti;
};
class FlyTiger : public Tiger
{
public:
Krolik( int x, int y )
{
try {
while ( ... ) if ( krolik_left ) _WingLeft.Maxnut();
else if ( krolik_right ) _WingRight.Maxnut();
}
catch ( WingMalfunction _WingMalfunction )
{
Tiger::Krolik ( x, y );
}
_Chelusti.Zaxvat();
}
protected:
Wing _WingLeft, _WingRight;
};
p.s. насчет файлового менеджера - последняя текущая строчка в этом проекте была написана прошлым летом - то есть больше года назад. и своим файловым менеджером я пользуюсь до сих пор. а Total Commander - отстой по сравнению с ним полный.
попробуй перепиши данный пример с помощью private тогда разговор будт более предметным :
{
public:
Krolik( int x, int y )
{
while ( ... ) if ( krolik_left ) _Nogi.StepLeft();
else if ( krolik_right ) _Nogi.StepRight();
_Chelusti.Zaxvat();
}
protected:
Nogi _Nogi;
Chelusti _Chelusti;
};
class FlyTiger : public Tiger
{
public:
Krolik( int x, int y )
{
try {
while ( ... ) if ( krolik_left ) _WingLeft.Maxnut();
else if ( krolik_right ) _WingRight.Maxnut();
}
catch ( WingMalfunction _WingMalfunction )
{
Tiger::Krolik ( x, y );
}
_Chelusti.Zaxvat();
}
protected:
Wing _WingLeft, _WingRight;
};
p.s. насчет файлового менеджера - последняя текущая строчка в этом проекте была написана прошлым летом - то есть больше года назад. и своим файловым менеджером я пользуюсь до сих пор. а Total Commander - отстой по сравнению с ним полный.[/QUOTE]
Использовать try/catch для ветвления алгоритма - плохая практика.
Ок, я покажу тебе, как это сделать без protected. Только сначала, объясни мне человеческим языком, что у тебя происходит в коде? Каким образом и почему твой тигр теряет крылья? Что происходит, когда тигр теряет крылья? Если тебе известно понятие UseCase, то составь его.
Кстати, что-то твой тигр часто клацает челюстями... Последствия чумки? :)
Ок, я покажу тебе, как это сделать без protected. Только сначала, объясни мне человеческим языком, что у тебя происходит в коде? Каким образом и почему твой тигр теряет крылья? Что происходит, когда тигр теряет крылья? Если тебе известно понятие UseCase, то составь его.
Кстати, что-то твой тигр часто клацает челюстями... Последствия чумки? :)[/quote]
Я вам так скажу чуваки, чё то диалог гнилой... Если создатель языка C++ предусмотрел наличие protected, значит так требовалось, и в действительности без этой области видимости иногда не обойтись. Да и применять концепцию ООП для описания эволюционного процесса - однозначно неудачная идея, так как не все моменты влезают в ООП
Еще предусмотрены void*, что тоже не очень вписывается в картину ООП. Ну и т.д.
Я не утверждал, что protected вообще не нужен, но его использование оправдано в весьма ограниченном ряде и очень специфичных случаев.
"В частности объявление данных защищенными свидетельствует об ошибках на этапе проектирования" Бьерн Стауструп.
Подобные средства нужны потому, что не всегда есть возможность перепроектировать приложени(создать новую иерархию классов и т.д.) и нужно как-то выходить из положения, дорабатывать существующую.
Т.е. Использование данного механизма нежелательно, но может понадобиться.
[/QUOTE]
пацстулом.
Ок, я покажу тебе, как это сделать без protected. Только сначала, объясни мне человеческим языком, что у тебя происходит в коде? Каким образом и почему твой тигр теряет крылья? Что происходит, когда тигр теряет крылья? Если тебе известно понятие UseCase, то составь его.
Кстати, что-то твой тигр часто клацает челюстями... Последствия чумки? :)[/QUOTE]
логика проста : если крылья не фунционируют в следсвтвии механической поломки ( например если это робот ) или были прострелены врагом ( например если єто в компьтерной игре ) то тигр догоняет кролика на ногах. я про это уже писал в теме private vs public.
а насчет клацанья челюстями - не придирайся к мелочам.
а насчет клацанья челюстями - не придирайся к мелочам.[/QUOTE]
Т.е. иначе говоря, в результате некоторого события происходит переключение статегии (политики) преследования кролика. Так?
[QUOTE=Green]
Использовать try/catch для ветвления алгоритма - плохая практика.
[/QUOTE]
пацстулом.
[/QUOTE]
Исключения следует использовать для исключительных ситуаций.
Т.е. для различных аварийных ситуаций. Аварийных с точки зрения выполнения программы, а не погони тигра за зайцем.
Тормозить можно и ручником, но не думаю, что пользуешься этим способом в штатной ситуации.
Кроме того, исключения - это медленно, это увеличивает размер программы, это усложняет её отладку и приводит к некоторым потенциальным ошибкам, типа memory leak и т.п.
Т.е. для различных аварийных ситуаций. Аварийных с точки зрения выполнения программы, а не погони тигра за зайцем.[/QUOTE]
с точки зрения робота - поломка крыльев - неисправность hardware - так что вполне аварийная ситуация.
[QUOTE=Green]
Кроме того, исключения - это медленно, это увеличивает размер программы, это усложняет её отладку и приводит к некоторым потенциальным ошибкам, типа memory leak и т.п.[/QUOTE]
а также к атакам на башни-близнецы , цунами на обитель разврата и прочему прочему... :D
на самом деле речь идет об эволюции тигров : в мозгу последнего(FlyTiger) хранится две стратегии , причем одна из них включает в себя другую. если потом появится тигр с ногами , крыльями и реактивным двигателем - в том примере который ты собирался написать - придется переписывать базовый класс и добавлять новые события. вообщем приведи код.
[QUOTE=warchangel]с точки зрения робота - поломка крыльев - неисправность hardware - так что вполне аварийная ситуация.
[/QUOTE]
М-да... детсад
Какого робота? Фантастики перечитался?
Ок, продолжу в твоем ключе.
Если изначально не предполагалось, что делать роботу в такой ситуации, то он должен упасть ничком и ждать спасателей.
Если же, твоя супербоевая машина готова к таким переменам, то для неё это часть программы.
Нет ничего хуже роботов, которые в исключениях начинают действовать по незапланнированным программам.
[QUOTE=warchangel]
а также к атакам на башни-близнецы , цунами на обитель разврата и прочему прочему... :D[/QUOTE]
Именно так, если изначально в программе не предполагалось таких ситуаций. Если же это симулятор атак на башни, то это вполне рядовая ситуация, а не исключение.
[QUOTE=warchangel]на самом деле речь идет об эволюции тигров : в мозгу последнего(FlyTiger) хранится две стратегии , причем одна из них включает в себя другую. если потом появится тигр с ногами , крыльями и реактивным двигателем - в том примере который ты собирался написать - придется переписывать базовый класс и добавлять новые события. вообщем приведи код.[/QUOTE]
О... да мы читаем мысли?
В общем, ты сначала определись, что ты хочешь.
Тигр и стратегия - это две сущности, хотя и взаимосвязанные, поэтому и должны существовать отдельно. Ты же лепишь и тигра и его стратегии в одну сущность и гордо называешь это "эволюцией"... хотя именно в таких помойках рождается новая жизнь - баги.
М-да... детсад
Какого робота? Фантастики перечитался?
Ок, продолжу в твоем ключе.
Если изначально не предполагалось, что делать роботу в такой ситуации, то он должен упасть ничком и ждать спасателей.
Если же, твоя супербоевая машина готова к таким переменам, то для неё это часть программы.
Нет ничего хуже роботов, которые в исключениях начинают действовать по незапланнированным программам.
Именно так, если изначально в программе не предполагалось таких ситуаций. Если же это симулятор атак на башни, то это вполне рядовая ситуация, а не исключение.
О... да мы читаем мысли?
В общем, ты сначала определись, что ты хочешь.
Тигр и стратегия - это две сущности, хотя и взаимосвязанные, поэтому и должны существовать отдельно. Ты же лепишь и тигра и его стратегии в одну сущность и гордо называешь это "эволюцией"... хотя именно в таких помойках рождается новая жизнь - баги.[/QUOTE]
вообще-то я занимался разработкой настоящих роботов ... для обследования объекта "укрытие".... это пример конечно несколько академиечский но аналогия почти полная...остальную твою тираду комментировать не буду .... можт приведешь код ? :D
{
public:
virtual void catchRabbit(Position) =0;
};
Здесь есть возражения?
Далее определимся, что есть обобщенный тигр. В моём представлении, это совокупность систем различного назначения: навигационная, визирования, передвижения и т.п.
Судя по твоему примеру кода, нас интересует только система передвижения. Что представляет собой система движения? Это набор органов движения и стратегий их применения. Назначение системы передвижения - переместить объект тигр в некоторую точку в пространстве заданную абсолютными или относительными координатами.
Назначение стратегии передвижения - используя имеющийся набор органов движения выполнить это перемещение.
Определим обобщенный интерфейс стратегий:
{
public:
virtual void moveTo(Position) =0;
};
И так наш тигр представляет собой набор органов движения, захвата и т.п. и стратегий управления этими органами, причем существует некоторая текущая стратегия, используемая в конкретный момент времени и переключаемая по некоторому событию:
{
public:
void catchRabbit(Position pos) {
moveStrategy->moveTo(pos);
jaws.snap();
}
private:
Jaws jaws;
Legs legs;
IMoveStrategy* moveStrategy;
void specifyMoveStrategy();
};
Собственно метод specifyMoveStrategy выбирает нужную стратегию, конструирует её и делает текущей используемой. Это может быть как открытый, так и закрытый метод в зависимости от того, каким образом выбираются стратегии.
Теперь рассмотрим, что есть стратегия для простого тигра.
Конкретная стратегия управляет органами, сл-но она должна иметь доступ (ссылки) на эти органы:
{
public:
RunStrategy(Jaws& jaws, Legs& legs) :jaws(jaws), legs(legs) {}
void moveTo(Position);
private:
Jaws& jaws;
Legs& legs;
};
Надо заметить, что для органов захвата так же может быть множество стратегий, как и самих органов, но в данном примере они выродились в единственный орган - челюсти (Jaws) и единственную стратегию snap.
С обычным тигром закончили, переходим к летающему.
Это сам летающий тигр:
{
public:
void catchRabbit(Position pos) {
moveStrategy->moveTo(pos);
jaws.snap();
}
private:
Jaws jaws;
Legs legs;
Wings wings;
IMoveStrategy* moveStrategy;
void specifyMoveStrategy();
};
Это стратегия использования ног и крыльев в полете:
{
public:
FlyStrategy(Jaws& jaws, Legs& legs, Wings wings)
:jaws(jaws), legs(legs), wings(wings) {}
void moveTo(Position);
private:
Jaws& jaws;
Legs& legs;
Wings& wings;
};
Теперь у нас тигр может использовать как стратегию RunStrategy, так и FlyStrategy. Выбор и конструирование конкретной стратегии производится в методе specifyMoveStrategy в зависимости от определенных условий.
В принципе, теперь мы имеем полноценную, расширяемую систему классов, выполняющих те же действия, что и твоя система, но имеющая и ещё ряд преимуществ (помимо расширяемости), но об этом позднее.
Пока же займемся рефакторингом того, что у нас получилось. Есть некоторое дублирование кода, от которого можно избавиться. Ну для начала можно скомпоновать органы в одну структуру, назовем её "тело". Наверное, это не совсем корректно, но на данном этапе это вполне приемлемо.
И так у нас есть тело обычного тигра и тело летающего тигра:
{
Jaws jaws;
Legs legs;
};
struct FlyTigerBody :TigerBody
{
Wings wings;
};
Вот тебе и эволюция. Действительно, ведь эволюция затрагивает органы, а умения (стратегии) не эволюционируют, они меняются в соответствии с новыми возможностями.
Соответственно поменяются и классы стратегий:
{
public:
typedef TigerBody Body;
RunStrategy(TigerBody& body) :body(body) {}
void moveTo(Position);
private:
Body& body;
};
class FlyStrategy :public IMoveStrategy
{
public:
typedef FlyTigerBody Body;
FlyStrategy(FlyTigerBody& body) :body(body) {}
void moveTo(Position);
private:
Body& body;
};
Для чего нужен typedef будет понятно далее.
Далее мы видим, что классы Tiger и FlyTiger так же содержат дублирующий код и данные. Перенесем их в некоторый базовый класс:
{
public:
void catchRabbit(Position pos) {
moveStrategy->moveTo(pos);
jaws.snap();
}
void setMoveStrategy(IMoveStrategy* strategy) { moveStrategy = strategy; }
private:
IMoveStrategy* moveStrategy;
};
class Tiger :public TigerBase
{
private:
TigerBody body;
void specifyMoveStrategy();
};
class FlyTiger :public TigerBase
{
private:
FlyTigerBody body;
void specifyMoveStrategy();
};
Теперь рассмотрим метод specifyMoveStrategy. По большому счету это стратегия выбора стратегии. Мы можем выделить эту функциональность в отдельный класс-стратегию все с тем же интерфейсом IMoveStrategy:
{
public:
typedef FlyTigerBody Body;
RunFlyStrategy(FlyTigerBody& body) :body(body) {}
void moveTo(Position)
private:
Body& body;
// --- Optional ---
// IMoveStrategy* moveStrategy;
// void specifyMoveStrategy();
};
Будет ли выбираться стратегия в специальном методе или каждый раз определяться при вызове moveTo, зависит от различной постановки задачи. Поэтому я закомментировал и метод выбора стратегии и указатель на её интерфейс. В моей архитектуре они не понадобятся.
Т.о. мы избавились от метода specifyMoveStrategy в классах Tiger и FlyTiger, перенеся функциональность по выбору стратегии в специальный класс RunFlyStrategy. Теперь эти классы отличаются лишь типом тела (body) и задаваемой базовой стратегией. Сл-но мы можем вместо двух этих классов ввести один шаблонный. Кстати, на этом этапе мы можем отказаться от общего интерфейса (IMoveStrategy) у стратегий.
Переделаем базовый класс в шаблонный:
class TigerBase :public ITiger
{
public:
TigerBase() : moveStrategy(body) {}
void catchRabbit(Position pos) {
moveStrategy->moveTo(pos);
body.jaws.snap();
}
private:
Body body;
MoveStrategy moveStrategy;
};
Теперь наши тигры будут определяться таким образом:
typedef TigerBase<FlyTigerBody, RunFlyStrategy> FlyTiger;
Если мы захотим тигра с реактивной тягой, мы должны всего лишь определить ему новое тело и стратегию управления этим телом.
Для приближения системы к естественной, введем обратную связь (ОС). Пусть в органах тела имеется информация об энергетических ресурсах. Другими словами, мы можем получить информацию о том, сколько сил осталось в ногах, крыльях и т.п. На основе этой информации мы можем выбирать как примитивные стратегии, т.е. лететь или бежать, так и определять сложные стратегии – подбегаем, а потом как прыгнем с помощью крыльев. Для осуществления подобного нам надо будет ввести соотв. функциональность в классы органов тела и создать соотв. стратегии. При этом наши старые тигры, не имеющие ОС, будут продолжать себе охотиться на кроликов по-старинке.
Создадим нового тигра с выбором примитивных стратегий:
{
public:
typedef FlyTigerBody Body;
RunFlyPowerFeedbackStrategy(FlyTigerBody& body) :body(body) {}
void moveTo(Position pos) {
// выясняем в каких органах осталось больше сил
if( body.legs.getPowerLevel() > body.wings.getPowerLevel() ) {
RunStrategy(body).moveTo(pos);
} else {
FlyStrategy(body).moveTo(pos);
}
}
private:
Body& body;
};
typedef TigerBase<FlyTigerBody, RunFlyPowerFeedbackStrategy> FlyPowerFeedbackTiger;
Но это ещё не самое интересное.
Как думает летающий тигр, видя кролика? Наверное, он думает: как бы до него быстрее добраться, долететь или добежать? Т.е. он строит прогноз и по нему выбирает стратегию.
Сейчас реализуем такого тигра.
Т.к. только зная механизм, заложенный в стратегию, можно определить скорость достижения результата, то прогноз для конкретной стратегии должен определяться непосредственно в классе этой стратегии. Прогноз может строиться на априорном опыте, моделировании ситуации, расчету по параметрам, полученным непосредственно от органов передвижения, и пр. Сам механизм прогнозирования нас сейчас не интересует.
Вот как будет выглядеть подобная стратегия для нашего летающего тигра:
{
public:
Time getMovmentTime(pos);
};
class FlySpeedFeedbackStrategy :public FlyStrategy
{
public:
Time getMovmentTime(pos);
};
class RunFlySpeedFeedbackStrategy
{
public:
RunFlySpeedFeedbackStrategy(FlyTigerBody& body) :body(body) {}
void moveTo(Position pos) {
RunSpeedFeedbackStrategy runStrategy(body);
FlySpeedFeedbackStrategy flyStrategy(body);
// выясняем как быстрее добраться в заданную точку
if( runStrategy.getMovmentTime(pos) < flyStrategy.getMovmentTime(pos) ) {
runStrategy.moveTo(pos);
} else {
flyStrategy.moveTo(pos);
}
}
private:
FlyTigerBody& body;
};
typedef TigerBase<FlyTigerBody, RunFlySpeedFeedbackStrategy> FlySpeedFeedbackTiger;
Интересно создать механизм прогнозирования на основе моделирования процесса перемещения. Для этого создадим модель тела на основе реального и смоделируем его передвижение в заданную точку с помощью конкретной стратегии:
class TSpeedFeedbackStrategy :public BaseStrategy
{
public:
Time getMovmentTime(Position pos) {
BaseStrategy::Body modelBody(body); // создаем модель тела на основе реального
BaseStrategy modelStrategy(tempBody); // создаем экземпляр стратегии для модели
Time startTime = getTime();
modelStrategy.moveTo(pos) // "гипотетически" перемещаемся
Time endTime = getTime();
return (endTime – startTime);
}
};
typedef TSpeedFeedbackStrategy<RunStrategy> RunSpeedFeedbackStrategy;
typedef TSpeedFeedbackStrategy<FlyStrategy> FlySpeedFeedbackStrategy;
Ясно, что подобный механизм прогнозирования далеко неидеален, но смысл, думаю, понятен.
Кстати, здесь и выявилась необходимость typedef для Body.
Я сведу воедино Framework нашей архитектуры, состоящий из одного интерфейса, одного базового шаблонного класса и одного вспомогательного класса для прогнозирования по скорости:
{
public:
virtual void catchRabbit(Position) =0;
};
template<class Body, class MoveStrategy>
class TigerBase :public ITiger
{
public:
TigerBase() :moveStrategy(body) {}
void catchRabbit(Position pos) {
moveStrategy->moveTo(pos);
body.jaws.snap();
}
private:
Body body;
MoveStrategy moveStrategy;
};
template<class BaseStrategy>
class TSpeedFeedbackStrategy :public BaseStrategy
{
public:
Time getMovmentTime(Position pos) {
BaseStrategy::Body modelBody(body);
BaseStrategy modelStrategy(tempBody);
Time startTime = getTime();
modelStrategy.moveTo(pos)
Time endTime = getTime();
return (endTime – startTime);
}
};
На основе этого простого Framework мы наделали множество разных тигров:
typedef TigerBase<FlyTigerBody, RunFlyStrategy> FlyTiger;
typedef TigerBase<FlyTigerBody, RunFlyPowerFeedbackStrategy> FlyPowerFeedbackTiger;
typedef TigerBase<FlyTigerBody, RunFlySpeedFeedbackStrategy> FlySpeedFeedbackTiger;
Ну как тебе архитектура?
Посмотри, на сколько элементарен и интуитивно понятен каждый класс.
А сколько возможностей для расширения...
P.S. Получилась небольшая статья. В принципе, после обсуждения, внесения корректив и дополнений, можно будет сделать из неё полноценную статейку.
поспорили дьявол с богом кто из них создаст самую лучшую в мире вещь : ну дьявол засучив рукава начал ковать самую прекрасную в мире вещь, а бог просто взял паука и превратил его в сонце, и дьявол был посрамлен...
если не согласен то приведи хоть одно поддающеюся объетивному измерению преимущество твоей "архитектуры" над моим примером...
:))))
а статейку напишу я, о нормальной форме сложной системы описывемой в ООП терминах.
typedef TigerBase<TigerBody, RunFlyStrategy> FlyTiger;
таким образом получаем тигра со стратегией для остуствующих у него органов, в данном случае крыльев.
[/QUOTE]
Ну чтож, значит ты ещё, просто, не дорос до понимания изложенного мной. Если бы ты был серьезным архитектором, проектирующим системы более двух классов, то постарался бы вникнуть и указал бы на преимущества и недостатки моей системы. Ты же лишь проявил свою некомпетентность.
[QUOTE=warchangel]
а теперь сравни то что ты здесь наворотил с моими двумя простыми и понятными классами :)))
[/QUOTE]
А кто тебе сказал, что они просты и понятны?
Я вот другого мнения: они запутанны, неверно съархитектурованы и тащат за собой много лишнего. В них смешано все в одну кучу, поэтому приходится применять protected, try/catch и пр. механизмы не предназначенные для таких систем.
Что я наворотил? Ты вообще, текст прочитал, вникнул, или тебе для спора это не обязательно?
Объясню (для тех кто в танке) ещё раз.
1. Я ввел общий интерфейс для тигров. Это надо было сделать в любой системе,даже такой "идеально", как твоя. Но ты этого не сделал, почему?
2. Я ввел шаблонный класс, который связывает стратегию управления с самими управляемыми элементами. Класс сверх элементарен.
3. Я выделил управляемые элементы в отдельную структуру.
4. Я задал стратегию управления.
В реализации это отразилось в одном определении интерфейса, одном шаблонном классе, двух структурах (одна является наследником другой) и двух классах стратегий. Все структуры и классы элементарны.
[QUOTE=warchangel]
... с точки зрения простоты, наглядности, расширямости, скорости выполнения и объема программы мой пример явно предпочтительнее ...
[/QUOTE]
Голословие... Мой пример предпочтительнее, докажи обратное.
Только учти, что мой пример не аналог твоему, а совершенно иной подход, уровнем повыше.
Расширяемость в твоем примере нулевая, поэтому и понатыкал protected. Расширяемость своей системы я показал на нескольких примерах. Доказывай обратное, реализовав аналогичное своей системой.
Я вот тут захотел тигра с реактивной тягой, на гусенницах, БЕЗ ног, но с крыльями. И чтоб, когда у него заканчивалась горючка он махал крыльями, но только если пархать быстрее, чем ехать на гусенницах. Реализуешь? Поговорим.
Скорость выполнения? :D
Вот ты и ещё раз показал, что ты профан. Ты профайлил код? Ты знаешь скорость его выполнения? На коком тогда основании ты утверждаешь?
Да и о чем ты собственно говоришь? О скорости выполнения ЧЕГО? Какого именно участка.
Ну давай, покажи ещё раз, скажи "всего" или т.п.
Объем программы? О чем ты? О чем конкретно? Где ты видишь превышение объема?
Простота? Где же протота в твоем коде, если там protected, try/catch, вызов методов родительского класса из дочернего и пр.
[QUOTE=warchangel]
если не согласен то приведи хоть одно поддающеюся объетивному измерению преимущество твоей "архитектуры" над моим примером...
[/QUOTE]
Ну а ты способен это сделать?
Твой пример - это первый шаг в попытке структурировать информацию и весьма нелепый шаг.
Интересно, ты слыгал что-нибудь о паттернах проектирования? Сможешь описать свою "систему" в общепринятых терминах?
Я то свою смогу набросать (и сделал это уже неоднократно, только я боюсь ты так и не врубился) ясно и понятно, а ты свою?
Только не надо говорить "смогу", смоги, опиши, заодно и диаграмку для наглядности нарисуй.
[QUOTE=warchangel]
а статейку напишу я, о нормальной форме сложной системы описывемой в ООП терминах.[/QUOTE]
Ага, давай, с удовольствием почитаю. Только вот не уверен, что ты сможешь это сделать. Ну а отговорок найдется масса, а причина одна - мало пока у тебя опыта, а прислушиваться к другому не способен.
[QUOTE=warchangel]
пример ввода системы в некорректное состояние ( признак неудачной архитектуры ) :
typedef TigerBase<TigerBody, RunFlyStrategy> FlyTiger;
таким образом получаем тигра со стратегией для остуствующих у него органов, в данном случае крыльев.
[/QUOTE]
Ну во-первых, код надо писать при участии головного мозга, а не спинного. Я же в твой код для доказательств своей правоты мусор не вводил.
А во-вторых, такое не скомпилируется. Видимо, ты слабо разбираешься в шаблонах. Здесь защита от дурака сработала. :D
Это признак хорошей архитектуры, да? Признаешь?
В моем коде "стратегия" четко сопоставляется с "телом" , только ты этого не заметил... хихикал много.
Короче, разочаровался я в тебе, как в опоненте. Сразу видно было, что архитектор ты ещё не сильный, но думал, хоть что-то сопоставить сможешь, а ты только хихикать, да со своим бестолковым примером носиться.
Интересно, сможешь ответить на то, что в этом посте написано, ну и представить соотв. выкладки (код, диаграмки, в т.ч. код супер-тигра) или опять сольёшь? Что-нибудь объективное скажешь или опять флейм?
1. механизм выбора стратегии на основе уровня енергии в органах.
2. механизм выбора стратегии на основе прогнозирования скорости достижения цели.
...................................
1. механизм выбора стратегии на основе уровня енергии в органах.
понятно следующее : такой механизм имеет смысл только для FlyTiger ( так как только у него есть
выбор между крыльями и ногами ) , поэтому мы имеем возможность зашить эту стратегию прямо в
реализацию метода FlyTiger::Krolik.
{
public:
Krolik( int x, int y )
{
if ( _Nogi.getPowerLevel() > ( _WingLeft.GetPowerLevel() +
_WingRight.GetPowerLevel() )
{
Tiger::Krolik ( x, y );
}
else {
try {
while ( ... ) if ( krolik_left ) _WingLeft.Maxnut();
else if ( krolik_right ) _WingRight.Maxnut();
_Chelusti.Zaxvat();
}
catch ( WingMalfunction _WingMalfunction )
{
Tiger::Krolik ( x, y );
}
}
}
protected:
Wing _WingLeft, _WingRight;
};
2. механизм выбора стратегии на основе прогнозирования скорости достижения цели.
здесь имеем аналогичную ситуацию, только FlyTiger есть из чего выбирать. поступаем аналогично:
{
public:
Krolik( int x, int y )
{
// прогнозирование на основе моделирования
FlyTiger* _TempFlyTiger = new FlyTiger();
Time _start = GetTime();
_TempFlyTiger->Tiger::Krolik ( x, y );
Time _end = GetTime();
delete _TempFlyTiger();
Time tiger_time = _end - _Start;
//
_start = GetTime();
goto_krolik_on_wings( x, y );
_end = GetTime();
Time flytiger_time = _end - _start;
//
if ( tiger_time < flytiger_time )
{
Tiger::Krolik( x, y );
}
else {
try {
goto_krolik_on_wings( x, y );
}
catch ( WingMalfunction _WingMalfunction )
{
Tiger::Krolik ( x, y );
}
}
}
protected:
goto_krolik_on_wings( x, y )
{
while ( ... ) if ( krolik_left ) _WingLeft.Maxnut();
else if ( krolik_right ) _WingRight.Maxnut();
_Chelusti.Zaxvat();
}
Wing _WingLeft, _WingRight;
};
изучая вышеприведенный код напрашивается следующее решение : выделить стратегии в отдельные классы
с возможностью динамической замены. ок, хотя на данном этапе возможность выбора есть только у
FlyTiger, добавим механизм выбора стратегии и для Tiger, например он может бежать к кролику
галопом, а может и тихо подкрадываться. с точки зрения пользователя нужно оставить неизменным
интерфейс Krolik( x, y ); таким образом рефакторим:
{
public:
Krolik( x, y )
{
MoveToKrolik_Strategy* _MoveToKrolik_Strategy =
_Std_SelectStrategy->GetStrategy();
_MoveToKrolik_Strategy->Fas( x, y );
}
protected:
class SelectStrategy_Strategy
{
public:
MoveToKrolik_Strategy* GetStrategy();
};
class Std_SelectStrategy : public SelectStrategy_Strategy
{
public:
MoveToKrolik_Strategy* GetStrategy()
{
return new Galop_Strategy();
}
};
class MoveToKrolik_Strategy
{
public:
Fas( x, y ) = 0;
Time GetMovment( x,y ) = 0;
};
class Galop_Strategy : public MoveToKrolik_Strategy
{
public:
Galop_Strategy( Nogi&, Chelusti&) ; // этот момент мне не сильно нравится
// но алтернативы я пока не вижу. дружественные классы считаются плохим стилем.
Fas( x, y )
{
while ( ... ) if ( krolik_left ) _Nogi.StepLeft();
else if ( krolik_right ) _Nogi.StepRight();
_Chelusti.Zaxvat();
}
Time GetMovment()
{
const int step = 5;
return get_distance( curr_pos, target_pos ) * step;
}
};
Std_SelectStrategy* _Std_SelectStrategy;
Nogi _Nogi;
Chelusti _Chelusti;
};
class FlyTiger: public Tiger
{
public:
Krolik( x, y )
{
MoveToKrolik_Strategy* _MoveToKrolik_Strategy =
_Std_SelectStrategy->GetStrategy();
_MoveToKrolik_Strategy->Fas( x, y );
}
protected:
class ByEnergy_SelectStrategy : public Tiger::SelectStrategy_Strategy
{
public:
};
class BySpeed_SelectStrategy : public Tiger::SelectStrategy_Strategy
{
};
class Fly_Strategy : public Tiger::MoveToKrolik_Strategy
{
public:
Fas( x,y )
{
try {
while ( ... ) if ( krolik_left ) _WingLeft.Maxnut();
else if ( krolik_right ) _WingRight.Maxnut();
_Chelusti.Zaxvat();
}
catch ( WingMalfunction _WingMalfunction )
{
Galop_Strategy::Fas( x, y ); // наверно имеет смысл сделать
методы стратегий статическими.
}
}
Time GetMovment()
{
...
}
};
Wing _WingLeft, _WingRight;
};
таким образом в данной иерархии у нас отсуствует как миниум один недостаток твоей архитектуры :
возможность назначения не имеющей смысла для данного класса стратегии. кроме того - имно
использлвание protected позволяет легко и просто убрать дублирование кода, а также достаточно
изщно реализовать всю систему. так что Страуструп тоже наверно не всегда прав.
ах .... ну да конечно... для решения элементарной задачи ты ввел кучу классов , структур, интерфейсов в которых и черт ногу сломит и которые нужны там как зайцу пятая, шестая и седьмая нога соответсвенно... если ты считаешь что главный показатель качества системы это кол-во классов в ней то тут как говорится без комментариев...
[QUOTE=Green]
то постарался бы вникнуть и указал бы на преимущества и недостатки моей системы. Ты же лишь проявил свою некомпетентность.
А кто тебе сказал, что они просты и понятны?
Я вот другого мнения: они запутанны, неверно съархитектурованы и тащат за собой много лишнего. В них смешано все в одну кучу, поэтому приходится применять protected, try/catch и пр. механизмы не предназначенные для таких систем.,[/QUOTE]
[QUOTE=Green]
Что я наворотил? Ты вообще, текст прочитал, вникнул, или тебе для спора это не обязательно?
Объясню (для тех кто в танке) ещё раз.
1. Я ввел общий интерфейс для тигров. Это надо было сделать в любой системе,даже такой "идеально", как твоя. Но ты этого не сделал, почему?
2. Я ввел шаблонный класс, который связывает стратегию управления с самими управляемыми элементами. Класс сверх элементарен.
3. Я выделил управляемые элементы в отдельную структуру.
4. Я задал стратегию управления.
В реализации это отразилось в одном определении интерфейса, одном шаблонном классе, двух структурах (одна является наследником другой) и двух классах стратегий. Все структуры и классы элементарны.
Голословие... Мой пример предпочтительнее, докажи обратное.
Только учти, что мой пример не аналог твоему, а совершенно иной подход, уровнем повыше.[/quote]
здеся идет голословие для непосвященных.... а также тут ты фактически расписался в том что не можешь объкетивно обосновать преимущестово своей системы над моей... мне кажется очевидным что система состоящая из двух классов и двух виртуальных методов будет занимать меньше места и выполняться быстрее чем в случае твоего нелепого нагромаждения классов, шаблонов, методов....
[QUOTE=Green]
Расширяемость в твоем примере нулевая, поэтому и понатыкал protected. Расширяемость своей системы я показал на нескольких примерах. Доказывай обратное, реализовав аналогичное своей системой.
Я вот тут захотел тигра с реактивной тягой, на гусенницах, БЕЗ ног, но с крыльями. И чтоб, когда у него заканчивалась горючка он махал крыльями, но только если пархать быстрее, чем ехать на гусенницах. Реализуешь? Поговорим.
Скорость выполнения? :D
Вот ты и ещё раз показал, что ты профан. Ты профайлил код? Ты знаешь скорость его выполнения? На коком тогда основании ты утверждаешь?
Да и о чем ты собственно говоришь? О скорости выполнения ЧЕГО? Какого именно участка.
Ну давай, покажи ещё раз, скажи "всего" или т.п.
Объем программы? О чем ты? О чем конкретно? Где ты видишь превышение объема?
Простота? Где же протота в твоем коде, если там protected, try/catch, вызов методов родительского класса из дочернего и пр.
Ну а ты способен это сделать?
Твой пример - это первый шаг в попытке структурировать информацию и весьма нелепый шаг.
Интересно, ты слыгал что-нибудь о паттернах проектирования? Сможешь описать свою "систему" в общепринятых терминах?
Я то свою смогу набросать (и сделал это уже неоднократно, только я боюсь ты так и не врубился) ясно и понятно, а ты свою?
Только не надо говорить "смогу", смоги, опиши, заодно и диаграмку для наглядности нарисуй.
Ага, давай, с удовольствием почитаю. Только вот не уверен, что ты сможешь это сделать. Ну а отговорок найдется масса, а причина одна - мало пока у тебя опыта, а прислушиваться к другому не способен.
Ну во-первых, код надо писать при участии головного мозга, а не спинного. Я же в твой код для доказательств своей правоты мусор не вводил.
А во-вторых, такое не скомпилируется. Видимо, ты слабо разбираешься в шаблонах. Здесь защита от дурака сработала. :D
Это признак хорошей архитектуры, да? Признаешь?
В моем коде "стратегия" четко сопоставляется с "телом" , только ты этого не заметил... хихикал много.
[/QUOTE]
дык .... твой код так отвратительно и бессистемно написан что я этого не заметил... так что скорее минус тебе чем мне.
[QUOTE=Green]
Короче, разочаровался я в тебе, как в опоненте. Сразу видно было, что архитектор ты ещё не сильный, но думал, хоть что-то сопоставить сможешь, а ты только хихикать, да со своим бестолковым примером носиться.
Интересно, сможешь ответить на то, что в этом посте написано, ну и представить соотв. выкладки (код, диаграмки, в т.ч. код супер-тигра) или опять сольёшь? Что-нибудь объективное скажешь или опять флейм?[/QUOTE]
по моему дураку понятно что первый мой пример будет заниматься меньше места и быстрее выполняться - по одной причине - он меньше в размерах. а теперь посмотри на мой второй пример : по моему он на голову выше твоего со всех точек зрения.
P.S. на тему опыта в проектировании несколько лет назад я в одиночку спроектировал систему из более чем 150 классов. и все отлично фунциклровало.
по моему дураку понятно что первый мой пример будет заниматься меньше места и быстрее выполняться - по одной причине - он меньше в размерах.
Тут блин вобще нет слов - повеселил. Сам то понял, что сказал?=) И все время пытаешься рассуждать о вещах которые даже не понимаешь.
Да еще и строит из себя великого архитектора проектировщиака ))) А у самого до сих пор в коде:
Krolik
MoveToKrolik
Maxnut
Zaxvat
Да за один только такой нэйминг тебя засмеют в любой нормальной конторе =) Кстати он тоже показывает твой профессиональный уровень, как и остальной бред.
А по поводу 150 классов. У нас вон валяется проект из ~1000 классов, парой лоботрясов когда то разработанный. Тоже функционирует и не падает. Только неправильно =)
Тут блин вобще нет слов - повеселил. Сам то понял, что сказал?=) И все время пытаешься рассуждать о вещах которые даже не понимаешь.
Да еще и строит из себя великого архитектора проектировщиака ))) А у самого до сих пор в коде:
Да за один только такой нэйминг тебя засмеют в любой нормальной конторе =) Кстати он тоже показывает твой профессиональный уровень, как и остальной бред.
А по поводу 150 классов. У нас вон валяется проект из ~1000 классов, парой лоботрясов когда то разработанный. Тоже функционирует и не падает. Только неправильно =)[/QUOTE]
товарисч... вообще то здесь идет обсуждение темы а не моей личности... вы тут все поголовно постоянно переходите на обсуждение моей личности... видно по теме вам сказать нечего... а я занимался разработкой таких программных систем которые ламеру вроде тебя только по ночам наверно снятся... я консультировал людей в области ПО для разработки бортовых систем которые устанавлтиваются на украинские ракетоносители ( 100$ за час )... чуствуешь разницу между тобой и мной ?
на тему идентификаторов : что ты имеешь против русского языка ? можт ты фашист ? или жидок ?:D тут один такой уже был : uki его звали... тож много и упорно кричал какой я ну очень плохой программист ... а как до дела дошло облажался по полной программе... с тех пор его не видно... застрелился наверное.... теперь его в аду черти заставляют азы программирования учить.... :D
а я занимался разработкой таких программных систем которые ламеру вроде тебя только по ночам наверно снятся... я консультировал людей в области ПО для разработки бортовых систем которые устанавлтиваются на украинские ракетоносители
Блин, у нас уже над тобой вся контора ржет =)) Разработку ПО для ракетоносителей =)) Наверно потому и не летают? =)
чуствуешь разницу между тобой и мной ?
Ага чувствую - разница в том, что когда мне доводилось попреподовать - у таких как ты студентов я просто не принимал задания, пока они не научатся делать что то нормально. Если словами не понимают. =)
на тему идентификаторов : что ты имеешь против русского языка ? можт ты фашист ? или жидок ?
Никогда не думал, что человек хотя бы начинающий в этой професси может так тупить. =))
Если тебе нравится русский - исспользуй русский язык. То что ты исспользуешь - это не русский язык. Это то что исспользуют школьники двоешники по причине неопытности или лени.
Особенно шедевр русского языка: MoveToKrolik
=))
Извиняюсь, если когото еще обидел. Как бы тему не закрыли - посмеятся охото еще.
1) ты стал пользоваться термином "стратегия";
2) ты выделил стратегии в оидельный класс, т.е. принял, что управляемые органы и стратегии их управления - это разные сущности и мешать их в один класс не стоит;
3) ты стал пользоваться понятием "механизм переключения стратегий";
4) ты модернизируешь код в соотв. с поступлением новых задач. Видимо, ты уже не считаешь модернизацию кода признаком плохой архитектуры.
Теперь о недостатках. Как я и предполагал, ты "слил" задачу.
Ты совершенно не справился с задачей. Я же говорил о тигре БЕЗ НОГ, но с крыльями и ракетными двигателями.
В принципе на этом можно было бы и закончить, но я продолжу рассмотрение того, что ты понаписал.
1. Почему ты ломаешь существующих тигров? Надо, чтобы старые тигры оставались!
2. Ты целенаправлено не пишешь virtual? Тогда не понятно, где именно у тебя виртуальные классы, а где нет, и получается полная охинея.
3. Для чего нужен класс SelectStrategy_Strategy? Он нигде не применяется (наследование не в счет, т.к. оно в данном случае бессмыслено).
4. У тебя НЕТ механизма выбора стратегии.
5. Ты вообще, не смог применить стратегии, хотя и ввел их. Где, к примеру используется BySpeed_SelectStrategy ?
6. Кстати, а как ты связываешь органы со стратегиями? Что-то в коде это не отражено.
7. Ты каждый раз будешь расширять класс Tiger, когда будет возникать необходимость в новом виде шага? Алюр, нацыпочках, иноходь и т.п. ? :D
8. Метод goto_krolik_on_wings изначально предполагает возможность исключения, которое ты обрабатываешь в try/catch. Однако, при прогнозировании исключение не обрабатывается, сл-но прогнозирование становится опасным. :)
9. При прогнозировании ты создаешь нового свеженького тигра, который не имеет ничего общего с состоянием усталости реального тигра.
10. А если при неудачном использовании крыльев я хочу не галоп?
Твоя система в её теперешнем состоянии является карикатурной копией моей изначальной системы.
Для наглядности я убрал реализацию и оставил только интерфейсы (внешние и внутренние).
Сравни мою систему
{
public:
virtual void catchRabbit(Position) =0;
};
class IMoveStrategy
{
public:
virtual void moveTo(Position) =0;
};
class Tiger :public ITiger
{
public:
void catchRabbit(Position pos);
private:
void specifyMoveStrategy();
};
class RunStrategy :public IMoveStrategy
{
public:
void moveTo(Position);
};
class FlyTiger :public ITiger
{
public:
void catchRabbit(Position pos);
private:
void specifyMoveStrategy();
};
class FlyStrategy :public IMoveStrategy
{
public:
void moveTo(Position);
};
class RunFlyStrategy :public IMoveStrategy
{
public:
void moveTo(Position)
};
со своей
{
public:
Krolik( x, y );
protected:
class SelectStrategy_Strategy
{
public:
MoveToKrolik_Strategy* GetStrategy();
};
class Std_SelectStrategy : public SelectStrategy_Strategy
{
public:
MoveToKrolik_Strategy* GetStrategy();
};
class MoveToKrolik_Strategy
{
public:
Fas( x, y ) = 0;
Time GetMovment( x,y ) = 0;
};
class Galop_Strategy : public MoveToKrolik_Strategy
{
public:
Fas( x, y );
Time GetMovment();
};
};
class FlyTiger: public Tiger
{
public:
Krolik( x, y );
protected:
class ByEnergy_SelectStrategy : public Tiger::SelectStrategy_Strategy
{
public:
};
class BySpeed_SelectStrategy : public Tiger::SelectStrategy_Strategy
{
};
class Fly_Strategy : public Tiger::MoveToKrolik_Strategy
{
public:
Fas( x,y );
Time GetMovment();
};
};
Ну и что структурированнее и проще?
Я жду реализацию нового тигра на гусеницах с крыльями и ракетными двигателями, так же хочется увидеть старых тигров в нормальном рабочем состоянии, которые уживаются с новым тигром.
по моему дураку понятно что первый мой пример будет заниматься меньше места и быстрее выполняться - по одной причине - он меньше в размерах.
[/QUOTE]
Ну может дураку, и понятно, а вот мне нет.
[QUOTE=warchangel]P.S. на тему опыта в проектировании несколько лет назад я в одиночку спроектировал систему из более чем 150 классов. и все отлично фунциклровало.[/QUOTE]
Настораживает "функционировало" в прошедшем времени. Что потом? Разломал, как своих тигров в предыдущем посте?
[QUOTE=warchangel]
я консультировал людей в области ПО для разработки бортовых систем которые устанавлтиваются на украинские ракетоносители ( 100$ за час )...
[/QUOTE]
Моя специализация - "Системы управления КА, РН и наземные проверочно-пусковые комплексы". Так что не надо песен про бортовые системы РН, я знаю, как они устроены. НИЧЕГО сложного в их ПО нет. :)
[QUOTE=aks]
Разработку ПО для ракетоносителей =)) Наверно потому и не летают? =)
[/QUOTE]
Такие крупные разработки - дело огромного числа людей в течении долгих лет. Так что даже если "наш друг" принимал там участие, то его вклад на столько мизерный, что это не отразилось на летных характеристиках РН. А они летают очень даже не плохо, в частности из-за того, что ПО там весьма примитивно.
Кроме того, он же только "консультировал"... :)
2aks : судя по всему ты пишешь свои посты из конторы под названием "психбольница, палата для даунов".
и вообще низкий программный уровень греена, полное отсутствие такового у aks, низкий уровень дисскусии, а также постоянный переход на лчиности у вышеупомянутых [beep] , полное остуствие конструктивных и интересных предложений , нечленораздельный бред про том что его пример лучше - все єто убеждает меня прекратить обсужедние данного вопроса на форуме, а также полностью убеждает меня в том что этот форум - прибежище самовлюбленных личностей из вышеупомянутой палаты. все тема закрыта.[/QUOTE]
Однако, именно ты сейчас перевел тему на обсуждение личностей.
Я жду реализацию нового тигра на гусеницах с крыльями и ракетными двигателями, так же хочется увидеть старых тигров в нормальном рабочем состоянии, которые уживаются с новым тигром.
А так же внятные ответы на мои замечания по твоей последней реализации.
Или тебе уже нечего сказать по теме? По этому ты считаешь её закрытой?
<skip>
[/QUOTE]
Не стоит повторяться, тем более неся откровенный бред.
Это сообщение, как и другие (до уже этого перенесенные) не относящиеся к данной теме, а только к обсуждению личностей, перенесены в соотв. темы:
http://forum.codenet.ru/showthread.php?t=29486
http://forum.codenet.ru/showthread.php?t=29843
Я жду реализацию нового тигра на гусеницах с крыльями и ракетными двигателями, так же хочется увидеть старых тигров в нормальном рабочем состоянии, которые уживаются с новым тигром.
А так же внятные ответы на мои замечания по твоей последней реализации.
[/QUOTE]
Это сообщение, как и другие не относящиеся к данной теме, а только к обсуждению личностей, перенесены в соотв. темы:
http://forum.codenet.ru/showthread.php?t=29486
http://forum.codenet.ru/showthread.php?t=29843
Для тех, кто в танке:
Сообщения не относящиеся к обсуждаемой теме будут отсюда удалены. Пока складывается нехорошее впечатление, что тебе просто нечего сказать по теме.
Я жду реализацию нового тигра на гусеницах с крыльями и ракетными двигателями, так же хочется увидеть старых тигров в нормальном рабочем состоянии, которые уживаются с новым тигром.
А так же внятные ответы на мои замечания по твоей последней реализации.