2010-03-11 2 views
0

Я создал простой API для преобразования произвольных объектов в удобочитаемые строки. Подумайте об этом как о обобщенной функциональности String.valueOf().интеллектуальное отображение ключей класса

В API это достигается путем выбора

public interface ObjectFormatter { 
     public String format(Object object); 
     public Class getObjectClass(); 
     public boolean offer(Object object); 
    } 

в зависимости от способа getClass() конкретного объекта, а затем передать объект методу format(). Отображение осуществляется с помощью простого поиска:

Class clazz = object.getClass(); 
    ObjectFormatter formatter = this.formatters.get(clazz); 
    if(formatter != null) 
     return formatter; 

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

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

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

ответ

0

Вы можете использовать API isAssignableFrom для java.lang.Класс

Кроме того, если бы я вас вместо того, чтобы делать все рамки сам я бы просто использовать «классы поддержки PropertyEditor» с весны (конвертировать/формат боб в свойство строки и наоборот) http://static.springsource.org/spring/docs/2.5.x/reference/validation.html

+0

Я думаю, «isAssignableFrom» сделает это для меня. Я искал такой метод, но пропустил его несколько раз. –

0

В принципе, это то место, где небольшое отражение может помочь.

  1. Начните с просмотра всех суперклассы вашего класса объекта по телефону Class.getSuperclass(), но не забывайте, чтобы остановить свой супер-навигации, как только объект будет достигнута, так как суперкласс Объект Object.
  2. Если объект ObjectFormatter не найден, вы можете позвонить Class.getInterfaces(), чтобы получить список интерфейсов, реализованных вашим классом. Очевидно, что вызов его по интерфейсу будет возвращать интерфейсы, которые он расширяет ...

Тогда у вас есть выбор, вы можете позвонить (1), затем (2) или (желательно) позвонить (2) и агрегировать его результаты, и только если (2) не удается, вызовите (1). Таким образом, вы будете более уважительно относиться к различным контрактам вашего obejct.

0

Моя быстрая и грязная идея заключалась в том, что вы могли просто пересечь дерево наследования «clazz» и посмотреть, содержались ли в них форматирующие элементы. Таким образом, вы можете добавить один Throwable formatter, и все исключения получат его.

С надлежащей точки зрения ООП/наследования и предполагая, что вы не можете изменить фактический класс, потому что это третья сторона, я бы, вероятно, добавил адаптер вокруг третьего класса, у которого были методы, которые я хотел. В предыдущем проекте мы долгое время сопротивлялись этому, думая, что он будет слишком громоздким/уродливым, но это только привело к множеству хакерских обходных решений. Когда мы, наконец, купили пулю и сделали это, мы могли вернуться к правильному хорошему дизайну. Только мои 2 цента.

Смежные вопросы