Я хотел бы представить ситуацию, в которой было бы приятно:Расширения общего класса и реализует свой интерфейс во второй раз
- имеет общий интерфейс,
- имеет различные общие базовые классы реализуют ее ,
- предоставляют подклассы для базовых базовых классов,
- каким-то образом получают не общий интерфейс для подклассов.
Confused? Читайте дальше и расскажите мне, что вы думаете о решении.
Предположим, я хочу, чтобы служба предоставляла объекты любого типа на основе любого ключа и из любого места (DB, файл и т. Д.).
Для хорошего начала давайте создадим соответствующий интерфейс:
public interface ObjectProvider<K, V> {
V provide(K key);
}
В этом случае я буду в состоянии обеспечить любой вид реализации. Я хочу предоставить объекты из базы данных и файла.
Предположим, что предоставление V на основе K может быть выполнено с той же логикой DB независимо от типов объектов. Так что я могу написать общий базовый класс для доступа к БД:
public class DBObjectProvider<K, V> implements ObjectProvider<K, V> {
public V provide(K key) {
V v = null;
//some common DB logic to get V based on K
return v;
}
}
Собственно, получение объектов из файла также объект типа независимый:
public class FileObjectProvider<K, V> implements ObjectProvider<K, V> {
public V provide(K key) {
V v = null;
//some common file reading logic to get V based on K
return v;
}
}
Ok, теперь у меня есть две общие классы, Я могу использовать, чтобы получить все, что хочу.
Теперь я хочу использовать одну из этих общих функций, чтобы получить объект String на основе строкового ключа из базы данных. Кроме того, я хочу, чтобы он был определен как bean-компонент с использованием Spring XML. Я думаю, что нет способа определить общий боб в Spring XML (я прав?), Поэтому я создаю вместо этого класс нужного класса . Все, что мне нужно сделать, это:
public class DBStringStringProvider extends DBObjectProvider<String, String> {
}
Сейчас я могу вводить этот компонент в любой:
private ObjectProvider<String, String> objectProvider;
Все отлично, теперь ключевая часть. Я мог бы использовать мой полезный DB String-String провайдер во многих отношениях (hhmmm ... ok на самом деле). Предположим, я хочу сделать веб-сервис из него. Предположим, я хочу открыть DBStringStringProvider в качестве веб-службы CXF и протестировать его. Проблема заключается в том, что клиентский код для такой веб-службы выглядит следующим образом:
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setServiceClass(<INTERFACE>.class);
<INTERFACE> client = (<INTERFACE>) factory.create();
так мне нужен, не универсальный интерфейс для DBStringStringProvider который я не имею, потому что она расширяет общий базовый класс.
я могу сделать следующее:
Продлить ObjectProvider < String, > интерфейса Строки с другой:
@WebService
public interface StringStringProvider extends ObjectProvider<String, String> {
@WebMethod
String provide(String key);
}
Кроме его реализации, где она вроде уже внедренного родового базового класса:
public class DBStringStringProvider extends DBObjectProvider<String, String>
implements StringStringProvider {
}
Я чувствую себя немного непримиримым в отношении реализации того же интерфейса, где он уже введенный базовым классом. Но таким образом я могу использовать клиента WS:
factory.setServiceClass(StringStringProvider.class);
StringStringProvider client = (StringStringProvider) factory.create();
Мой вопрос: действительно ли это хорошая практика, чтобы делать то, что я только что сделал? Если нет, есть ли другой способ?
Это всего лишь один сценарий, где было бы здорово иметь не общий интерфейс для чего-то , который был определен как общий.
Я всегда представляю бедного парня, который наследует такой код. –
Что в этом плохого? – Dzik
@Dzik: ответить на ваш вопрос: просто слишком сложно ... держите его простым и спросите себя, каково преимущество такого дизайна, как это на самом деле (помните о поддерживаемости). – home