Java design pattern to keep a method name in a property file - java

I have property file(key/value) pair from where I currently read a value against a key and display that value as it is in the UI .
The complexity have increased,Now the value is more dynamic based on some formula. The formula includes a variable parameter whose value I will get at run time.
Is there any java design pattern to design this scenario .
I was thinking to put a method name in the property file against a key.
Now I will read the key and fetch the method name . This method will calculate the value for that particular key.
Please let me know your suggestion

Is there any java design pattern to design this scenario .
I don't know if there is a pattern.
If I understand your question right I can explain what I do usually.
Insert localizable strings in my properties values
I usually use #number#
Replace it later when variables are resolved
Little example:
messages.properties
name.of.key = sum of #0# + #1# = #2#
Then I read the value from and replace the #num# with appropiated values (NOTE: here is in the same method for shortenes, but I use an external replace method):
public void printSum(int n1, int n2) {
String myString = messageSource("name.of.key", Locale.getDefault(), null, null));
myString.replace("#0#", String.valueOf(n1));
myString.replace("#1#", String.valueOf(n2));
myString.replace("#2#", String.valueOf(n1+n2));
System.out.println(myString);
}
OUTPUT printSum(1,2);
sum of 1 + 2 = 3

Looks like the ANTLR would make here a great fit.
It is a parser generator. You give it grammar as an input and in return it provides you with a parser.
You can use the parser to transform the textual formula into a parsed tree representation. After that, you can run a visitor to evaluate each of the nodes. You just write some simple function to implement the behavior, such as:
public Double visitAdd(AntlrNode left, AntlrNode right) {
Double left = visit(left);
Double right = viist(right);
return left + right;
}
The grammar is very close to the familiar BNF notation. You just describe how your formula strings are. For example:
formula : left '+' right;
left: Number;
right: Number;
Number: [0-9]+;

Use Java built-in JavaScript engine to evaluate expressions. To match the spirit more closely, you can use JSON for properties.
If security is important, you need to provide the class filter. It can be very simple and restrictive as you only need to evaluate trivial expressions. The example on class filter can be found here.

You can use the strategy pattern putting the method/algorithm name in the property file:
public interface IFormula{
public int formula(int a, int b);
}
public class Sum implements IFormula{
public int formula(int a, int b){
return a+b;
}
}
Then you can select the method getting the name from a property file:
public static Strategy getStrategy(Name name) {
switch (name) {
case SUM:
return new Sum();
...
}
}

Another solution is to refactor your map so that the value type is a functional interface whose method accepts an arbitrary parameter. For example:
#FunctionalInterface
interface ValueType<R> {
R eval(Object param);
}
This solution (or a variant of it) would enable you to associate a lambda with your keys rather than a fixed value. The performance of a lambda ought to be much better than a run-time parser while still affording you the flexibility to make the associated value depend upon a run-time argument.
This solution should also be less vulnerable to injection attacks than a solution based on run-time parsing.

Since you seem to want a name for the pattern... the pattern is called: Domain Specific Language.
And again if you want to remain in the realms of abstract patterns and design you can peruse Martin Fowlers discussion on the topic at length.
Needless to say their are a metric ton of tools that solve the above pattern (including some of the answers here).
The other pattern which I highly recommend you NOT do is use a general purpose language that has an evaluator (ie Javascript, EL, Groovy, etc). This generally has security issues and performance issues (of course there are exceptions).

Related

Is using a class which sole purpose is to group 2 (very much related) objects together considered a good idea?

