Re[4]: Кстати об ООП дизайне
От: Ведмедь Россия  
Дата: 09.12.03 15:18
Оценка:
Здравствуйте, George Seryakov, Вы писали:

GS>Здравствуйте, Hacker_Delphi, Вы писали:


LVV>>>Ты лучше скажи что за книжка и где ее взять.

H_D>>Павел Шумилов (Павел Шумил) "Пойди поймай свою звезду".

GS>Виндж (рекомендую) тоже по программситам-археологам проходится.


А ссылочку можно?
Да пребудет с тобой Великий Джа
Re[5]: Кстати об ООП дизайне
От: George Seryakov Россия  
Дата: 09.12.03 15:32
Оценка:
Здравствуйте, Ведмедь, Вы писали:

GS>>Виндж (рекомендую) тоже по программситам-археологам проходится.


В>А ссылочку можно?


http://lib.ru/INOFANT/WINDZH/

Программисты-археологи — это из http://lib.ru/INOFANT/WINDZH/deepness.txt. Но читать советовал бы все подряд.
GS
Re: Кстати об ООП дизайне
От: Воронков Василий Россия  
Дата: 09.12.03 18:14
Оценка:
Здравствуйте, Hacker_Delphi, Вы писали:

H_D>Вот отрывок из книши одного очень хорошего писателя:

H_D>
H_D>      - Долгая история. Все дело в том, что местные программисты пошли
H_D>по неверному пути. Этот путь называется объектно ориентированный подход
H_D>в программировании. На самом деле это мина с часовым механизмом в
H_D>красивой упаковке. В очень красивой упаковке. Как с этим бороться, я
H_D>не знаю. Упустил момент.
H_D>      - Мастер, ближе к делу.
H_D>      - Знаешь анекдот, как программист кипятит чайник. Дано: пустой
H_D>чайник, кран, спички, газовая плита. Программа действий: наполнить
H_D>чайник водой из-под крана, поставить на плиту, зажечь газ. Ждать, пока
H_D>закипит чайник. Эта программа оформляется как объект. Второй случай.
H_D>Все то же самое, но чайник с водой уже стоит на плите. Действия
H_D>программиста: вылить воду из чайника и выполнить предыдущий объект.
H_D>      - Грустно. А нырнуть внутрь объекта нельзя? Туда, где надо газ
H_D>зажечь?
H_D>      - Нельзя. Можно добавить новое свойство или действие. В нашем случае
H_D>- воду вылить. Будет новый объект. Но внутрь влезть нельзя. Объект дается
H_D>как единое целое. Никто не знает, что там внутри. Все давно забыли, откуда
H_D>ноги растут. В результате получается колоссальное дублирование кода и данных
H_D>и огромная потеря производительности компьютера. С каждым годом компьютеры
H_D>требуют все больше памяти, а работают все медленнее.
H_D>


Налицо неумелое проектирование. _Чайник_ должен быть представлен как отдельный объект, _Вода_ также как отдельный объект. _Чайник_с_водой_ представляет собой объект, отнаследованный от объектов _Чайник_ и _Вода_. Соответственно, имеем:

функция _Главная_
{
    _Чайник_ экземпляр как _Чайник_с_водой_
    _Устройство_для_кипячения_::_Кипятить_(экземпляр) 
}


_Устройство_для_кипячения
{
    функция _Кипятить_(_Чайник_ экземпляр)
    {
        если (экземпляр есть _Чайник_с_водой_)
            кипятить
        другое
            пошел взад
    }
}



Во втором случае просто сокращаем функцию _Главная_ на одну строчку.
... << RSDN@Home 1.1.2 beta 1 >>
Re: Кстати об ООП дизайне
От: krpav  
Дата: 10.12.03 01:35
Оценка:
Здравствуйте, Hacker_Delphi, Вы писали:

H_D>Вот отрывок из книши одного очень хорошего писателя:

