Как мне обрабатывать похожие объекты с разными свойствами?

Я создаю RSS-клиент и использую фреймворк Argotic. Он предоставляет разные классы для разных видов каналов, таких как Atom, RSS и OPML. Эти классы не наследуются ни от какого другого класса, и они не реализуют общий интерфейс для доступа к своим свойствам.

E сть GenericSyndicationFeed тип, который реализует перегруженный метод, где вы можете передать AtomFeed или же RssFeed, Если я хочу использовать "более" строго типизированные классы, мне, по сути, понадобятся два пути кода (один для Atom и один для RSS) везде в моей программе. Очевидно, я не собираюсь этого делать.

Никакой документации от автора, кроме документации API, нет, поэтому я немного растерялся, почему он был реализован таким образом, вместо того, чтобы полностью использовать преимущества полных классов. Меня беспокоит то, что я не могу получить авторов элемента при использовании GenericSyndicationItem тип.

Что я могу сделать здесь? Сделать класс-оболочку? Или наследовать от RssFeed а также AtomFeed классы и реализовать интерфейс, чтобы выставить свойства, которые я считаю, должны быть похожи от обоих?

2 ответа

Если вы используете стороннюю библиотеку и библиотека не соответствует вашим архитектурным потребностям: адаптируйтесь! Но как?

Вы уже определили некоторые из ваших вариантов, и есть еще:

  1. Оберните существующие классы в новые классы, используя шаблон адаптера
  2. Расширяйте и объединяйте разнородные классы, реализуя общий интерфейс
  3. Рефакторинг исходного кода для использования Полиморфизма изначально

Если в существующих классах вообще нет общего базового класса, то первые два варианта имеют примерно одинаковый объем работы. Обертывание имеет преимущество в виде более слабой связи в случае, если вы когда-нибудь решите переключиться на другую структуру. Расширение позволяет избежать большого количества кода, например adaptee.AdapteeMethod так как вы можете вызывать базовые методы без указания экземпляра. В этом случае я бы склонялся к шаблону адаптера, если нет хотя бы некоторого общего базового класса, который вы можете использовать посредством наследования.

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

Прошло очень много времени с тех пор, как я написал Argotic (он был написан до того, как System.ServiceModel.Syndication существовал в.NET), но поскольку концепция автора существует как в RSS 2.0, так и в Atom, я не могу вспомнить, почему универсальный Элемент фида не включает коллекцию авторов. Возможно, это связано с тем, что элементы структуры в документе OPML не имеют понятия автора. Плохой дизайн с моей стороны, очевидно.

Суть в том, что я был еще молод и учусь, а Argotic полезен, когда он был написан 3 года назад; крайне нуждается в серьезном рефакторинге. Если System.ServiceModel.Syndication может удовлетворить ваши потребности, я рекомендую вам использовать это для анализа ваших каналов синдикации.

Поскольку у вас есть полный исходный код Argotic, и он не удовлетворяет вашим потребностям; Вы можете добавить коллекцию авторов в класс общих синдикационных элементов и заполнить ее при использовании канала RSS или Atom.

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

Тем не менее, если вы знаете формат канала перед его использованием, вы можете сделать следующее:

RssFeed feed = RssFeed.Create(new Uri("http://www.pwop.com/feed.aspx?show=dotnetrocks&filetype=master"));

AtomFeed feed = AtomFeed.Create(new Uri("http://news.google.com/?output=atom"));
Другие вопросы по тегам