LINUX.ORG.RU
Ответ на: комментарий от shty

это Вы со своими коллегами щитоле?

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

программа, кстати, не будет валиться только в том случае, если нигде в архитектуре нет завязки на инварианты интерфейса - что бывает только в проектах уровня hello world. и, кстати, как ты собираешься в статике отслеживать все вызовы геттера несуществующего поля, чтобы выдать хотя бы соответствующий warning?

jtootf ★★★★★
()
Ответ на: комментарий от shty

может поменяться вообще вся начинка класса

и в случае, если эта начинка будет выведена в интерфейс с помощью геттеров/сеттеров - тебе придётся менять и интерфейс тоже

видимо, ты очень любишь этот самый рефакторинг

jtootf ★★★★★
()
Ответ на: комментарий от jtootf

ты уж определись, светоч ты наш,- то ли ты ратуешь за инкапсуляцию

да, инкапсуляция - есть хорошо

то ли защищаешь технику, её нарушающую

*еттеры не нарушают инкапсуляцию, правильно написанные *еттеры, и только там где нужно, а не на все члены данных подряд

программа, кстати, не будет валиться только в том случае, если нигде в архитектуре нет завязки на инварианты интерфейса

поясните что именно Вы имеете в виду и как Вы планируете разрешать проблему

и, кстати, как ты собираешься в статике отслеживать все вызовы геттера несуществующего поля, чтобы выдать хотя бы соответствующий warning?

элементарно

#ifdef __GNUC__
    #define DEPRECATED(func) func __attribute__ ((deprecated))
#elif defined(_MSC_VER)
    #define DEPRECATED(func) __declspec(deprecated) func
#else
    #pragma message("WARNING: You need to implement DEPRECATED for this compiler")
    #define DEPRECATED(func) func
#endif

...

//don't use me any more
DEPRECATED(void OldFunc(int a, float b));

//use me instead
void NewFunc(int a, double b);

будет warning, со включенным Wall компиляция остановится

shty ★★★★★
()
Ответ на: комментарий от jtootf

может поменяться вообще вся начинка класса

и в случае, если эта начинка будет выведена в интерфейс с помощью геттеров/сеттеров - тебе придётся менять и интерфейс тоже

Вы не умеете читать? перечитайте сообщение к которому аппелируете

видимо, ты очень любишь этот самый рефакторинг

нет, кто ж его любит, но приходится постоянно использовать ибо программные продукты развиваются

а Вы не используете рефакторинг? быть может Ваши программы Вы один раз написали и положили на полочку и только пыль сдуваете?

shty ★★★★★
()
Ответ на: комментарий от shty

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

ну так и не надо тогда говорить, что геттеры/сеттеры в общем случае улучшают инкапсулированность класса

поясните что именно Вы имеете в виду и как Вы планируете разрешать проблему

#include <cassert>

class Rect
{
public:
    Rect(const double width, const double height) : width_(width), height_(height) {}

    double getWidth() const { return width_; }
    void setWidth(const double width) { width_ = width; }

    double getHeight() const { return height_; }
    void setHeight(const double height) { height_ = height; }
private:
    double width_;
    double height_;
};

class NewRect
{
public:
    NewRect(const double width, const double height) : width_(width) { (void)height; }

    double getWidth() const { return width_; }
    void setWidth(const double width) { width_ = width; }

    double getHeight() const { return 0; }
    void setHeight(const double height) { (void)height; }
private:
    double width_;
};

double square(Rect const & rect)
{
    return rect.getWidth() * rect.getHeight();
}

double square(NewRect const & rect)
{
    return rect.getWidth() * rect.getHeight();
}

int main()
{
    Rect a(2, 2);
    NewRect b(2, 2);

    assert(square(a) == square(b));

    return 0;
}

при изменении Rect на NewRect (отличаются только реализацией, NewRect по некоторым причинам превратился в квадрат) инвариант вычисления площади в функции square() нарушается

пример утрированный - однако в реальном проекте завязок на свойства интерфейса будет ещё больше (на то он и интерфейс). правильным вариантом (одним из) был бы вынос в интерфейс класса функции, расчитывающей площадь, и избавление от геттеров/сеттеров

jtootf ★★★★★
()
Ответ на: комментарий от jtootf

пример утрированный

Сэр Вы себе льстите, пример идиотский, в этом случае getHeight будет возвращать тоже что и getWidth

wfrr ★★☆
()
Ответ на: комментарий от shty

перечитайте сообщение к которому аппелируете

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

а Вы не используете рефакторинг?

использую. однако сознательно плодить ошибки архитектуры, чтобы в очередной раз его выполнить, я не собираюсь

jtootf ★★★★★
()
Ответ на: комментарий от jtootf

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

ну так и не надо тогда говорить, что геттеры/сеттеры в общем случае улучшают инкапсулированность класса

ссылку на сообщение где я это говорил

shty ★★★★★
()
Ответ на: комментарий от wfrr