I can't find any information on this anywhere and was wondering whether such a use of a class is considered bad practise or not.
Let me explain. I have a class ToDecimalConverter which converts an integer from any base to decimal. However, I now need to add the functionality to also convert fractions. As such, I abstracted the integer conversion into a separate class and created a new class with the purpose of converting fractions. (Code isn't finished so I just added some comments to explain)
public class ToDecimalConverter {
private IntegerToDecimalConverter integerConverter;
private DoubleToDecimalConverter doubleConverter;
public double convert(String number, int baseNumber) {
this.integerConverter = new IntegerToDecimalConverter();
this.doubleConverter = new DoubleToDecimalConverter();
number = this.removeZerosAtBeginningOfNumber(number);
// split the number into integer and fraction so they can be used below:
int decimalInt = this.integerConverter.convert(integerNumber, baseNumber);
double decimalDouble = this.doubleConverter.convert(fractioNumber, baseNumber);
// add them together and return them
}
}
Now, except for the methods that remove the zero's from the start of a number and the method that splits the number into integer and fraction (both of which can easily be abstracted into their own class), the ToDecimalConverter class does nothing but group the integer and fraction converters together.
When searching online, I don't see a lot of classes being used like this. Should this be avoided or not? and if so, what are alternatives?
This meant as a more general question, the above is just to explain what I mean.
Edit: Or should I see it as a sort of mini GoF Facade pattern?
There is nothing wrong with it by default, but I would guess that you could achieve the same result with two methods. something like:
public int convertFromInt(String number, int baseNumber) {
int theConvertedInt = 0;
//Really cool convertion
return theConvertedInt;
}
public double convertFromFraction(String number, int baseNumber) {
double theConvertedInt = 0;
//Really cool convertion
return theConvertedInt;
}
Also, keep in mind that a lot of this conversions are already done by Java native classes like BigInteger, BigDecimal, Integer, Decimal, Double, the Math package and so on.
Not going into the specifics of what your class is doing, there indeed value in grouping several or many function/classes together to from a single unified API.
This is called the Facade design pattern.
The intent is that instead of relying on your client to have to know of the various classes/objects you use internally to achieve a feature and to have to look all over the place inside your implementation code is that you put in place a single entry point for given feature/set of feature. It is much better for discoverability & documentation.
Also this way, you ensure to only provide the public API that is only one or a few classes that make the facade while the implementation remains hidden and can change at any time.

Regular expression for finding functions

All C++ functions are of the form
type name ( parameters ) { … }
To identify the regex, I'm using
regex = "...";
pattern = Pattern.compile(regex);
matcher = pattern.matcher(line);
if (matcher.matches())
{
...
}
I can only realistically search for the type name ( part since I am using a line reader and function definitions can be multi-line and I'm not sure of what the regex would be. .*\\b.*\\( was my latest guess, but it doesn't work. Any help would be greatly appreciated.
Unfortunately, there is no general regular expression that can match all function definitions.
The C++ grammar specification allows you to parenthesize the name of any variable as many times as you'd like. For example, you can write
int ((((((a))))));
to declare a variable named a. This means that you can define functions like this:
void whyWouldYouDoThis(int (((((becauseICan)))))) {
/* ... */
}
The problem with this is that it means that function declarations can have arbitrarily-complicated nesting of parentheses. You can prove that, in general, sets of strings that require keeping track of balanced parentheses cannot be matched by regular expressions (formally, that the language of those strings is not regular), and unfortunately this applies here.
This is definitely really contrived, but there are cases where you will see lots of nested parentheses. For example, consider this function:
void thisFunctionTakesACallback(void imACallbackFunction()) {
/* ... */
}
Here, there's an extra layer of parentheses induced by the fact that the function argument is itself of function type. If that function took a callback, you could see something like this:
void thisFunctionTakesACallback(void soDoesThisOne(void imACallbackInACallback())) {
/* ... */
}
If you're looking to find all function declarations, you might be better off using a parser and defining a grammar for what you're looking for, since these patterns are context-free. You could alternatively consider hooking into a compiler front-end (g++ can produce ASTs for you in the GIMPLE or GENERIC framework, for example) and using that to extract what you're looking for. That guarantees you won't miss anything.

Java Based Expression Evaluator

I need an Expression Evaluator that can allow me to evaluate an expression such as follows:
(ItemWeight + PackageWeight) * 2
So, given the following Input:
ItemWeight = new Weight(2.0, LBS);
PackageWeight = new Weight(0.2, LBS);
Output would be: Weight(4.4, LBS)
public class Weight {
private final float value;
private final Unit unit;
public float getValue() { return value; }
public Unit getUnit() { return unit; }
public enum Unit {
LB, KG, GRAMS;
}
}
Similarly, I'd like to add/subtract two Amount objects (where amount is made up of a value and currency symbol).
Note: It is OK in my use case to assume that two values that do not have the same unit cannot be added/subtracted, etc
I read about MVEL, but it didn't seem like MVEL would be able to handle arithmetic expressions involving POJOs. Other options that came to mind are Rhino and Commons EL.
What would be a good library that I can use (and if needed extend) for solving this problem?
Thanks!
Java isn't C++; you can't overload operators.
It might not be quite as visually appealing to do it using a fluent interface, but I would say it's easier than what you're proposing.
This is interesting, because you're going to have to think about more than just EL. The idea is far more general than your Weight class. It's more like QuantityWithUnits. Here are a few of the questions you'll have to answer:
How will you prohibit addition and subtraction operations on objects with differing units?
How will you account for creating new units when you divide and multiply?
Will you allow scalar multiplication and division?
Will you disallow addition of scalars to quantities with units? Or will you silently create new objects with like units behind the scenes?
Will you have other common physics operations like powers?
How will you work with systems of units and conversions?
You may think "I'm too clever for all that; I just want to do something 'simple and practical'", but eventually you'll have to answer all these.

OO strategy to match a set of tokens to an appropriate method / constructor

This question isn't specifically about performing tokenization with regular expressions, but more so about how an appropriate type of object (or appropriate constructor of an object) can be matched to handle the tokens output from a tokenizer.
To explain a bit more, my objective is to parse a text file containing lines of tokens into appropriate objects that describe the data. My parser is in fact already complete, but at present is a mess of switch...case statements and the focus of my question is how I can refactor this using a nice OO approach.
First, here's an example to illustrate what I'm doing overall. Imagine a text file that contains many entries like the following two:
cat 50 100 "abc"
dog 40 "foo" "bar" 90
When parsing those two particular lines of the file, I need to create instances of classes Cat and Dog respectively. In reality there are quite a large number of different object types being described, and sometimes different variations of numbers of arguments, with defaults often being assumed if the values aren't there to explicity state them (which means it's usually appropriate to use the builder pattern when creating the objects, or some classes have several constructors).
The initial tokenization of each line is being done using a Tokenizer class I created that uses groups of regular expressions that match each type of possible token (integer, string, and a few other special token types relevant to this application) along with Pattern and Matcher. The end result from this tokenizer class is that, for each line it parses, it provides back a list of Token objects, where each Token has a .type property (specifying integer, string, etc.) along with primitive value properties.
For each line parsed, I have to:
switch...case on the object type (first token);
switch on the number of arguments and choose an appropriate constructor
for that number of arguments;
Check that each token type is appropriate for the types of arguments needed to construct the object;
Log an error if the quantity or combination of argument types aren't appropriate for the type of object being called for.
The parser I have at the moment has a lot of switch/case or if/else all over the place to handle this and although it works, with a fairly large number of object types it's getting a bit unwieldy.
Can someone suggest an alternative, cleaner and more 'OO' way of pattern matching a list of tokens to an appropriate method call?
The answer was in the question; you want a Strategy, basically a Map where the key would be, e.g., "cat" and the value an instance of:
final class CatCreator implements Creator {
final Argument<Integer> length = intArgument("length");
final Argument<Integer> width = intArgument("width");
final Argument<String> name = stringArgument("length");
public List<Argument<?>> arguments() {
return asList(length, width, name);
}
public Cat create(Map<Argument<?>, String> arguments) {
return new Cat(length.get(arguments), width.get(arguments), name.get(arguments));
}
}
Supporting code that you would reuse between your various object types:
abstract class Argument<T> {
abstract T get(Map<Argument<?>, String> arguments);
private Argument() {
}
static Argument<Integer> intArgument(String name) {
return new Argument<Integer>() {
Integer get(Map<Argument<?>, String> arguments) {
return Integer.parseInt(arguments.get(this));
}
});
}
static Argument<String> stringArgument(String name) {
return new Argument<String>() {
String get(Map<Argument<?>, String> arguments) {
return arguments.get(this);
}
});
}
}
I'm sure someone will post a version that needs less code but uses reflection. Choose either but do bear in mind the extra possibilities for programming mistakes making it past compilation with reflection.
I have done something similar, where I have decoupled my parser from code emitter, which I consider anything else but the parsing itself. What I did, is introduce an interface which the parser uses to invoke methods on whenever it believes it has found a statement or a similar program element. In your case these may well be individual lines you have shown in the example in your question. So whenever you have a line parsed you invoke a method on the interface, an implementation of which will take care of the rest. That way you isolate the program generation from parsing, and both can do well on their own (well, at least the parser, as the program generation will implement an interface the parser will use). Some code to illustrate my line of thinking:
interface CodeGenerator
{
void onParseCat(int a, int b, String c); ///As per your line starting with "cat..."
void onParseDog(int a, String b, String c, int d); /// In same manner
}
class Parser
{
final CodeGenerator cg;
Parser(CodeGenerator cg)
{
this.cg = cg;
}
void parseCat() /// When you already know that the sequence of tokens matches a "cat" line
{
/// ...
cg.onParseCat(/* variable values you have obtained during parsing/tokenizing */);
}
}
This gives you several advantages, one of which being that you do not need a complicated switch logic as you have determined type of statement/expression/element already and invoke the correct method. You can even use something like onParse in CodeGenerator interface, relying on Java method overriding if you want to always use same method. Remember also that you can query methods at runtime with Java, which can aid you further in removing switch logic.
getClass().getMethod("onParse", Integer.class, Integer.class, String.class).invoke(this, catStmt, a, b, c);
Just make note that the above uses Integer class instead of the primitive type int, and that your methods must override based on parameter type and count - if you have two distinct statements using same parameter sequence, the above may fail because there will be at least two methods with the same signature. This is of course a limitation of method overriding in Java (and many other languages).
In any case, you have several methods to achieve what you want. The key to avoid switch is to implement some form of virtual method call, rely on built-in virtual method call facility, or invoke particular methods for particular program element types using static binding.
Of course, you will need at least one switch statement where you determine which method to actually call based on what string your line starts with. It's either that or introducing a Map<String,Method> which gives you a runtime switch facility, where the map will map a string to a proper method you can call invoke (part of Java) on. I prefer to keep switch where there is not substantial amount of cases, and reserve Java Maps for more complicated run-time scenarios.
But since you talk about "fairly large amount of object types", may I suggest you introduce a runtime map and use the Map class indeed. It depends on how complicated your language is, and whether the string that starts your line is a keyword, or a string in a far larger set.