H_D>
H_D>      - Долгая история. Все дело в том, что местные программисты пошли
H_D>по неверному пути. Этот путь называется объектно ориентированный подход
H_D>в программировании. На самом деле это мина с часовым механизмом в
H_D>красивой упаковке. В очень красивой упаковке. Как с этим бороться, я
H_D>не знаю. Упустил момент.
H_D>      - Мастер, ближе к делу.
H_D>      - Знаешь анекдот, как программист кипятит чайник. Дано: пустой
H_D>чайник, кран, спички, газовая плита. Программа действий: наполнить
H_D>чайник водой из-под крана, поставить на плиту, зажечь газ. Ждать, пока
H_D>закипит чайник. Эта программа оформляется как объект. Второй случай.
H_D>Все то же самое, но чайник с водой уже стоит на плите. Действия
H_D>программиста: вылить воду из чайника и выполнить предыдущий объект.
H_D>      - Грустно. А нырнуть внутрь объекта нельзя? Туда, где надо газ
H_D>зажечь?
H_D>      - Нельзя. Можно добавить новое свойство или действие. В нашем случае
H_D>- воду вылить. Будет новый объект. Но внутрь влезть нельзя. Объект дается
H_D>как единое целое. Никто не знает, что там внутри. Все давно забыли, откуда
H_D>ноги растут. В результате получается колоссальное дублирование кода и данных
H_D>и огромная потеря производительности компьютера. С каждым годом компьютеры
H_D>требуют все больше памяти, а работают все медленнее.
H_D>

H_D>Которая лишь подтверждает мысль, что ООП везде — это вред и блед, хотя и не отрицает что в бизнес приложениях ООП — это просто круто

итого получаем класс

class КЧайник
{
public:
КЧайник() { ... Вскипятить();};
~КЧайник();
void НалитьЧашкуКипятка(ККружка &);
protected:
void Вскипятить();
private:
....
};


Супер!!! Учится отправлять надо людей, которые говорят, что знают, что такое ООП и такое проектируют.
Re[2]: Кстати об ООП дизайне
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 10.12.03 08:48
Оценка: 40 (2) :))) :))) :))
Здравствуйте, Воронков Василий, Вы писали:

ВВ>Налицо неумелое проектирование. _Чайник_ должен быть представлен как отдельный объект, _Вода_ также как отдельный объект. _Чайник_с_водой_ представляет собой объект, отнаследованный от объектов _Чайник_ и _Вода_.


С чего это отнаследованный? Самая типичная агрегация.
public abstract class Content
{
    public vitual double Weight
    {get;}
    
    public vitual double Volume
    {get;}
}

public abstract class LiquidContent : Content
{
    public vitual double BoilTemperature
    {get;}
    
    public bool IsBoiled
    {
        get
        {
            return _temperature >= DoilTemperature;
        }
    }
}

public class WaterContent
{
    public WaterContent(double count) {...}

    public override double BoilTemperature
    {
        get { return 100f; }
    }
}

public interface IContentProvider
{
    Content GetContent(double count);
}

public class Tap : IContentProvider
{
    WaterContent GetWater(double count)
    {
        try
        {
            _waterPipe.QueryWater(count);
        catch (WaterAbortedBySomebodyException)
        {
            throw new NoWaterInTapException("Воду выпили жиды");
        }
    }

    Content IContentProvider.GetContent(double count)
    {
        return GetWater(count);
    }
}

public interface IContentContainer
{
    double ContentRoom
    {get;}
    
    void PutContent(LiquidContent content);
}

public class Teapot : IContentContainer
{
    public double ContentRoom {...}
    
    public void PutContent(LiquidContent content)
    {
        if (content.Volume > (ContentRoom - _alreadyContained))
            throw new OverflowException();
        _alreadyContained += content.Volume;
    }
}

public interface IFireable
{
    bool IsFired
    {get;}

