LINUX.ORG.RU

Бритва Оккама

 


0

1

Небольшой холивар на тему. Что делать если класс «распух»? Ведь правило гласит: «Не плоди лишних сущностей без нужды». Нужды нет, я могу нахерачить методов внутри одного класса, мне это не помешает, но как быть с «Принципом единственной обязанности»? Кто, что думает по этому поводу?

Методы это тоже сущности. Чем меньше классы, тем легче их понимать и покрывать тестами.

panter_dsd ★★★★
()

Принцип единственной обязанности говорит, что дополнительные классы нужны. Это не противоречит правилу «Не плоди лишних сущностей без нужды» потому, что нужда есть.

anonymous
()

Что делать если класс «распух»?

Что что ... рефакторить.

TEX ★★★
()

а еще есть правило — не жарить рыбу больше 15-20 минут, иначе она будет сухой

давай в программирование тащить это правило — не разрабатывать класс более 20 минут

anonymous
()

Используй композицию и делегируй функциональность.

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

не разрабатывать класс более 20 минут

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

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

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

трехлитровую? :-()

anonymous
()

Просто задать вопрос: этот класс не слишком много на себя берёт и не отвечает ли за многое (что невозможно по сути)?

В результате не делает ничего - эдакая завуалированная форма безделья и ухода от ответственности )

Полезно спросить: что он делает и что должен делать, какая его роль и главное предназначение. Но это уже последствия - нужно начинать раньше - еще на стадии проектирования: четко определить что должен делать данный класс, какая его главная функциональная обязанность, роль и ответственность и все становится на свои места.

В итоге, если класс делает всё, то это как-бы «класс-шланг». Например класс ячейка - формально делает всё, но по сути контейнер, в котором могут быть сущности, делающие всё что угодно...

На конце концов должно быть так: эффективность, функциональность, возможность.

Когда сущность высокоэффективна, если она универсальна и возможно ли это?

anonymous
()

Мне недавно достался в наследство классец, который реализует 16 (!) интерфейсов. Не надо так делать.

Gvidon ★★★★
()

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

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

И как именно прототипирование решает проблему плохого дизайна и разбухания сущностей? Как будто в каком-нибудь жабоскрипте нельзя забабахать объект, у которого будет 100 членов-данных и столько же функций.

Gvidon ★★★★
()

Если класс распух, то перепиши все на православной сишечке!

anonymous
()

И вообще: забанили меня, засранцы, и я не мог по-быстрому решить идиотскую проблему с наследованием классов в этом голимом С++ (совершенствовал сишную обертку над плюсовой библиотекой). Пришлось часа 2 ковыряться, наобум разные действия совершая (т.к. я в плюсах вообще 0). Наконец догадался, что чтобы один из шести произвольных подклассов в качестве указателя на глобальный объект выбрать, можно этот указатель изначально сделать типом материнского класса! Едреный язык! Жутчайший!!!

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

Вот простенький пример


Animal := Object clone do(
 whoAMe := method(("\nI am " .. self type) println)
 whenBaby := method("I am drinking milk when i am baby" println)
)

Predator := Animal clone do(
 eatingMeat := method("I like to eat meat" println)
)

Herbivore := Animal clone do(
 eatingHerb :=method("I like to eat vegetable food" println) 
)

Cat := Predator clone do(
 job := method("I like to catch mouses" println)
)

Mouse := Herbivore clone do(
 job := method("I'm afraid the cat" println)
)

Bear := Object clone do(
 appendProto(Predator)
 appendProto(Herbivore)
 job := method("I'm stealing honey, fishing and eating herb" print)
)


Cat clone do(
 whoAMe
 whenBaby
 eatingMeat
 job
)
Mouse clone do(
 whoAMe
 whenBaby
 eatingHerb
 job
)
Bear clone do(
 whoAMe
 whenBaby
 eatingHerb
 eatingMeat
 job
)

# ::: 
# ::: I am Cat
# ::: I am drinking milk when i am baby
# ::: I like to eat meat
# ::: I like to catch mouses
# ::: 
# ::: I am Mouse
# ::: I am drinking milk when i am baby
# ::: I like to eat vegetable food
# ::: I'm afraid the cat
# ::: 
# ::: I am Bear
# ::: I am drinking milk when i am baby
# ::: I like to eat vegetable food
# ::: I like to eat meat
# ::: I'm stealing honey, fishing and eating herb

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

Ты показал пример, как из маленьких «кирпичиков» понастроить себе объектов, это элементарно делается средствами любого ООП языка, а человек спросил, как ему сделать обратный финт ушами.

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

делается средствами любого ООП

Средствами «любого ООП», насколько я понимаю, не так легко специализировать методы для каждого субкласса. А может и невозможно. Пример, может, и не особо удачный, это хорошо видно на сложных иерархиях.

Покажи, как это будет выглядеть на жабе, например.

как ему сделать обратный финт ушами.

Насколько я понял, ТС ищет средства против разбухания 1-го класса, построение субклассов — это и есть такое средство.

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

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

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

в других языках есть mixins

миксины тут не прокатят.

в плюсах тоже самое делается через множественное наследование