в этом случае getHeight будет возвращать тоже что и getWidth

class NewRect
{
public:
    NewRect(const double width, const double height) : width_(width) { (void)height; }

    double getWidth() const { return width_; }
    void setWidth(const double width) { width_ = width; }

    double getHeight() const { return width_; }
    void setHeight(const double height) { (void)height; }
private:
    double width_;
};

int main()
{
    NewRect b(2, 2);

    b.setWidth(5);
    b.setHeight(1);

    assert(square(a) == 5);
...
}

расширенный список нарушаемых инвариантов (и ошибочных решений) можешь посмотреть в статье о принципе подстановки Лисков

jtootf ★★★★★
()
Ответ на: комментарий от tailgunner

> ИМХО, за функцию setField, которая только присваивает значение some_other_field, нужно бить по рукам.

Чуть позже, когда например потребуется сделать листенер на изменение поля, ты начнешь рвать волосы на некоторых частях своего тело (причем эти части не грудь, не голова и не жопа), но будет поздно.

no-dashi ★★★★★
()
Ответ на: комментарий от shty

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

ну так и не надо тогда говорить, что геттеры/сеттеры в общем случае улучшают инкапсулированность класса

ссылку на сообщение где я это говорил

пожалуйста:

elf

Нужны ли вообще геттеры сеттеры в классах?

shty

wfrr

Облегчает рефакторинг и сопровождения, ибо интерфейс не меняется

неистово и яростно плюсую

shty

man инкапсуляция

ты разделяешь интерфейс от реализации и если реализация меняется, то в коде который использует интерфейс ничего менять не надо

хочешь сказать, что ты имел в виду что-то другое?

jtootf ★★★★★
()
Ответ на: комментарий от no-dashi

>> ИМХО, за функцию setField, которая только присваивает значение some_other_field, нужно бить по рукам.

Чуть позже, когда например потребуется сделать листенер на изменение поля, ты начнешь рвать волосы на некоторых частях своего тело

Веско, аргументированно. Вот тебе такой же ответ: нет, не начну.

tailgunner ★★★★★
()
Ответ на: комментарий от jtootf

расширенный список нарушаемых инвариантов

равен пустому множеству, вы сами догадаетесь почему или вам рассказать что стоит ожидать от объекта квадрата? А то Вы впадаете в маразм навроде того что сортированная очередь нарушает инварианты модели FILO.

wfrr ★★☆
()
Ответ на: комментарий от jtootf

при изменении Rect на NewRect (отличаются только реализацией, NewRect по некоторым причинам превратился в квадрат) инвариант вычисления площади в функции square() нарушается

эм, в таком разе интерфейс вообще не надо менять, пусть возвращают одно и то же - какие проблемы?

правильным вариантом (одним из) был бы вынос в интерфейс класса функции, расчитывающей площадь, и избавление от геттеров/сеттеров

в данном случае - да, непонятно только что этот пример показывает

shty ★★★★★
()
Ответ на: комментарий от jtootf

хочу сказать что не увидел в цитатах «геттеры/сеттеры в общем случае улучшают инкапсулированность класса», ещё будут цитаты?

shty ★★★★★
()
Ответ на: комментарий от shty

эм, в таком разе интерфейс вообще не надо менять, пусть возвращают одно и то же - какие проблемы?

я выше привёл пример инварианта, нарушаемого таким подходом

непонятно только что этот пример показывает

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

jtootf ★★★★★
()
Ответ на: комментарий от jtootf

>и, кстати, как ты собираешься в статике отслеживать все вызовы геттера несуществующего поля, чтобы выдать хотя бы соответствующий warning?

Чъёрт. Мне Eclipse всегда вставляет «сентенцию» @Override на переопределённый метод. Видимо, чтобы разработчики «не забывали», ЧТО они переопределяют. Ж)

iZEN ★★★★★
()
Ответ на: комментарий от jtootf

Начнем урок геометрии за школьный курс. Ученик jtootf, назовите отличия квадрата от прямоугольника.

wfrr ★★☆
()
Ответ на: комментарий от iZEN

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

wfrr ★★☆
()
Ответ на: комментарий от jtootf

Гражданин, Вы сами просили рассказать, ежели рассказ мой будет монологом то Вы ничего не выучите, так что извольте вкушать материал и отвечать на мои вопросы.

wfrr ★★☆
()
Ответ на: комментарий от jtootf

При наличии геттеров сеттеров, гораздо проще следить на тем, чтобы связанные поля в классе не находились в «неправильном» состоянии (в то время когда класс доступен).

В многопоточных приложениях, проще следить, за тем, чтобы к объекту нельзя было получить доступ во время транзации или если можно, то объект бы вёл себя всё равно правильно. Напр блокирование доступа к объекту (или определенным полям).

Плюс если разрабатывается некая библиотека, то переработка внутренней реализации без смены интерфейсов, тоже упрощается. (Пример: Vector в jdk, который был полностью переделан к ЕНМИП jdk5)