    void Fire(FireSource source);
}

public abstract class FireSourceProvider
{
    public abstract FireSource CreateFireSource();
}

public abstract class FireSource : IFireable
{
    protected abstract IsFired
    {get;}
    
    public abstract void Fire(FireSource source);
    
    public bool DoFire(IFireable what)
    {
        while (!what.IsFired)
        {
            what.Fire(this);
            if (IsFired)
                return false;
        }
        return true;
    }
}

public class Match : FireSource
{
    public override bool IsFired
    {
        get { return _isFired; }
    }
    
    public override void Fire() {...}
}

public class MatchBox : FireSourceProvider
{
    public override FireSource CreateFireSource()
    {
        if (_matchCount = 0)
            throw new NotEnoughMatchesException();
        _matchCount--;
        return new Match();
    }
}

public class Stove : IFireable
{
    public bool IsFired
    {
        get { return _isFired; }
    }
    
    public void Fire()
    {
        ...
        _isFired = true;
    }
    
    public void PutOn(object what)
    {
        ...
    }
}


А теперь собственно требуемый код:
const double overflowPreventVolume = 0.05f;
Teapot teapot = Home.Instance.Kitchen.PlatesAndDishesShelf.Extract("Teapot #1");
double requiredContentCount = teapot.ContentRoom - teapot.Content.Volume - overflowPreventVolume;
if (requiredContentCount > 0)
    teapot.PutContent(Home.Instance.Kitchen.Tap.GetContent(requiredContentCount));
MatchBox matchBox = Home.Instance.Kitchen.SmallShelf.Extract("MatchBox");
Stove stove = Home.Instance.Kitchen.Stove;
while (!stove.IsFired)
{
    int atemptCount = 0;
    const totalAtempts = 10;
    FireSource match = matchBox.CreateFireSource();
    while (!match.IsFired)
    {
        match.Fire(null);
        atemtpCount++;
        if (atemptCount > totalAtempts)
            throw new ArgumentException("Черт побери, какого фига спички мокрые!");
    }
    match.DoFire(stove);
}
stove.PutOn(teapot);
const int checkInterval = 30000;
while (!teapot.Content.IsBoiled)
    System.Threading.Sleep(checkInterval);


Так что нефиг свою криворукость списывать на недостатки ООП.
... << RSDN@Home 1.1.2 beta 2 >>
AVK Blog
Re: Кстати об ООП дизайне
От: _Obelisk_ Россия http://www.ibm.com
Дата: 10.12.03 08:54
Оценка: 27 (1) :)
Здравствуйте, Hacker_Delphi, Вы писали:

Это пример криво спроектированного чайника, который инкапсулирован с газовой плитой и водопроводным краном . Поддерживает сия штука лишь методы "ВылитьВоду", "НалитьВодуПоставитьНаПлитуВключитьГаз". Брр....
Такие "мины с часовым механизмом" закладываются не технологией, а архитектором.



Душа обязана трудиться! (с) Н.Заболоцкий.
Re[2]: Кстати об ООП дизайне
От: Ведмедь Россия  
Дата: 10.12.03 09:00
Оценка: 29 (2)
Здравствуйте, _Obelisk_, Вы писали:

_O_>Здравствуйте, Hacker_Delphi, Вы писали:


_O_>Это пример криво спроектированного чайника, который инкапсулирован с газовой плитой и водопроводным краном . Поддерживает сия штука лишь методы "ВылитьВоду", "НалитьВодуПоставитьНаПлитуВключитьГаз". Брр....

_O_>Такие "мины с часовым механизмом" закладываются не технологией, а архитектором.

