I would like to know if there's a way to create objects on the fly or should I say by not using a Class object and its properties. The normal way I'm doing it is this.
ApiHelper apiHelper = new ApiHelper();
User user = new User();
user.Firstname = "FirstName";
apiHelper.send("", user);
I would like to accomplish this on my code snippet:
ApiHelper apiHelper = new ApiHelper();
apiHelper.send("", new { Firstname = "Firstname"});
The second paramter on send() has a data type of Object and this Object is later on converted to json string.
This is a c# example, is there a counterpart of this in java? I kind of think that if I use the first approach when creating objects, I have to a lot of classes just to comply with the objects that I need to build, So I was hoping to if I can do it in java using the 2nd approach.
Technically, that's possible with Java. the syntax would be this:
apiHelper.send("", new Object(){ String firstName = "Firstname"});
However, that's generally pretty useless. What you more likely want to do it create an interface/class to define the methods and fields you want, and pass an instance of that.
Example:
class Data{
String firstname;
public Data(String firstname){
this.firstname=firstname;
}
}
Well, all you really need is a constructor that takes the Firstname as a parameter.
public User(String fName) {
Firstname = fName;
}
Although, capitalizing your members isn't convention in Java as it is in C#; should be
String firstname;
Then you would just do...
apiHelper.send("", new User("Firstname"));
If you can't modify User to add a constructor, what I would use is "double brace initialization," where you can basically run code in a class where that class is instantiated:
ApiHelper apiHelper = new ApiHelper();
apiHelper.send("", new User(){{
Firstname = "Firstname";
}});
Then the line Firstname = "Firstname"; gets executed immediately after instantiation.
Related
I am implementing a log management system and want the types of logs to be extendible. We get a base object parsed from JSON (from Filebeat) such as:
class LogLine {
String message
Date timestamp
String type
String source
}
Given this LogLine object, I want to be able to create different objects, which will also extend this LogLine.
class SomeLog extends LogLine {
int myfield
String username
}
class SomeOtherLog extends LogLine {
Date startTime
Date endTime
String username
String transactionID
}
So, in my current non-ideal implementation:
void parse(String s){
LogLine logLine = .....parseFromString(s)
if ( logline.type.equals('def') ){
SomeLog someLog = new SomeLog.Builder.build(logLine)
} else if ( logline.message.containts('abc') ){
SomeOtherLog someotherLog = new SomeOtherLog.Builder.build(logline)
}
}
However, as you can imagine the builders in subclasses copies the superclass LogLine object, is there anyway I can do that without copying the values as they are already subclasses? Is there a design pattern to achieve this? I would not like to rely on reflection like BeanUtils.copyProperperties
When you create a new object based on another it's a good idea to make a copy of all field. It's a best practice called defensive copying.
Since you parse a string, a defensive copy doesn't needed. Also I suppose you'll want to parse some specific fields from input string like myfield for SomeLog and startDate for SomeOtherLog. You could re-factor object creation like
LogLine result = null;
if (s.contains('type=def') {
result = SomeLog.parse(s);
} else if (trickyRegexp.mathces(s)) {
result = SomeOtherLog.parse(s);
} else {
result = LogLine.parse(s);
}
If you have many subclasses of LogLine then probably you'll want to move creation logic to a LogFactory which manages all the stuff regarding parsing string to specific object.
Introduce a factory interface for creating LogLine objects.
public interface LogLineFactory {
public LogLine createLog(LogLine logLine);
}
and use a Map for the lookup.
private Map<String, LogLineFactory > logLineFactories = new HashMap<>();
{
logLineFactories .put("def", new SomeLogFactory());
logLineFactories .put("abc", new SomeOtherLogFactory());
}
You can then ommit the if else branches using the map looup.
LogLine logLine = parseFromString(s);
LogFactory logFactory = logLineFactories.get(logLine.type);
if(logFactory != null) {
LogLine wrappedLogLine = logFactory.createLog(logLine);
}
Maybe you will need more information to create the LogLines and you have to change the interface.
public interface LogLineFactory {
public LogLine createLog(LogLine logLine, String s);
}
PS: with Java 8 you might want to use method references.
logLineFactories.put("def", SomeLog::new);
logLineFactories.put("abc", SomeOtherLog::new);
I want to allow name and message customisation in both my lexer and parsers. The parser/lexer must be able to select a specific message or name, e.g.:
messageManager.tokenName.eofToken
Here, eofToken would be a String. tokenName would be a set of names for lexer tokens and messageManager would be a structure like { parserMessage, lexerMessage, contextName, tokenName }
However, I want the message customisation very directly constructed. I don't want something like:
TokenName tokenName = new TokenName();
tokenName.eofToken = "end of file";
tokenName.identifier = "identifier";
tokenName.keyword = "keyword";
tokenName.regExpLiteral = "regexp' literal";
// much more...
I want something like:
new TokenName(
"end of file",
"identifier",
"keyword",
...
)
I know we just need to define parameters and assign them to the corresponding variables, but I don't want a huge constructor like the one I had in my previous parser:
public TokenNames(
String booleanLiteral,
String eofToken,
String identifier,
String punctuator,
String keyword,
String numericLiteral,
String nullLiteral,
String regExpLiteral,
String stringLiteral,
String xmlName,
String xmlMarkup,
String xmlPunctuator,
String xmlTagCharacters,
String xmlText
)
{
this.booleanLiteral = booleanLiteral;
this.eofToken = eofToken;
this.identifier = identifier;
this.punctuator = punctuator;
this.keyword = keyword;
this.numericLiteral = numericLiteral;
this.nullLiteral = nullLiteral;
this.regExpLiteral = regExpLiteral;
this.stringLiteral = stringLiteral;
this.xmlName = xmlName;
this.xmlMarkup = xmlMarkup;
this.xmlPunctuator = xmlPunctuator;
this.xmlTagCharacters = xmlTagCharacters;
this.xmlText = xmlText;
}
I believe it's possible with arrays or varargs (more readable). How to?
Define class like this:
public class Token {
private String booleanLiteral;
private String eofToken;
...
public Token withBooleanLiteral(String booleanLiteral) {
this.booleanLiteral = booleanLiteral;
return this;
}
public Token withEofToken(String eofToken) {
this.eofToken = eofToken;
return this;
}
...
}
You'll get
Token token = new Token()
.withBooleanLiteral("something");
Check out Lombok library and #Wither annotation. It does everything for you.
Of course, the builder pattern is the most obvious solution in here (and the correct one).
But I would like to draw your attention to the fact there is a lot of fields that can be encapsulated by their own classes.
The following fields can be collected into an XMLDescription class:
String xmlName;
String xmlMarkup;
String xmlPunctuator;
String xmlTagCharacters;
String xmlText;
The next ones can be grouped by a LiteralDescription class:
String numericLiteral;
String nullLiteral;
String regExpLiteral;
String stringLiteral;
Think the problem over once more: if there is a chance to shorten a number of the fields to 3 (an extreme bound according to good practices), the constructor can be used instead of the builder.
I believe it's possible with arrays or varargs (more readable).
Please, don't do that - it's an error-prone approach. You are coupling an index of the array with a corresponding field. Such code, hard to maintain and document, causes an API user
to read a documentation if any provided,
to poke around in the sources if no provided,
to follow to any API change believing that nothing is changed.
So I have a webproject with Hybris, Spring and so on.
I have some classes, which are autogenerated. Let's say I have one modelclass, which is autogenerated and inherits from another class some methods, to set fields.
When writing Unit-tests, is it useful to start using the Builder pattern? Because the thing is, I don't have a constructor, like Employee(int id, String name) and so on, I only have the inherited methods to set them (setId(int id) and so on).
So when I would write a Builder class for this model for example, I would have the methods .withId(int id) and .withName(String name) and the build()-method, where I would run the setter-methods.
so in the end in my test-class I would have:
EmployeeBuilder eb = new EmployeeBuilder();
Employee emp = eb.withId(123)
.withName("John")
.build();
But since I already have Setter-Methods I normally have:
Employee emp = new Employee();
emp.setId(123);
emp.setName("John");
So is it really worth the effort in this case? Or is there something I have not really understood?
Thanks!
Before I give an answer to your question I would like to explain the builder pattern.
The builder pattern is usually used when you have a lot of overloaded constructors (telescoping constructor anti-pattern). E.g.
public class Employee {
public Employee(String firstName, String lastName){
...
}
public Employee(String firstName, String lastName, Sex sex){
...
}
public Employee(String firstName, String lastName, String salutation) {
...
}
}
In this case client code must decide which constructor to invoke depending on the data it has. If it has a firstName and lastName it must invoke new Employee(firstName, lastName). If it only has a firstName it must invoke Employee(String firstName). So the client code might have a lot of if/then/else. E.g.
Employee employee = null;
if(firstName != null && lastName != null && sex != null){
employee = new Employee(firstName, lastName, sex);
} else if(firstName != null && lastName != null && salutation != null){
employee = new Employee(firstName, lastName, salutation );
} else {
.....
}
The design of the Employee class in this example includes that firstName and lastName are mandatory attributtes of an Employee, because every constructor needs them. The attributes sex and saluation are optional. If the client code decides which constructor to invoke this also means that the decision process is duplicated accross client code. E.g. if a client knows the firstName, lastName, sex and salutation which constructor should it call? Either new Employee(firstName, lastName, sex) or new Employee(firstName, lastName, saluation)?
In order to encapsulate the constructor resolution you might want to use a builder pattern.
public class EmployeeBuilder {
public EmployeeBuilder(String firstName, String lastName){
}
public void setSex(Sex sex){ ... }
public void setSalutation(Salutation salutation){ ... }
public Employee build(){
if(salutation != null){
return new Emplyoee(firstName, lastName, salutation);
} else if(sex != null){
return new Emplyoee(firstName, lastName, sex);
} else {
return new Emplyoee(firstName, lastName);
}
}
}
This makes the client-code much easier to read and the constructor invokation decision is encapsulated. E.g.
EmployeeBuidler employeeBuilder = new EmployeeBuilder(firstName, lastName);
Sex sex = ...;
String salutation = ...;
employeeBuilder.setSex(sex);
employeeBuilder.setSalutation(salutation);
Employee employee = employeeBuilder.build();
Back to your question
So is it really worth the effort in this case?
For your unit tests you might want to create Employee objects with some attributes and the others should be set to default values. In this case I think it is a good idea to use a builder pattern. I would name the builder then e.g. EmployeeDefaultValuesBuilder to make it clear.
You might also want to build Employees based on other employee objects (templates). In this case I would add another constructor to the EmployeeBuilder. E.g.
public EmployeeBuilder(Employee template){
// initialize this builder with the values of the template
}
So it is worth the effort if you encapsulate construction logic or if it increases readability.
Builder pattern is useful for:
Immutable classes, which is not the case here.
When you need to build many of the same things with minor differences. Which is also not the case here.
Writing a "Fluent" API.
When you have a complex object which requires a complex build.
So is it really worth the effort in this case?
Given what you have posted, I'd say no.
Finally the effort involved is tiny when using the right APIs, such as Project Lombok or Google Auto. (Also if you are using a builder to hide a telescoping constructor anti-pattern I think you are abusing the pattern, but hey...)
Builder pattern is useful in two cases:
resulting object is immutable(all fields are final) - builder is
better than constructor with many arguments.
you want to be sure that created object is valid and no inconsistent objects can be created - for example you can throw error from build() method if longitude field was set but latitude was not.
As you demonstrate in your code example, with the builder pattern you only save a couple time writing out your variable name emp, but also have to add a final build() call or similar.
In my book that certainly does not pay off the investment of creating additional builders.
But ...
Maybe you have fields that need to be filled, but that are really not relevant for what you want to test.
Or you want to create multiple instances that only differ in few properties.
Those can be build nicely in a builder, saving lots of lines of code, and what is more important, makes your tests much clearer.
How can I do such a thing?
String N = jTextField0.getText();
MyClass (N) = new Myclass();
Is it even possibe?
Or as my question's explains, how can I just make a method to create a new object of my specified class just with a different name each time I call it.
I really searched everywhere with no luck.
Thanks in Advance
P.S.
I wish you guys can excuse me for not being clear enough, Just to say it as it is, I made a textfield to get the name of someone who wants to make an account, and I made a class named "Customer". and a button named "Add". Now I want every time "Add" is clicked, compiler take what is in my textfield and make an object of the class "Customer" named with what it took from the textfield
It was too hard to read it in comments so I updated my question again, so sorry.
I'm stuck so bad. I suppose my problem is that I didn't "understand" what you did and only tried to copy it. This is what I wrote:
private void AddB0MouseClicked(java.awt.event.MouseEvent evt) {
String name = NameT0.getText();
Customer instance = new Customer(Name);
Customer.customers.add(instance);
and this is my Customer class:
public class Customer{
String name;
public Customer(String name){
this.name = name;
}
public String getName(){
return name;
}
static ArrayList<Customer> customers = new ArrayList<Customer>();
Variable names must be determined at compile time, they are not even part of the generated code. So there is no way to do that.
If you want to be able to give your objects names, you can use
Map<String, MyClass> map = new HashMap<>();
Add objects to the map like this (e.g):
map.put(userInput, new MyClass());
and retrieve objects like this:
MyClass mc = map.get(userInput);
I'm not entirely sure what you mean by...
how can I just make a method to create a new object of my specified
class just with a different name each time I call it
...but if I'm interpreting you correctly, I believe what you're trying to do as make MyClass accept a constructor parameter. You can do:
public class MyClass {
private String name;
public MyClass(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
Then to create a new instance of MyClass, do:
String name = jTextField0.getText();
MyClass instance = new MyClass(name);
instance.getName(); // returns the name it was given
EDIT
Since you've added clarifications in the comments since I first answered this question, I thought I would update the answer to portray more of the functionality that you're looking for.
To keep track of the MyClass instances, you can add them to an ArrayList. ArrayList objects can be instantiated as follows:
ArrayList<MyClass> customers = new ArrayList<MyClass>();
Then for each MyClass instance you wish to add, do the following:
customers.add(instance);
Note that the ArrayList should not be reinstantiated for each instance that you wish to add; you should only instantiate the ArrayList once.
I write a little web API which should it make easy to create URIs. Each resource class should contain a method createURI which takes the needed parameters. This method should use a helper method, populateUriTemplate, in the background to create an URI string. populateUriTemplate needs key value pairs to populate an URI template. In another language like Scala or Python I would use named parameters, but Java doesn't support them. So the question is: How to simulate named parameters in Java?
The straight forward solution would be to create a map:
public String createUri(int id, String name){
Map<String, Object> params = new HashMap<String, Object>();
params.put("id", id);
params.put("name", name);
return populateUriTemplate(params);
}
But I don't like to create a map first and put each parameter to it.
Another idea is to use a static method, param, to create key value pairs:
public String createUri(int id, String name){
return populateUriTemplate(param("id", id), param("name", name));
}
Looks much better to me!
It could be refined a bit to make it more self-explanatory, even if a few more characters are needed:
public String createUri(int id, String name){
return populateUriTemplate(key("id").value(id), key("name").value(name));
}
I've also thought of the builder pattern, but this would force the user of my API to create an explicit builder for each resource class, what would be tedious without a benefit. The type of the parameter is not important, as long as a proper implemented toString method exists.
My favourite is one of the both approaches with the static methods above (param(key, value) or key(k).value(v)). Do you know a better way to simulate named parameters in this case?
For some ideas on the builder pattern, you could see this blog post by Stephan Schmidt.
You also just gave me the idea to do the following, with fluent interfaces, a Callable, and a static method:
createUri().id(5).name("dennetik").call();
Which would require createing a Callable class (CreateUri) with the static method:
public static final CreateUriFluentInterface createUri() {
return FluentInterface.of(new CreateUri(), CreateUriFluentInterface.class);
}
And a fluent interface, like this:
public interface CreateUriFluentInterface {
public CreateUriFluentInterface id(Integer id);
public CreateUriFluentInterface name(String name);
}
Which isn't that much boilerplate code, is it?
(Well, if you tone down that horribly named CreateUriFluentInterface a bit, it isn't.)
(You would probably have CreateUriFluentInterface extend Callable<String>, to be able to reroute the call to Callable#call())
populateUriTemplate("id",id, "name",name);
void populateUriTemplate(Object... nvs){
for(int i=0; i<nvs.length/2; i++)
....
}
Maybe you like this approach:
class Params {
private HashMap<String, Object> allParams = new HashMap<String,Object>();
public Params(ParamEntry...params) {
for( ParamEntry p : params ) {
allParams.put(p.name, p.value);
}
}
public getParam(String name) {
return allParams.get(name);
}
class ParamEntry {
public String name;
public Object value;
}
}
public String createUri(Params.ParamsEntry ... params){
return populateUriTemplate(new Params(params));
}
To call it use
createUri(new Param.ParamEntry("name", valueObject) );
Inside the populateUriTemplate...
just use params.get("name");
Spring MVC does exactly this. As well as being able to bind requests to specific methods in controller classes, you can bind request parameters to method parameters. You can have a look to see how it works, but basically it picks a strategy to map the right request parameter to the right method parameter.
You basically get something like:
public String createUri(#RequestParam int id, #RequestParam String name){
return populateUriTemplate(id, name);
}
This is almost silly and slightly off topic, but using Lombok's #Builder annotation takes this closer to the desired result.
Furthermore if the builder, builder method and build method names are changed to _ they almost disappear:
import static foo.Template._;
class Resource {
String createURI(String id, String name) {
return populateURITemplate(_.id(id).name(name)._());
}
String populateURITemplate(Template t ){
return t.id+"="+t.name;
}
}
#Builder(builderClassName = "_", builderMethodName = "_", buildMethodName = "_" )
class Template {
static _ _ = _();
String id;
String name;
}
Named parameters are not the way:
Named parameters do not make your code any cleaner in this case. I would argue that they make things more complex and error prone in Java because you lose type safety and you lose compiler warnings about identifiers that do not exist.
TypeSafe Immutable Fluent Builders:
I wrote an article on a UrlBuilder implementation earlier this year, it shows a type safe fluent interface that enforces order of construction for mandatory input and allows for optional parts with sane defaults as well.
Now I will be the first to admit that the approach I use is fairly verbose, but it is extremely productive once that initial price is paid. It works with dependency injection and is easily unit testable and most importantly is composable for specialization.
final URL url1 = new UrlBuilder().scheme("http").host("www.google.com").build();
System.out.println("url1 = " + url1);
final URL url2 = new UrlBuilder().scheme("https").userInfo("xkcd", "correcthorsebatterystaple").host("admin.xkcd.com").build();
System.out.println("url2 = " + url2);
Produces:
url1 = http://www.google.com
url2 = https://xkcd:correcthorsebatterystaple#admin.xkcd.com
I am addressing the verbosity of the anonymous inner class implementations of the interfaces with another approach I am experimenting with; type safe implementations of value objects from interfaces using dynamic proxies.
This will do away with the boilerplate value objects and replace them with Map<String,?> but put a dynamically generated type safe immutable Interface wrapper around them.
I encourage you to read about both of these and see how combining them gives you a better solution than named properties ever would.
When I get time to refactor my UrlBuilder with the dynamic proxies I will post another blog post about it as well.
Named Parameters via Guice
If you are dead set on named parameters then I would recommend looking at Guice #Named bindings. You still lose the compile type checks and safety but at least you get some validations from Guice.
public class RealBillingService implements BillingService {
#Inject
public RealBillingService(#Named("Checkout") CreditCardProcessor processor,
TransactionLog transactionLog) {
...
}