Сомневаюсь. Тут не только множественное наследование, тут позднее связывание. В плюсах оно есть? Покажи как это пишется в плюсах.

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

class Bear:virtual Predator, virtual Hervibore{ public: virtual void job(){cout<<«I'm stealing honey, fishing and eating herb»);} };

тут позднее связывание

позднего связывания в примере не увидел. вполне вероятно, плохо смотрел, JS не знаю. а, понял, вы наверное про классическое позднее связывание методов (а не объектов иерархии) речь ведёте. в С++ это через virtual делается. вот в рантайме иерархию классов менять, в С++, действительно, не выйдет (точнее выйдет, но с костылями).

next_time ★★★★★
()
Последнее исправление: next_time (всего исправлений: 1)
Ответ на: комментарий от nond
И встал Айболит, побежал Айболит.
По полям, но лесам, по лугам он бежит.
И одно только слово твердит Айболит:
«Полиморфизм, виртуальные методы»
anonymous
()
Ответ на: комментарий от next_time

class Bear:virtual Predator, virtual Hervibore{ public: void job(){cout<<«I'm stealing honey, fishing and eating herb»);} };

В этом примере Bear унаследует от Animal?

JS не знаю

Это не JS вообще-то, это Io

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

Тут еще вот какая вещь, в классе Animal содержится метод whoAMe. Технически, это выглядит примерно так. При вызове экземпляра медведь, метод в рантайме ищется по цепочке наследования, и после его нахождения, этот метод применяется к неймспейсу самого экземпляра. То есть, заново идет поиск по цепочке наследования экземпляра медведя, находится в его ближайшем родительском классе, и уже затем происходит разрешение имен в методе whoAMe. На плюсах такое тоже делается?

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

В этом примере Bear унаследует от Animal?

конечно

Это не JS вообще-то, это Io

IO вообще первый раз вижу

next_time ★★★★★
()

Какой ЯП? Насколько распух класс и как именно?

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

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

 

Person := Object clone do(
 whoAMe := method(("I am " .. self type) println)
 greeting := method(("Hello, my name is " .. name) println)
 name ::= "nothing"
)

Musician := Person clone
Scientist := Person clone

musician1 := Musician clone setName("John")
musician2 := Musician clone setName("Jack")

scientist1 := Scientist clone setName("Lara")
scientist2 := Scientist clone setName("Mike")

musician1 do(
 whoAMe
 greeting
)

musician2 do(
 whoAMe
 greeting
)

scientist1 do(
 whoAMe
 greeting
)

scientist2 do(
 whoAMe
 greeting
)

# ::: I am Musician
# ::: Hello, my name is John
# ::: I am Musician
# ::: Hello, my name is Jack
# ::: I am Scientist
# ::: Hello, my name is Lara
# ::: I am Scientist
# ::: Hello, my name is Mike

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

прочитал про твой виртуал. Это похоже на костыль. Там создается таблица, для каждого экземпляра, при множественном наследовании там вообще ад по-ходу будет. Но, опять же, этот суррогат все равно не может в нормальную динамику. Метод ты разрешишь динамически, а как потом достать имена из неймспейса объекта, из которого метод вызывается? К примеру, я хочу достать изнутри виртуального метода другой виртуальный метод этого же объекта, а затем применить его к какому-нибудь его унаследованному свойству. Как это сделать?

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

совершенствовал сишную обертку над плюсовой библиотекой

Ужас какой. Земляне обычно делают наоборот. Если только плюсовую библиотеку надо обернуть для использования в каком-нибудь скриптоязычке...

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

Земляне обычно делают наоборот

Чушь-то какая! С++ нужен только для гуевин хомячковых. И то, это еще вопрос, нужен ли!

А вот и обертка. К сожалению, наркоманы из Apogee написали библиотеку на гнусной параше, пришлось для юзабельности писать прослойку.

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

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

Чем это выдуманную? С матрицей надо работать? Надо. Сишной библиотеки нет? Нет. Писать с нуля — не вариант (тем паче, документации нет, кроме кода библиотеки на говноязычке). Вот и пришлось выкручиваться, прослойку писать.

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

Там создается таблица, для каждого экземпляра, при множественном наследовании там вообще ад по-ходу будет.

нет, не для каждого экземпляра, кроме того, виртуальная таблица — всего лишь возможный вариант реализации, хоть и самый ходовой.

не может в нормальную динамику

это и есть нормальная динамика. в питонах и прочих IO используется ровно тот же самый подход.

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

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

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

в питонах

в питонах и прочем говне, так оно и есть. Но обобщать не надо.

nond
()

Скорее всего тебе надо миксовать.

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

Можно просто не считать язык «говноязычком» и написать всё на нём...

Кстати, у тебя даже в README нет ссылки на оригинальную плюсовую библиотеку. Так я и не понял, над чем именно ты писал обёртку.

hobbit ★★★★★
()
Последнее исправление: hobbit (всего исправлений: 1)
Ответ на: комментарий от hobbit

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

Она лежит в директории libapogee, а ссылку на веб-сайт — да, надо добавить. Забыл.

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