Ну почему надо цепляться за конкретный пример и говорить, что пример неправильный, поэтому автор не прав?
Понятно, что приведенный пример высосан из пальца. Но проблема выделена по моему достаточно ясно : Невозможность(трудоемкость или неудоно) изменить логику работы обьекта, когда он уже спроектирован и написан. И это проблемы ООП, а не архитектора. Архитекор в рамках ООП ДЛЯ ДАННОЙ ЗАДАЧИ может ъхорошо спроектировать обьект. Когда задача измениться, часто приходится делать новый класс обьектов.
Да пребудет с тобой Великий Джа
Re[2]: Кстати об ООП дизайне
От: Sinclair Россия https://github.com/evilguest/
Дата: 10.12.03 09:07
Оценка: :)
Здравствуйте, _Obelisk_, Вы писали:

_O_>Такие "мины с часовым механизмом" закладываются не технологией, а архитектором.

Ага.
type TMainObject = class
private
...
public
  procedure DoEverything; virtual; // override this if you need to do something else
end;
... << RSDN@Home 1.1.0 stable >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re: Кстати об ООП дизайне
От: akasoft Россия  
Дата: 10.12.03 09:12
Оценка: 18 (2)
Здравствуйте, Hacker_Delphi, Вы писали:

H_D>Которая лишь подтверждает мысль, что ООП везде — это вред и блед, хотя и не отрицает что в бизнес приложениях ООП — это просто круто


Не-ет, сякундочку...

Ничего я в этом отрывке подтверждающего не нашёл, одни словоизвороты. Никак смысла не пойму, может объяснит кто?

Там две задачи приведены. Посмотрим на первую задачу. Цитировать её не буду. Сразу напишу

type
    Чайник = class()
    private
        procedure НалитьВоды();
        procedure ПоставитьНаПлиту()
        procedure ЗажечьГаз();
        function ЖдатьКогдаЗакипит(): Boolean;
    public
        procedure Кипятить();
    end;
    
procedure Чайник.Кипятить();
begin
    НалитьВоды();
    ПоставитьНаПлиту()
    ЗажечьГаз();
    repeat
    until ЖдатьКогдаЗакипит();
end;


В начале нигде не сказано, что условия задачи могут меняться. А потом их взяли, да изменили. И пытаются показать, что раз мы не можем плюхнуться в середину метода Кипятить(), значит это глупо. А менять постановку задачи, значит, правильно, потому как из жизни.

Никто же не мешает модифицировать класс Чайник. Например, сделать метод Кипятить() виртуальным, и заменить его в потомке. А приватные методы сделать protected, раз уж нужно управляемое поведение.

Никто не мешает завести состояние класса чайник. "Вода есть?". "На плите?" "Газ зажжён?" Ждём, когда закипит?" "Чайник закипел?"

В чём фишка-то? В игре слов? Или в проектировании?
... << RSDN@Home 1.1.2 beta 2 >>
Re[2]: Кстати об ООП дизайне
От: Hacker_Delphi Россия  
Дата: 10.12.03 09:59
Оценка:
Здравствуйте, akasoft, Вы писали:

[skip]
A>Там две задачи приведены. Посмотрим на первую задачу. Цитировать её не буду. Сразу напишу

[skip]

A>В начале нигде не сказано, что условия задачи могут меняться. А потом их взяли, да изменили. И пытаются показать, что раз мы не можем плюхнуться в середину метода Кипятить(), значит это глупо. А менять постановку задачи, значит, правильно, потому как из жизни.

В точку
A>Никто же не мешает модифицировать класс Чайник. Например, сделать метод Кипятить() виртуальным, и заменить его в потомке. А приватные методы сделать protected, раз уж нужно управляемое поведение.

Нет нельзя.. представь, что вместо чайника — объект ядра ОС... (там-то про то, что ОСы ОО стали).

A>Никто не мешает завести состояние класса чайник. "Вода есть?". "На плите?" "Газ зажжён?" Ждём, когда закипит?" "Чайник закипел?"

Только в наследниках... т.е. велосипед
по идее — нужно наоборот делать
... << RSDN@Home 1.1.2 beta 2 >>
Если при компиляции и исполнении вашей программы не происходит ни одной ошибки — это ошибка компилятора :)))
Re[3]: Кстати об ООП дизайне
От: _Obelisk_ Россия http://www.ibm.com
Дата: 10.12.03 10:35
Оценка: 3 (1)
Здравствуйте, Ведмедь, Вы писали:

