частный вопрос про хороший стиль
От: Ashley  
Дата: 22.12.10 16:30
Оценка:
У меня есть контейнер для базового класса с объектами разных типов, а мне нужно выбрать из него элементы только одного типа, небазового. Кажется, что getClassName это не совсем чистый код и должно быть более хорошее решение.
Re: частный вопрос про хороший стиль
От: __kot2  
Дата: 23.12.10 08:05
Оценка: -1
Здравствуйте, Ashley, Вы писали:

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

например специально для таких случаев я обычно завожу enum name {CHERRY, LEMON, APPLE, COUNT}
который инициализируется автоматом в конструкторе
class Fruit { enum Name{CHERRY, LEMON, APPLE, COUNT} name;}

class Apple : Fruit (Name::APPLE){}
...

перебор
if (it->name == Fruit::Name::APPLE)
{
динамик_каст
ассерт
если не ноль то работаем дальше
}


это нарушает принцип что базовый класс не должен знать о существовании наследников, но лучше и компактней способа я не знаю
Re[2]: частный вопрос про хороший стиль
От: Аноним  
Дата: 23.12.10 09:18
Оценка:
__>перебор
__>if (it->name == Fruit::Name::APPLE)
__>{
__> динамик_каст
__> ассерт
__> если не ноль то работаем дальше
__>}
__>это нарушает принцип что базовый класс не должен знать о существовании наследников, но лучше и компактней способа я не знаю

И это в форуме "Архитектура программного обеспечения"?
Re: частный вопрос про хороший стиль
От: Baudolino  
Дата: 23.12.10 11:49
Оценка:
A>У меня есть контейнер для базового класса с объектами разных типов, а мне нужно выбрать из него элементы только одного типа, небазового. Кажется, что getClassName это не совсем чистый код и должно быть более хорошее решение.
getClass в языках с поддержкой reflection в общем случае вполне нормальное решение. Проблема может быть скорее в том, зачем вам это понадобилось.
Re: частный вопрос про хороший стиль
От: Ronaldo 9  
Дата: 23.12.10 13:05
Оценка: 2 (1)
Здравствуйте, Ashley, Вы писали:

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


Сыграйте на полиморфизме. Можно сделать виртуальный/абстрактный метод, который возвращает bool. Пусть в нужном вам подклассе этот метод всегда возвращает true, а во всех остальных — false. Тогда вы сможете перебрать коллекцию и выбрать нужные объекты по значению, которое возвращает этот метод-фильтр.

С другой стороны, если у вас 10 подклассов и нужно выбирать объекты любого из этих 10 классов, то создавать 10 виртуальных методов глупо. Возможно, лучшим вариантом будет рефлекшн. Либо паттерн Visitor, если хотите хорошей масштабируемости. Либо — пересмотреть дизайн.
Re[3]: частный вопрос про хороший стиль
От: __kot2  
Дата: 23.12.10 15:28
Оценка:
Здравствуйте, Аноним, Вы писали:

__>>перебор

__>>if (it->name == Fruit::Name::APPLE)
__>>{
__>> динамик_каст
__>> ассерт
__>> если не ноль то работаем дальше
__>>}
__>>это нарушает принцип что базовый класс не должен знать о существовании наследников, но лучше и компактней способа я не знаю

А>И это в форуме "Архитектура программного обеспечения"?

ну раз вам так смешно, значит я какую-то глупость написал. пишу на С++ уже 10 лет, поэтому вы наверное пишете все 20. всегда приятно узнать что-то новое от настолько опытного человека. делитесь своим опытом — как сделать в С++ лучше, чем я предложил.
Re[4]: частный вопрос про хороший стиль
От: __kot2  
Дата: 23.12.10 15:33
Оценка:
Здравствуйте, __kot2, Вы писали:
А>>И это в форуме "Архитектура программного обеспечения"?
__>ну раз вам так смешно, значит я какую-то глупость написал. пишу на С++ уже 10 лет, поэтому вы наверное пишете все 20. всегда приятно узнать что-то новое от настолько опытного человека. делитесь своим опытом — как сделать в С++ лучше, чем я предложил.
ну и давайте даже задачу уточню — есть коллекция фруктов, нужно помимо кучи всяких вещей которые можно делать с фруктами нужно уметь выбирать из коллекции все фрукты по некоему идентификатору типа
Re[5]: частный вопрос про хороший стиль
От: out-of-the-way США www.tehnoromantik.net
Дата: 23.12.10 16:54
Оценка:
Здравствуйте, __kot2, Вы писали:

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

