LINUX.ORG.RU

[Mono][C#] Иерархия классов: как правильно сделать?

 


0

1

Здравствуй, ЛОР!

Суть проблемы такова: пишем программу для игры в шахматы. Сейчас столкнулся с архитектурной дилеммой: как лучше описать иерархию классов - сначала определить абстрактный класс «Шахматная фигура», а потом от нее производить потомков «Пешка», «Конь» и т.д.

Или же определить обобщенный класс «Фигура», которому потом уже передавать нужный параметр при создании объектов «Конь», «Слон» и т.д.

Как производительнее и рациональнее поступить, как считаешь, ЛОР?

Всем большое спасибо за ответы по делу.

С уважением.

З.Ы. «Производительнее» в плане быстроты работы приложения.

★★★★★

Последнее исправление: LongLiveUbuntu (всего исправлений: 1)

> Или же определить

Или заменить на И.
И будет нормально, классы и фактори.

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

А в плане годности архитектуры?

По «бритве Оккама» лучше второй вариант, конечно, но...

Сомнения гложут.

LongLiveUbuntu ★★★★★
() автор топика

Перед чтением моего поста ознакомьтесь с
http://www.linux.org.ru/forum/development/5788733

Тут я попробую дать практически противоположный набор советов :)

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

Или же определить обобщенный класс «Фигура», которому потом уже передавать нужный параметр при создании объектов «Конь», «Слон» и т.д.



Не стоит вообще городить иерархию и др... на ООП :)
Суть моего имхо - у Вас _ строго ограниченный и нерасширяемый_ набор фигур, разнящихся лишь способом передвижения и ресурсом (графическим изображением)

Есть смысл сделать вместо иерархии перечисление + воспользоваться чем-то вроде паттерна Template/Factory Method но ближе к функциональному стилю (дабы не городить вместо одной иерархии другую(-ие)) - с использованием вместо подклассов функций высшего порядка.

yaws
()

>производительнее

Ранняя оптимизация - корень всех зол

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

>По «бритве Оккама» лучше второй вариант, конечно, но...

Нифига не лучше.

Как ты для каждой фигуры будешь отслеживать просматриваемые ею поля? Большим свичём по параметру фигуры? Я бы убил за такое.

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

>Есть смысл сделать вместо иерархии перечисление + воспользоваться чем-то вроде паттерна Template/Factory Method но ближе к функциональному стилю (дабы не городить вместо одной иерархии другую(-ие)) - с использованием вместо подклассов функций высшего порядка.

Ещё один кудесник, йопт.

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

>сначала определить абстрактный класс «Шахматная фигура», а потом от нее производить потомков «Пешка», «Конь»

Вот она - бритва то.

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

> Большим свичём по параметру фигуры? Я бы убил за такое.

О да, будешь убивать за паттерн матчинг? Ну да, ведь ООП - überalles in der Welt.

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

ADT и паттерн-матчинг это, конечно, круто, но только не в контексте C# :)

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

Диспетчеризация по типу в виде полиморфизма является более родной для шарпа, чем паттерн-матчинг, говорю же.

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

Большое это какое? Пешка, Конь, Слон, Ладья, Ферзь, Король.

yoghurt ★★★★★
()

Наследование - частный случай агрегации, такой своеобразный синтаксический сахар над ней. Так что ваш вопрос равносилен вопросу как мне назвать переменную: mfv или my_fucken_variable ?

предлагаю все-таки первое, то есть наследование, ибо короче, хотя и менее гибко, но так как гибкость вам нафиг не нужна, так что наследование.

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

Если вспомнить ту же Scala, то там ADT реализуется как раз через наследование. А предложение применять паттерн-мачинг путем замены его свичем ввиду отсутствия в языке паттерн-мачинга - это полный укуринг.

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

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

Предложение (вернее, намёки) были на использование нормального языка. Например, haskell. Без OOP. Без фокуса на низкоуровневые детали реализации, но с фокусом на решение: нужно определить типы фигур - определили, нужно сопоставить фигуру и поведение - сопоставили. Всё просто. Хотя, jedem das seine.

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

