When creating a POJO it is bad practice to set any attributes in the constructor without passing them in because of dependency injection.
If you are setting one of the fields to a UUID value is this acceptable to be generated and set on construction? Or should it be passed in through the constructor?
Or is there a general pattern used for this?
I would definitely have a constructor that accepts a UUID for the reasons you already outlined. (And testing.)
However I would also add a static factory method that only accepts the values you really want to set externally in regular code. So something like this:
public class Foo {
private final UUID id;
private final Bar bar;
Foo(UUID id, Bar bar) {
this.id = id;
this.bar = bar;
}
public static Foo create(Bar bar) {
return new Foo(UUID.randomUUID(), bar);
}
}
I specified the constructor as package-private, which is permissive enough for testing (if you happen to need it), and only leaves one publicly visible way to create instances of the class.
Related
I am reading about javafx properties and can't understand why non abstract classes we can use for creating instances of properties (for example SimpleStringProperty) have Simple word in their names. As I know Simple in implementation means basic implementation of something.
Is it supposed that developers should implement their own XXXProperty that must extend XXXPropertyBase in JavaFX?
Let's consider for example SimpleStringProperty.
java.lang.Object
javafx.beans.binding.StringExpression
javafx.beans.property.ReadOnlyStringProperty
javafx.beans.property.StringProperty
javafx.beans.property.StringPropertyBase
javafx.beans.property.SimpleStringProperty
Should we develop our own OurStringProperty that will extend StringPropertyBase?
At the same time in javadoc it is said that javafx.beans.property.StringProperty class provides a full implementation of a Property wrapping a String value. So why do we need this SimpleStringProperty? How to explain it?
Here is a sample how to add a simple Object-based property to your class using the implementations provided by JavaFX (similar classes exist for String and primitive types):
private final ObjectProperty<Foo> foo = new SimpleObjectProperty<>(this,
"foo", null);
public final Foo getFoo() {
return fooProperty().get();
}
public final void setFoo(Foo foo) {
fooProperty().set(foo);
}
public ObjectProperty<Foo> fooProperty() {
return foo;
}
Here is a sample of a read-only property implementation based on some base classes provided by JavaFX:
public class MyClass {
private final ReadOnlyBarProperty bar = new ReadOnlyBarProperty();
public final Bar getBar() {
return barProperty().get();
}
private void setBar(Bar bar) {
this.bar.set(bar);
}
public ReadOnlyObjectProperty<Bar> barProperty() {
return bar;
}
[...]
private class ReadOnlyBarProperty extends ReadOnlyObjectPropertyBase<Bar> {
private Bar bar = null;
#Override
public final Bar get() {
return bar;
}
private void set(Bar newValue) {
if (!Objects.equals(bar, newValue)) {
bar = newValue;
fireValueChangedEvent();
}
}
#Override
public Object getBean() {
return MyClass.this;
}
#Override
public String getName() {
return "bar";
}
}
}
Then there are some rare cases where you want to provide your own property implementation. E.g. I've written a SimpleEventHandlerProperty in Drombler Commons.
I hope these samples cleared things up a bit.
It depends.
There is a fairly common pattern in the standard JavaFX libraries of creating local or anonymous classes that extend one of the "base" classes (ReadOnlyXXXPropertyBase or XXXPropertyBase). In my experience, this is done usually for one of two reasons:
It's a read-only property whose value is managed from outside the property.
Something must happen internally when the property is invalidated.
To see an example of the first case take a look at the source code of ListPropertyBase. This property class has two properties of its own, empty and size, inherited from ListExpression. These properties, as expected, reflect the empty and size states of the contained ObservableList. The way these properties are implemented are as local classes but their values are managed by the ObservableList itself. The ListPropertyBase class simply has them fire change events when appropriate.
For the second case, the local or anonymous class will override the protected invalidated method provided by most (all?) of the XXXPropertyBase classes. This method is called when the property is invalidated. It allows one to react without the overhead of a listener. You can see this in action by looking at the source code of ButtonBase. For example, the onAction property:
public final ObjectProperty<EventHandler<ActionEvent>> onActionProperty() { return onAction; }
public final void setOnAction(EventHandler<ActionEvent> value) { onActionProperty().set(value); }
public final EventHandler<ActionEvent> getOnAction() { return onActionProperty().get(); }
private ObjectProperty<EventHandler<ActionEvent>> onAction = new ObjectPropertyBase<EventHandler<ActionEvent>>() {
#Override protected void invalidated() {
setEventHandler(ActionEvent.ACTION, get());
}
#Override
public Object getBean() {
return ButtonBase.this;
}
#Override
public String getName() {
return "onAction";
}
};
When the property is invalidated, the invalidated method registers/unregisters the EventHandler from the Node.
With all that said, if you don't need to add customized behavior stick to using ReadOnlyXXXWrapper for read-only properties and SimpleXXXProperty for read-write properties.
Simple?
Why do the concrete implementations have Simple in their name? Why not just have XXXProperty be the concrete implementation?
I can't give a definitive answer, as I wasn't involved in development, but I can offer a guess: The JavaFX developers wanted to provide multiple "extension points" that offer various degrees of "already implemented". Need full customization? Extend XXXProperty. Need some customization? Extend XXXPropertyBase. And so on.
And the SimpleXXXProperty classes needed names that didn't conflict with the XXXProperty class names. Simple fits because that's what they are—simple implementations. They do nothing but what the interfaces require.
Worth Mentioning
On an API level, virtually every JavaFX class exposes properties as either ReadOnlyXXXProperty or XXXProperty. Never is it Property<SomeObject> or SimpleXXXProperty. Basically, when it comes to properties, consider using ReadOnlyXXXProperty and XXXProperty as "programming to the interface". Just like you'd expose List instead of ArrayList.
I'd also consider that quote:
This class provides a full implementation of a Property wrapping a String value.
To be misleading. If you look at the source of StringProperty is is certainly not a "full implementation". Maybe it's trying to say its the API level class? Maybe it's trying to say it implements all the necessary interfaces? Honestly, I have no idea...
Suppose I have a class com.example.Foo and another class com.sample.Bar which needs to know the fully-qualified name of Foo. If I am a Java novice I might put:
public class Bar {
private String fooName = "com.example.Foo";
//...
}
However, if I refactored Foo to change the name or package, the changes would not be reflected in Bar, unless the IDE is really clever. So it's better to do something like this:
import com.example.Foo;
public class Bar {
private String fooName = Foo.class.getName();
// ...
}
This way, if I refactor Foo, then the change should be picked up by Bar.
Now consider methods. If I have a method name in class Foo and the name needs to be known by Bar, it seems the best I can do is:
public class Bar {
private String bazName = Foo.class.getMethod("bazMethod", Qux.class);
// ...
}
But I haven't actually achieved anything - I still have a string literal "bazMethod" which won't be refactored if the real bazMethod gets renamed.
What I really want to do is something like:
public class Bar {
private String bazName = tellMeTheMethodName((new Foo()).bazMethod(null));
// ...
}
Not sure if this is possible somehow and if there is any way around it.
Now comes the real problem - even if you can sort that out as above, the real thing I am trying to access is an annotation attribute/element name. But annotations are abstract and cannot even be instantiated. So is this possible?
Annotation is just an interface, which you can subclass too! :) For example, annotation
public #interface SomeAnno
{
String attr1();
int attr2();
}
And you want a "statically typed" way to reference names "attr1", "attr2".
This can be done through some elaborate conspiracies among some methods.
String n1 = name( SomeAnno::attr1 );
class MyAnno implements SomeAnno
{
String attr1(){ ... }
MyAnno.attr1()/attr2()/... each triggers a distinct side effect; name(action) compares the side effect of the action, and matches it to one of the attr.
We can generalize this trick to write a universal util that works on any annotation type (actually, any interface type).
SomeAnno anno = proxy(SomeAnno.class);
String n1 = name( anno::attr1 );
But this is really not worth it:) You can just hardcode the name, and do a runtime check (as early as possible) to assert that the name is indeed valid.
I have a scenario where some of the final variables declared at class level are optional in some cases.
That means I have different constructors. Some of those have to leave the member variables with null values.
Since I have declared the variable as final, I am forced to initialize those in the constructor. So I have to add var = null; statement in the constructor.
But explicitly assigning variables to null is considered to be a bad practice and tools like PMD, reports it as a violation. (Controversial rule in PMD. But do not want to switch it off, since I do not want the null assignment to be practiced in other areas of my code)
Any other suggessions or good practices to achieve this?
You can use constructor chaining, passing null to the values that are not used in your instance. (You can either use the super constructor if we are discussing inheritance, or a different constructor in the same class.)
After all I would reconsider the design of your classes, for example extract the optional part to a different class.
Instance variables are assigned default values(null in case of custom object).
So unless you are really assigning some value to your final variables why bother about null assignments?
As user has pointed out in the comment above does not stand good for final variables. So what can be done define a no-arg constructor with all final values set to null.
Now in individual arg constructors place a call to this default constructor by using this() as the 1st statement .. then you can assign values depending on the arguments passed.
What you are looking for is the builder pattern.
Say you have a class with a constructor that accepts all the values:
class Job {
private final Integer id;
private final String name;
private final Boolean retry;
public class Job(Integer id, String name, Boolean retry) {
this.id = id;
this.name = name;
this.retry = retry;
}
}
Now, you want to let other create different flavors of that object while keeping it immutable, removing the default value logic from it and keeping it clean. You create a new builder class:
class JobBuilder {
// Values the user MUST provide are non-initialized and
// declared as final
private final Integer id;
// Values the user MAY provide are initialized with default values
// and are not final
private String name = "[none]";
private Boolean retry = true;
public class JobBuilder(Integer id) {
this.id = id;
}
public JobBuilder name(String name) {
this.name = name;
}
public JobBuilder retry(Boolean retry) {
this.retry = retry;
}
public Job build() {
return new Job(this.id, this.name, this.retry);
}
}
Now, you can create different job objects easily while enforcing the requirements:
Job job1 = JobBuilder(1).name("firstJob").retry(false).build();
Job job2 = JobBuilder(2).name("secondJob").build();
Job job3 = JobBuilder(3).build();
In my one class I have many constructors like this..
public MyData(int position,String songName,String duration, boolean e) {
//initialization of above variable like int, string,string and boolean
}
public MyData(String songName, String artistName, String duration,String downloadPath, String songSize, String albumName,String url,String trackId, boolean e)
{
//initialization of above variable like String,String,String,String,String,String,String,String and boolean
}
and some more like above.
Now the calling time, I'm calling that constructor only that I require data. but I don't think my flow is good so I need some help to reduce my code as well as creation of good flow.
If anybody have a good flow to achieve this, then please share.
Thanks in advance.
Assuming you're effectively applying defaults, usually the best approach is to have one "full" constructor and make the others call it. For example:
public Foo(String name)
{
// Default the description to null
this(name, null);
}
public Foo(String name, String description)
{
this.name = name;
this.description = description;
}
You still end up with quite a lot of cruft in terms of overloaded constructors, but at least each of those "extra" constructors contains no actual code - just a call to another constructor. If possible, chain the constructors together so that the default for any particular value is only specified in one place - or use a constant. That way you get consistency.
Another option is to use a "parameter object" following the builder pattern - create another class whose sole purpose is to hold the data for the constructor parameters. This should be mutable, with setters for all of the different values. Often it's useful to make the setters return the builder, so you can use:
FooParameters parameters = new FooParameters()
.setName("some name")
.setDescription("some description");
// Either a constructor call at the end, or give FooParameters
// a build() or create() method
Foo foo = new Foo(parameters);
This is particularly useful if the main type you're constructing is an immutable type - it means you can apply conditional logic in the calling code to set some parameters but not others. The Java framework itself uses this approach in ProcessBuilder, although personally I'm not keen on the way it overloads method names to either return a value or set a value based on whether you provide an argument :(
Note the comment above the constructor call in the final snippet - if your helper class is only ever helpful for creating objects of a single type, you can give it an extra method (build, create, start, whatever is most appropriate) to take the place of the constructor call. This allows you to build the whole final object in a fluent way.
One option in the Java implementation of the builder pattern is to use a nested type, e.g.
Foo foo = new Foo.Builder().setName(...).setDescription(...).build();
That avoids polluting your package with another class which is only useful for building instances of Foo.
You may want to have another object that is responsible for creating the object through the builder pattern. For example, you could define an object like this:
public class SongBuilder {
private String artistName;
private String songTitle;
/* ... everything else ... */
public SongBuilder setArtistName(String name) {
this.artistName = name;
return this;
}
public SongBuilder setSongTitle(String title) {
this.songTitle = title;
return this;
}
/* ... everything else ... */
public Song create() {
return new Song(artistName, songTitle, /* ... everything else ... */);
}
}
You could then define a single constructor for Song that takes in all the data. To make a Song, you could then write
Song s = new SongBuilder().setSongTitle("Still Alive").setArtistName("GLaDOS").create();
The advantage of this approach is that you can set a reasonable default for all the parameters, then just call the appropriate set functions for parameters that you actually use. It also allows you to add new parameters easily without having to go back and rewrite important code.
Alternatively, as Jon Skeet points out, you can have multiple constructors that all call one another. The advantage of the builder pattern over this approach is that if you have n different parameters, there are 2n combinations of constructors you'd need to write, whereas you only need one builder.
Hope this helps!
First of all I should probably say that the term 'constant object' is probably not quite right and might already mean something completely different from what I am thinking of, but it is the best term I can think of to describe what I am talking about.
So basically I am designing an application and I have come across something that seems like there is probably an existing design pattern for but I don't know what it is or what to search for, so I am going to describe what it is I am trying to do and I am looking for suggestions as to the best way to implement it.
Lets say you have a class:
public class MyClass {
private String name;
private String description;
private int value;
public MyClass(String name, String description, int value) {
this.name = name;
this.description = description;
this.value = value;
}
// And I guess some getters and setters here.
}
Now lets say that you know in advance that there will only ever be say 3 instances of this class, and the data is also known in advance (or at least will be read from a file at runtime, and the exact filename is known in advance). Basically what I am getting at is that the data is not going to be changed during runtime (once it has been set).
At first I thought that I should declare some static constants somewhere, e.g.
public static final String INSTANCE_1_DATA_FILE = "path/to/instance1/file";
public static final String INSTANCE_2_DATA_FILE = "path/to/instance2/file";
public static final String INSTANCE_3_DATA_FILE = "path/to/instance3/file";
public static final MyClass INSTANCE_1 = new MyClass(getNameFromFile(INSTANCE_1_DATA_FILE), getDescriptionFromFile(INSTANCE_1_DATA_FILE), getValueFromFile(INSTANCE_1_DATA_FILE));
public static final MyClass INSTANCE_2 = new MyClass(getNameFromFile(INSTANCE_2_DATA_FILE), getDescriptionFromFile(INSTANCE_2_DATA_FILE), getValueFromFile(INSTANCE_2_DATA_FILE));
public static final MyClass INSTANCE_3 = new MyClass(getNameFromFile(INSTANCE_3_DATA_FILE), getDescriptionFromFile(INSTANCE_3_DATA_FILE), getValueFromFile(INSTANCE_3_DATA_FILE));
Obvisouly now, whenever I want to use one of the 3 instances I can just refer directly to the constants.
But I started thinking that there might be a cleaner way to handle this and the next thing I thought about was doing something like:
public MyClassInstance1 extends MyClass {
private static final String FILE_NAME = "path/to/instance1/file";
public String getName() {
if (name == null) {
name = getNameFromFile(FILE_NAME);
}
return name;
}
// etc.
}
Now whenever I want to use the instances of MyClass I can just use the one I want e.g.
private MyClass myInstance = new MyClassInstance2();
Or probably even better would be to make them singletons and just do:
private MyClass myInstance = MyClassInstance3.getInstance();
But I can't help but think that this is also not the right way to handle this situation. Am I overthinking the problem? Should I just have a switch statement somewhere e.g.
public class MyClass {
public enum Instance { ONE, TWO, THREE }
public static String getName(Instance instance) {
switch(instance) {
case ONE:
return getNameFromFile(INSTANCE_1_DATA_FILE);
break;
case TWO:
etc.
}
}
}
Can anyone tell me the best way to implement this? Note that I have written the sample code in Java because that is my strongest language, but I will probably be implementing the application in C++, so at the moment I am more looking for language independent design patterns (or just for someone to tell me to go with one of the simple solutions I have already mentioned).
If you want the values to be constant, then you will not need setters, otherwise code can simply change the values in your constants, making them not very constant. In C++, you can just declare the instances const, although I'd still get rid of the setters, since someone could always cast away the const.
The pattern looks ok, although the fact that you are creating a new instance each time one is requested, is not usual for constants.
In java, you can create enums that are "smart" e.g.
public enum MyClass {
ONE(INSTANCE_1_DATA_FILE),
TWO(INSTANCE_2_DATA_FILE),
//etc...
private MyClass(String dataFile)
{
this(getNameFromDataFile(dataFile), other values...)
}
private MyClass(String name, String data, etc...)
{
this.name = name;
// etc..
}
public String getName()
{
return name;
}
}
In C++, you would create your MyClass, with a private constructor that takes the filename and whatever else it needs to initialize, and create static const members in MyClass for each instance, with the values assigned a new instance of MyClass created using the private constructor.
EDIT: But now I see the scenario I don't think this is a good idea having static values. If the types of ActivityLevel are fundamental to your application, then you can enumerate the different type of activity level as constants, e.g. a java or string enum, but they are just placeholders. The actual ActivityDescription instances should come from a data access layer or provider of some kind.
e.g.
enum ActivityLevel { LOW, MED, HIGH }
class ActivityDescription
{
String name;
String otherDetails;
String description; // etc..
// perhaps also
// ActivityLevel activityLevel;
// constructor and getters
// this is an immutable value object
}
interface ActivityDescriptionProvider
{
ActivityDescription getDescription(ActivityLevel activityLevel);
}
You can implement the provider using statics if you want, or an enum of ActivityDescription instnaces, or better still a Map of ActivityLevel to ActivityDescription that you load from a file, fetch from spring config etc. The main point is that using an interface to fetch the actual description for a given ActivityLevel decouples your application code from the mechanics of how those descriptions are produced in the system. It also makes it possible to mock the implementation of the interface when testing the UI. You can stress the UI with a mock implementation in ways that is not possible with a fixed static data set.
Now lets say that you know in advance that there will only ever be say 3 instances of this class, and the data is also known in advance (or at least will be read from a file at runtime, and the exact filename is known in advance). Basically what I am getting at is that the data is not going to be changed during runtime (once it has been set).
I'd use an enum. And then rather in this flavor:
public enum MyEnum {
ONE("path/to/instance1/file"),
TWO("path/to/instance2/file"),
THREE("path/to/instance3/file");
private String name;
private MyEnum(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
Which can be used as follows:
MyEnum one = MyEnum.ONE;
String name = one.getName();
(I'm too slow once again, you already accepted an answer, but here it is anyway...)
You want to (a) prevent changes to the data held in objects of MyClass, and (b) allow only a fixed set of MyClass objects to exist, implying that runtime code should not be able to create new instances of MyClass.
Your initial example has a public constructor, which violates (b)
I'd use a Factory approach so the Factory is the only thing that can create instances, and the class doesn't provide any setters so it's immutable.
Depending on how much flexibility you want for the future, you could put the factory and the class in the same package and limit scope that way, or you could make MyClass an inner class within the factory. You may also consider making MyClass an interface separate from its implementation.
A properties file could be used to configure the factory itself.
The properties file (e.g. "foo.properties") could look something like
one=/path/to/datafile1
two=/another/path/to/datafile2
three=/path/to/datafile3
I use "Foo" instead of "MyClass" in the (Java) examples below.
public class FooFactory
{
/** A place to hold the only existing instances of the class */
private final Map<String, Foo> instances = new HashMap<String, Foo>();
/** Creates a factory to manufacture Foo objects */
// I'm using 'configFile' as the name of a properties file,
// but this could use a Properties object, or a File object.
public FooFactory(String configfile)
{
Properties p = new Properties();
InputStream in = this.getClass().getResourceAsStream();
p.load(in); // ignoring the fact that IOExceptions can be thrown
// Create all the objects as specified in the factory properties
for (String key : p.keys())
{
String datafile = p.getProperty(key);
Foo obj = new Foo(datafile);
instances.put(key, obj);
}
}
public Foo getFoo(String which)
{
return instances.get(which);
}
/** The objects handed out by the factory - your "MyClass" */
public class Foo
{
private String name;
private String description;
private int value;
private Foo(String datafile)
{
// read the datafile to set name, description, and value
}
}
}
You're set to allow only your predefined instances, which can't be changed at runtime, but you can set it all up differently for another run at a later time.
Your first method seems to me like the best and the least prone to code rot. I'm not impressed by the idea of subclassing an object just to change the file name that contains the data that will be used to build it.
Of course, you could maybe improve on your original idea by wrapping these all in an outer class that provides some sort of enumeration access. A collection of MyClass's in other words. But I think you should discard this subclassing idea.
First, you really should be limiting where you use these instances in the code. Use them in as few places as possible. Given these are file names, I expect you want three class instances which accesses the files. How many classes are required depends on what your want to do with them? Look at the Singleton pattern for these classes.
Now you don't need the constants, but could have a helper class which will read the file containing the file names and supply them to the reader class. The code to find then name could also be a method called by the static initializer of the Singleton.
The common approach is to use a map:
private static final Map<String, YouClass> mapIt =
new HashMap<String, YouClass>(){{
put("one", new YourClass("/name", "desc", 1 )),
put("two", new YourClass("/name/two", "desc2", 2 )),
put("three", new YourClass("/name/three", "desc", 3 ))
}}
public static YourClass getInstance( String named ) {
return mapIt.get( named );
}
Next time you need it:
YouClass toUse = YourClass.getInstance("one");
Probably using strings as keys is not the best option but you get the idea.