Java replacement for C macros

Recently I refactored the code of a 3rd party hash function from C++ to C. The process was relatively painless, with only a few changes of note. Now I want to write the same function in Java and I came upon a slight issue.
In the C/C++ code there is a C preprocessor macro that takes a few integer variables names as arguments and performs a bunch of bitwise operations with their contents and a few constants. That macro is used in several different places, therefore its presence avoids a fair bit of code duplication.
In Java, however, there is no equivalent for the C preprocessor. There is also no way to affect any basic type passed as an argument to a method - even autoboxing produces immutable objects. Coupled with the fact that Java methods return a single value, I can't seem to find a simple way to rewrite the macro.
Avenues that I considered:
Expand the macro by hand everywhere: It would work, but the code duplication could make things interesting in the long run.
Write a method that returns an array: This would also work, but it would repeatedly result into code like this:
long tmp[] = bitops(k, l, m, x, y, z);
k = tmp[0];
l = tmp[1];
m = tmp[2];
x = tmp[3];
y = tmp[4];
z = tmp[5];
Write a method that takes an array as an argument: This would mean that all variable names would be reduced to array element references - it would be rather hard to keep track of which index corresponds to which variable.
Create a separate class e.g. State with public fields of the appropriate type and use that as an argument to a method: This is my current solution. It allows the method to alter the variables, while still keeping their names. It has the disadvantage, however, that the State class will get more and more complex, as more macros and variables are added, in order to avoid copying values back and forth among different State objects.
How would you rewrite such a C macro in Java? Is there a more appropriate way to deal with this, using the facilities provided by the standard Java 6 Development Kit (i.e. without 3rd party libraries or a separate preprocessor)?
Option 3, create you own MutableInteger wrapper class.
struct MutableInteger{
public MutableInteger(int v) { this.value = value;}
public int value;
}
public void swap3( MutableInteger k, MutableInteger l, MutableInteger m) {
int t = m.value;
m.value = l.value
l.value=k.value;
k.value=t;
}
Create a separate class e.g. State
with public fields of the appropriate
type and use that as an argument to a
method
This, but as an intermediate step. Then continue refactoring - ideally class State should have private fields. Replace the macros with methods to update this state. Then replace all the rest of your code with methods that update the state, until eventually your program looks like:
System.out.println(State(System.in).hexDigest());
Finally, rename State to SHA1 or whatever ;-)

Categories

Resources