Как мне обрабатывать похожие объекты с разными свойствами? - PullRequest
2 голосов
/ 07 июня 2011

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

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

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

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

Ответы [ 2 ]

3 голосов
/ 07 июня 2011

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

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

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

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

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

2 голосов
/ 07 июня 2011

Прошло очень много времени с тех пор, как я написал Argotic (он был написан до того, как System.ServiceModel.Syndication существовал в .NET), но поскольку концепция автора существует и в RSS 2.0 и Атом , я действительно не помню, почему общий элемент фида не включал коллекцию авторов. Возможно, это связано с тем, что элементы структуры в документе 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"));
...