интеллектуальное отображение ключей класса - PullRequest
0 голосов
/ 11 марта 2010

Я создал простой 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() не содержит желаемой информации объект.

Ответы [ 3 ]

0 голосов
/ 11 марта 2010

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

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

0 голосов
/ 11 марта 2010

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

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

0 голосов
/ 11 марта 2010

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

  1. Начните с просмотра всех суперклассов вашего класса объектов, вызвав <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Class.html#getSuperclass()" rel="nofollow noreferrer">Class.getSuperclass()</a>, но не забудьте остановить свой супер-navigation после достижения объекта, так как суперклассом объекта является Object.
  2. Если ObjectFormatter не найден, вы можете вызвать <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Class.html#getInterfaces()" rel="nofollow noreferrer">Class.getInterfaces()</a>, чтобы получить список интерфейсов, реализованных вашим классом.Очевидно, что вызов его через интерфейс вернет интерфейсы, которые он расширяет ...

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...