В>Понятно, что приведенный пример высосан из пальца. Но проблема выделена по моему достаточно ясно : Невозможность(трудоемкость или неудоно) изменить логику работы обьекта, когда он уже спроектирован и написан. И это проблемы ООП, а не архитектора. Архитекор в рамках ООП ДЛЯ ДАННОЙ ЗАДАЧИ может ъхорошо спроектировать обьект. Когда задача измениться, часто приходится делать новый класс обьектов.



Есть ли подход, который решает эту проблему ?



Душа обязана трудиться! (с) Н.Заболоцкий.
Re[2]: Кстати об ООП дизайне
От: Andy_MAN Россия  
Дата: 10.12.03 10:39
Оценка:
Здравствуйте, akasoft, Вы писали:

A>Здравствуйте, Hacker_Delphi, Вы писали:


H_D>>Которая лишь подтверждает мысль, что ООП везде — это вред и блед, хотя и не отрицает что в бизнес приложениях ООП — это просто круто


A>
A>type
A>    Чайник = class()
A>    private
A>        procedure НалитьВоды();
A>        procedure ПоставитьНаПлиту()
A>        procedure ЗажечьГаз();
A>        function ЖдатьКогдаЗакипит(): Boolean;
A>    public
A>        procedure Кипятить();
A>    end;
    
A>procedure Чайник.Кипятить();
A>begin
A>    НалитьВоды();
A>    ПоставитьНаПлиту()
A>    ЗажечьГаз();
A>    repeat
A>    until ЖдатьКогдаЗакипит();
A>end;
A>


Вот только что хотел написать то же самое. На самом деле, грамотно спроектированная ОО модель может иметь очень низкие накладные расходы, связанные с поддержанием модели как таковой, а не функциональности приложения. В данном случае надо говорить не о том, что мы теряем при использовании оо подхода, а том, что в итоге приобретается. А приобретается при правильном подходе гораздо больше, чем теряется. Пример с чайником является образцом НЕПРАВИЛЬНОГО моделирования сущностей реального мира с использованием объектов.
Re[4]: Кстати об ООП дизайне
От: Hacker_Delphi Россия  
Дата: 10.12.03 11:03
Оценка:
Здравствуйте, _Obelisk_, Вы писали:

_O_>Здравствуйте, Ведмедь, Вы писали:


В>>Понятно, что приведенный пример высосан из пальца. Но проблема выделена по моему достаточно ясно : Невозможность(трудоемкость или неудоно) изменить логику работы обьекта, когда он уже спроектирован и написан. И это проблемы ООП, а не архитектора. Архитекор в рамках ООП ДЛЯ ДАННОЙ ЗАДАЧИ может ъхорошо спроектировать обьект. Когда задача измениться, часто приходится делать новый класс обьектов.



_O_>Есть ли подход, который решает эту проблему ?

однозначно? — нет... про что и речь — не нужно делать ОО ОС...
... << RSDN@Home 1.1.2 beta 2 >>
Если при компиляции и исполнении вашей программы не происходит ни одной ошибки — это ошибка компилятора :)))
Re[4]: Кстати об ООП дизайне
От: Ведмедь Россия  
Дата: 10.12.03 11:07
Оценка:
Здравствуйте, _Obelisk_, Вы писали:

_O_>Здравствуйте, Ведмедь, Вы писали:


В>>Понятно, что приведенный пример высосан из пальца. Но проблема выделена по моему достаточно ясно : Невозможность(трудоемкость или неудоно) изменить логику работы обьекта, когда он уже спроектирован и написан. И это проблемы ООП, а не архитектора. Архитекор в рамках ООП ДЛЯ ДАННОЙ ЗАДАЧИ может ъхорошо спроектировать обьект. Когда задача измениться, часто приходится делать новый класс обьектов.