При множестенном наследовании на основе интерфейсов опять, же в случае сеттеров наследование возможно, а для просто полей нет.

В общем-то положительных моментов не мало.

qnikst ★★★★★
()
Ответ на: комментарий от wfrr

> Вас часто посещают подобные приступы?

Часто ли со мной говорят упоротые скунсы? Нет, не часто, и почему-то только на LOR.

tailgunner ★★★★★
()
Ответ на: комментарий от jtootf

>и в случае, если эта начинка будет выведена в интерфейс с помощью геттеров/сеттеров - тебе придётся менять и интерфейс тоже

видимо, ты очень любишь этот самый рефакторинг


«Предпочитайте интерфейсы абстрактным классам. Предпочитайте компоновку наследованию.» © Джошуа Блох

С помощью mixin'ов легче добиться нужной функциональности.

iZEN ★★★★★
()
Ответ на: комментарий от qnikst

При наличии геттеров сеттеров, гораздо проще следить

гораздо проще чем в каком случае? с чем сравниваем?

jtootf ★★★★★
()

elf, конкретно тебе геттеры/сеттеры не нужны, я гарантирую это. Тем более они не нужны тем, кто имеет привычку включать мозг при проектировании интерфейса. Лично я недоумеваю, кто же первым додумался до этого быдло-паттерна? Неужто и тут порылся отморозок Фаулер? Любителям с умным видом вещать про инкапсуляцию в контексте геттеров/сеттеров посылаю мощный заряд лучей поноса! Это из-за вас, индусов, ОО парадигма была значительно дискредитирована в последние 2 десятилетия. Геттеры/сеттеры в пистоне, где приватность ничем не гарантирована, это особенный шик! Пишите, шуры, пишите! По крайней мере, благодаря такой «технике» сходу выявляются индусы с жабой головного мозга. Тоже польза.

anonymous
()
Ответ на: комментарий от anonymous

Неужто и тут порылся отморозок Фаулер?

нет, Фаулер выступает против их использования; выше я приводил ссылку как раз не его статью по теме

jtootf ★★★★★
()
Ответ на: комментарий от jtootf
function randDouble(const double max){
   return (double)rand()/(double)RAND_MAX*max;
}
function randDouble2(const double max){
  return 42;
}
int main() {
   double a=randDouble(10);
              b=randDouble2(10);
   assert( (a>-10) and (a<10));
   assert( (b>-10) and (b<10));
}

тебя не напрягает такой пример? У тебя 2 класса, свойства которых следуют только из названий (т.е. ни о каких инвариантах речи идти не может).

qnikst ★★★★★
()
Ответ на: комментарий от jtootf

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

В общем, то аргументация против мысли в том, контексте в кот. она выражена будет?

qnikst ★★★★★
()
Ответ на: комментарий от wfrr

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

К экспертам это не относится.

iZEN ★★★★★
()
Ответ на: комментарий от qnikst

У тебя 2 класса, свойства которых следуют только из названий

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

в случае, если весь код, использующий данный класс, покрыт юнит-тестами, они отследят все подобные нарушения, и придётся всего лишь произвести (возможно, масштабный) рефакторинг. если юнит-тестов нет, получаем обширное поле трудноуловимых нарушений в логике работы системы. ради чего?

jtootf ★★★★★
()

Хм, ты же вроде только про Qt в девелопменте писал? Так и не выёживайся, делай геттеры и сеттеры :), в общем его стиле.

zJes ★★
()
Ответ на: комментарий от jtootf

вопрос №1. Это как то связанно с геттерами/сеттарами? или только про необходимость создания тестов?

qnikst ★★★★★
()
Ответ на: комментарий от iZEN

Только если «эксперт» - это диагноз. Тем более что экперды как раз за такое и бьют.

wfrr ★★☆
()
Ответ на: комментарий от qnikst

тема разговора 504.7 раз сменилась с начала топика

тема не менялась, просто альтернативой геттерам/сеттерам являются не только открытые поля

jtootf

проектирование от реализации к интерфейсу (у нас есть поле, значит надо его сделать приватным и поставить геттер/сеттер) - плохо, проектирование от интерфейса к реализации (мы фиксируем интерфейс, и имеем возможность менять реализацию с как можно большей свободой) - хорошо. тот факт, что подаляющее большинство аудитории ЛОРа считает избавление от сеттеров/геттеров ослаблением инкапсуляции, меня огорчает

где-то так

jtootf ★★★★★
()
Ответ на: комментарий от jtootf

в контексте проблемы автора, какие ещё есть варианты, кроме immutable объекта и открытых полей? (мне честно интересно услышать твое мнение)

Ну.. если понимать под геттером/сеттером то, что «у нас есть поле, значит его надо сделать приватным и поставить геттер/сеттер», тогда действительно, я с тобой согласен. Но мне кажется, что в данных вопросах стоит тут же напомнить, что бонусы от геттеров/сеттеров на этом не заканчиваются.

qnikst ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.