#java #reflection
#java #отражение
Вопрос:
Я разработал простую POS-систему, которая получает список продуктов и кнопок из базы данных. Таблица, содержащая все кнопки, предоставляет всю информацию, необходимую для рисования кнопки (т. Е. размер, положение, метку, цвет и артикул, к которому она относится).
В оригинальной версии все «функциональные» кнопки были жестко запрограммированы (т. Е.: числа 1-9, оплата, изменение уровней цен, окончание смены и т.д.), Но я хочу перейти к более настраиваемому дизайну, чтобы функциональные кнопки также могли храниться в базе данных.
Я рассматривал возможность сделать это с помощью чего-то, основанного на отражении. У меня есть класс, который действует как интерфейс, содержащий все методы, которые появятся в DB, которые затем будут вызывать любой из необходимых методов в системе. Но я не уверен, как сопоставить это с DB.
Я почти уверен, что каждый метод будет принимать 0, 1 или 2 параметра, которые имеют смесь boolean, int, double и char.
Я придумал обозначение для базы данных, которое я могу проанализировать, чтобы определить всю информацию, необходимую для вызова метода, например, для оплаты продажи, я бы написал что-то вроде
paySale[]
в базе данных, но если бы клиент дал мне 50 долларов, и я хотел бы использовать кнопку «быстрые наличные», тогда вызов метода был бы
paySale[d 50]
или что-то немного более сложное, например, оплата чеком
paySale[i 3, d 50]
где int — это тип способа оплаты (в данном случае это был бы чек), а double — общая сумма.
Моя проблема в том, что когда я пытаюсь извлечь метод с помощью GetMethod (), я не могу понять, как определить, какие параметры искать, например double.class и int.class
Потребуется вызвать несколько разных методов для обработки таких вещей, как изменения уровня цен, конец смены, оплата счетов / вкладок и т.д., Поэтому, если есть более простой способ сделать это, то я открыт для этого!
Еще раз спасибо, ребята!
Ответ №1:
Используйте что-то вроде
class.getMethod(int.class, double.class, String.class)
и т.д. Если ваш метод не является общедоступным, используйте getDeclaredMethod()
вместо этого.
Но, честно говоря, ваше решение звучит странно. Насколько я понимаю, вы на самом деле сохраняете в DB какой-то скрипт, а затем запускаете его. Если это так, используйте готовый к использованию скриптовый движок. Например, java 1.6 и выше имеет встроенный интерпретатор JavaScript (см. ScriptEngineManager). Вы можете генерировать javascripts и затем запускать их. Это намного проще, чем создавать очень ограниченный интерпретатор сценариев самостоятельно.
Комментарии:
1. Я понятия не имел, что интерпретатор JavaScript был встроен в 1.6, чтобы проверить это!
2. Принятый ответ на предлагаемое использование ScriptEngineManager. Спасибо, вы действительно упростили проблему!
Ответ №2:
В этом вопросе я согласен с AlexR.
Хотя то, что вы делаете, определенно возможно, вам было бы лучше сохранить исполняемый скрипт в базе данных и выполнить этот скрипт в контексте вашего приложения.
Тем не менее, я сомневаюсь в необходимости того, чтобы система была такой гибкой: существует лишь определенное количество функций (команд), которые, вероятно, понадобятся вашей системе. Похоже, что эти команды могут быть реализованы обычным образом и назначены определенным ключам / и т.д. С помощью обычного механизма настройки.
Комментарии:
1. Я не уверен, что вы подразумеваете под «нормально реализованным», и, хотя существует ограниченный набор функций, которые я могу предвидеть, большинство функций имеют потенциал для разного количества параметров (согласно моему исходному примеру), поэтому становится невероятно сложно пытаться обслуживать все это без какого-либо анализатора / интерпретатора.
2. @Le_Ryan Ваш пример не наводит меня на мысль, что мне нужен DSL для определения ключей. У каждого платежа есть способ оплаты, вы говорите, что метод X сопоставлен с ключом. У каждого платежа есть сумма, вы привязываете 50 долларов к ключу. Пока ничего не требует, кроме простой конфигурации.
3. Теперь я понимаю, к чему вы клоните. Примите этот совет к сведению для дальнейшего использования. Спасибо за ваш вклад!