_O_>Есть ли подход, который решает эту проблему ?


"Серебрянной пули нет" (с) Брукс
Да пребудет с тобой Великий Джа
Re[4]: Кстати об ООП дизайне
От: Sinclair Россия https://github.com/evilguest/
Дата: 10.12.03 11:22
Оценка: 5 (1)
Здравствуйте, _Obelisk_, Вы писали:
_O_>Есть ли подход, который решает эту проблему ?
Да. Это рефакторинг, т.е. набор преобразований объектной модели, сохраняющих семантику. Это когда мы режем статический метод вскипятить на три виртуальных и получаем ту же функциональность, но в более гибкой модели.
... << RSDN@Home 1.1.0 stable >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[5]: Кстати об ООП дизайне
От: _Obelisk_ Россия http://www.ibm.com
Дата: 10.12.03 11:27
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, _Obelisk_, Вы писали:

_O_>>Есть ли подход, который решает эту проблему ?
S>Да. Это рефакторинг, т.е. набор преобразований объектной модели, сохраняющих семантику. Это когда мы режем статический метод вскипятить на три виртуальных и получаем ту же функциональность, но в более гибкой модели.

Это не то, ведь мы же перелопачиваем весь код в данном случае, т.е. лезем внутрь всего.



Душа обязана трудиться! (с) Н.Заболоцкий.
Re[6]: Кстати об ООП дизайне
От: Sinclair Россия https://github.com/evilguest/
Дата: 10.12.03 11:37
Оценка:
Здравствуйте, _Obelisk_, Вы писали:
_O_>Это не то, ведь мы же перелопачиваем весь код в данном случае, т.е. лезем внутрь всего.
Да. Оставаясь в рамках модели, мы не сможем достичь некоторых целей. Что и показано чуть выше по топику. Так что это — именно то. В отличие от разработки модели с нуля, такой рефакторинг позволяет гарантировать функциональность без дополнительной отладки.
... << RSDN@Home 1.1.0 stable >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[7]: Кстати об ООП дизайне
От: _Obelisk_ Россия http://www.ibm.com
Дата: 10.12.03 14:40
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, _Obelisk_, Вы писали:

_O_>>Это не то, ведь мы же перелопачиваем весь код в данном случае, т.е. лезем внутрь всего.
S>Да. Оставаясь в рамках модели, мы не сможем достичь некоторых целей. Что и показано чуть выше по топику. Так что это — именно то. В отличие от разработки модели с нуля, такой рефакторинг позволяет гарантировать функциональность без дополнительной отладки.


Рефакторинг не страхует от кривых рук производещего этот самый рефакторинг. От отладки никуда не деться.



Душа обязана трудиться! (с) Н.Заболоцкий.
Re[8]: Кстати об ООП дизайне
От: Sinclair Россия https://github.com/evilguest/
Дата: 10.12.03 14:52
Оценка: +1
Здравствуйте, _Obelisk_, Вы писали:

_O_>Рефакторинг не страхует от кривых рук производещего этот самый рефакторинг. От отладки никуда не деться.

Это от того, что он не поддержиается средой. Я говорю именно о "математическом рефакторинге". Можно было лепить и объектные модели на С, вот только от кривых рук разработчика не было страховки, и в VMT могло оказаться все что угодно. Я прозрачно намекаю?
... << RSDN@Home 1.1.0 stable >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[9]: Кстати об ООП дизайне
От: _Obelisk_ Россия http://www.ibm.com
Дата: 11.12.03 08:31
Оценка: 6 (1)
Здравствуйте, Sinclair, Вы писали:

S>Это от того, что он не поддержиается средой. Я говорю именно о "математическом рефакторинге".


Нельзя формальным способом преобразовать бардак в порядок.



Душа обязана трудиться! (с) Н.Заболоцкий.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.