А>>>И это в форуме "Архитектура программного обеспечения"?
__>>ну раз вам так смешно, значит я какую-то глупость написал. пишу на С++ уже 10 лет, поэтому вы наверное пишете все 20. всегда приятно узнать что-то новое от настолько опытного человека. делитесь своим опытом — как сделать в С++ лучше, чем я предложил.
__>ну и давайте даже задачу уточню — есть коллекция фруктов, нужно помимо кучи всяких вещей которые можно делать с фруктами нужно уметь выбирать из коллекции все фрукты по некоему идентификатору типа

Паттерн Visitor:



  class Program {
        static void Main(string[] args){
           var fructs=new List<Fruct>();

           fructs.Add(new Apple());
           fructs.Add(new Apple());
           fructs.Add(new Pear());

           var visitor=new Visitor();

           foreach(var fruct in fructs){
                fruct.Access(visitor);
            }
        }
    }


    //базовый для всех фруктов или интерфейс
    public abstract class Fruct{
        public abstract void Access(Visitor visitor);
    }

    //яблоко
    public class Apple:Fruct{
        public override void Access(Visitor visitor){
            visitor.Visit(this);
        }
    }
    //груша
    public class Pear:Fruct{
        public override void Access(Visitor visitor){
            visitor.Visit(this);
        }
    }

    public class Visitor{
      public  void Visit(Apple apple){
          //ложим в нужную колекцию
         //............
      }
       public void Visit(Pear pear){
         //ложим в нужную колекцию
        //......................
       }
    }
Программа — мысли спрессованные в код.
Re: частный вопрос про хороший стиль
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 23.12.10 18:50
Оценка:
Здравствуйте, Ashley, Вы писали:

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


А зачем вам это делать? Нарушение LSP без необходимости — большой грех.

Есть одно исключение: иерархия фиксирована, те не планируется добавление наследников. такое может встретиться в AST. Тогда чисто ОО-способ это паттерн Visitor.
НО! Строго фиксированных иерархий не бывает, обычно рано или поздно требуется добавление наследников. Если такой сценарий реален, то можно заниматься type-testing_ом в рекурсивных функциях обхода, для этого можно использовать как встроенные функции получения типа, так и свои идентификаторы. Первый способ надежнее, второй быстрее.
Re[6]: частный вопрос про хороший стиль
От: __kot2  
Дата: 24.12.10 03:48
Оценка:
Здравствуйте, out-of-the-way, Вы писали:

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


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

А>>>>И это в форуме "Архитектура программного обеспечения"?
__>>>ну раз вам так смешно, значит я какую-то глупость написал. пишу на С++ уже 10 лет, поэтому вы наверное пишете все 20. всегда приятно узнать что-то новое от настолько опытного человека. делитесь своим опытом — как сделать в С++ лучше, чем я предложил.
__>>ну и давайте даже задачу уточню — есть коллекция фруктов, нужно помимо кучи всяких вещей которые можно делать с фруктами нужно уметь выбирать из коллекции все фрукты по некоему идентификатору типа

OOT>Паттерн Visitor:

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

но мастер, я не могу придумать способ как бы чтобы это не громоздко и коряво было. я подумал что стоит избавляться от идентификаторов типов фруктов вообще, но это код из игры — часть типов выбирает пользователь, часть выбирается случайно, ф-ия g — это часть логики игры и я не вижу способа как избавиться от типов. подскажи, как прорефакторить g?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.