И какой будет смысл в данной операции? Мифическое переиспользование кода? Гибкость сопровождения? Есть возможность добавить новые шахматные фигуры? Или что?

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

> Или что?

А ничего, это обычное поведение программистов на ОО языках. Пишут всякую ненужную фигню, понимаеш-ли.

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

> Как ты для каждой фигуры будешь отслеживать просматриваемые ею поля? Большим свичём по параметру фигуры? Я бы убил за такое.

если большой свич встретится один-два раза, то городить большое наследование точно не стоит.

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

Наибольший прикол состоит в том, что сообщество РСДН, задавшись вопросом: «на какой задаче продемонстрировать безусловное преимущество ООП перед ФП/МП» так и не смогло родить чего-то окончательного.

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

Хорошо. Если проект для обучения, то рекомендую попробовать F#. Он работает и на Mono. И к хаскелю опять же ближе. Легко интегрируется с C#. Всегда можно заглянуть в исходники.

Шахматные фигуры можно кодировать числами / enum. В F# будет предоставлена еще одна возможность: discriminated unions.

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

Что-то припоминаю, было дело. Сам принял скромное участие :) Забавно, что немерлисты в большинстве своем прожженные ооп-шники, особенно Влад.

dave ★★★★★
()

Без разницы. Нефиг перфекционизмом заниматься.

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

Это было до конкурса из журнала «Практика функционального программирования», в котором ФП эпичненько слил на своем же поле? )

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

Второе и третье.

Зачем делать что-то вручную, если это нам предоставляет сама объектная система? Идентифицировать типы фигур перечислениями и проводить диспетчеризацию через свитч *на шарпе* не является разумным методом *для шарпа*.

Да, это выглядит клево в CL и Haskell, но абсолютно неестественно для C#.

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

> Зачем делать что-то вручную, если это нам предоставляет сама объектная система?

Ы, лол. Тебе объектная система будет классы писать, код писать, наследование писать, методы классов писать?!

Отличный, даже можно сказать - показательный, фэйл сторонников ООП. Считать, что всё будет «автоматически» из-за ООП (реюз кода, гибкость, а здесь - автоматически предоставленно объектной системой).

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

> Это было до конкурса из журнала «Практика функционального программирования», в котором ФП эпичненько слил на своем же поле? )

Им нужно было изначально ввести «правильные» метрики, по которым бы ФП выигрывало - например, количесто ФВП :D

anonymous
()

>Суть проблемы такова: пишем программу для игры в шахматы. Сейчас столкнулся с архитектурной дилеммой: как лучше описать иерархию классов - сначала определить абстрактный класс «Шахматная фигура», а потом от нее производить потомков «Пешка», «Конь» и т.д.

без понятия как в шарпе, но в С++ я-бы именно так и сделал.

drBatty ★★
()

Как производительнее и рациональнее поступить, как считаешь, ЛОР?

Я так понимаю, тебе нужна будет оценочная функция по фигуре (и возможно местоположению и еще чего-нибудь типа начало/миттельшпиль/окончание партии). Нужен еще генератор ходов по фигуре. Я бы сделал так, чтобы фигуры кодировалась индексом массивов или эти индексы легко высчитывались (наложили маску и получили индекс). Имеем массив оценок (или массив оценочных функций от местоположения). Массив генераторов ходов. Будет эффективно. Прямолинейно. Не будет напрягаться сборщик мусора.

Последнее особенно важно, если ты собираешься производить поиск в глубину (по альфа-бета отсечению). А объекты тебе придется выделять из кучи. На каждую фигуру по новому объекту. Это так неэффективно! По-моему тут даже выбора нет ;)

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

Да и еще. Может быть, здесь я выбрал бы C++ (и в переборе использовал бы свой аллокатор). Но если тебе для учебы, то особо без разницы, какой язык.

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

Да просто я посчитал С++ чересчур замудренным. И потом я ленивый и забывчивый, постоянно буду забывать память освобождать ))

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