Exposing properties for binding - java

How should properties be exposed?
For example:
class A{
private ObjectProperty<X> objx;
}
class B{
private ObjectProperty<X> objy;
}
We want to bind objy to objx or add a listener to objx from B. Is it fine to just make a getter for objx? or is there a way to make a wrapper function for binding and expose just this function?

The standard pattern is
class A {
private final ObjectProperty<X> objx = new SimpleObjectProperty<>();
public ObjectProperty<X> objxProperty() {
return objx ;
}
public final X getObjx() {
return objxProperty().get();
}
public final void setObjx(X objx) {
objxProperty().set(objx);
}
}
The idea here is that you have an accessor method for the property itself (a "property accessor": objxProperty()) which can be used for binding and registering listeners, but the property also appears as a regular Java Bean as well: i.e. there are standard get and set methods. The general contract is that you should always have x.getObjx() == x.objxProperty().get(), which is enforced by making the Java Bean accessor methods (getObjx() and setObjx) final.
If you want to be able to modify the property internally, but want to only expose a read only property (to which other code could bind) use a ReadOnlyObjectWrapper:
class A {
private final ReadOnlyObjectWrapper<X> objx = new ReadOnlyObjectWrapper<>();
public ReadOnlyObjectProperty<X> objxProperty() {
return objx.getReadOnlyProperty();
}
public final X getObjx() {
return objxProperty().get();
}
}
Also have a look at this powerpoint presentation which, while old, shows a lot of useful idioms such as lazy- and super-lazy- initialization of the property.

The following structure is used extensively in JavaFX:
class A {
// Private inner property
private ObjectProperty<X> objx;
// Public property accessor method
public final ObjectProperty<X> objxProperty() {
if (objx == null)
objx = new SimpleObjectProperty<X>(DEFAULT_VALUE);
return objx;
}
// Public setter method
public final void setObjx(X val) {
objxProperty().set(val);
}
// Public getter method
public final X getObjx() {return objx == null ? DEFAULT_VALUE : objx.get();}
}
What you can see here is called lazy initialization. The trick is that the private inner property is not initialized until it (really) gets requested.
The public property accessor objxProperty() will initialize the private inner property objx. This property accessor method is used to expose the inner property for binding and listening. The private inner property gets the "Property" suffix, which can be considered as a convention in JavaFX.
The public setter method setObjx uses this property accessor method, therefore in case of the request to set the value of this property, the inner property will be initialized.
It is a bit different in case of the public getter getObjx(), as if the inner property is not initialized yet (no direct access request on the property and no set request before), the default value is returned directly without initializing the inner property, further delaying the initialization routine.
You can see this technique for example in case of alignmentProperty of TextField in JavaFX.
If you don't want to complicate things, the "standard pattern" explained by James_D in his answer is really the standard (the method naming is the same as here).

Related

Kotlin - How can we access private property with getter and setter? Is access methods are calling internally? [duplicate]

This question already has answers here:
Getters and Setters in Kotlin
(8 answers)
Closed 4 years ago.
class Sample1 {
private var test = ""
get() = field
set(value) {
field = value
}}
This is my class. I want to keep the property as private and have to access the property through getter and setter.
var sample1 = Sample1()
I tried to create an object and access the property, but fails.
When I go through the docs, I could found one interesting thing,
"Getters always have the same visibility as the property". link
What's the correct approach with kotlin?
Kotlin groups a field, its getter and its setter (if applicable) into the single concept of a property. When you're accessing a property, you're always calling its getter and setter, just with a simpler syntax, which happens to be the same as for accessing fields in Java. But the actual field backing the property is private, and all calls go through the getters and setters, which have the same visibility as the property itself, in your case, private. So your class would translate to this:
public final class Sample1 {
private String test = "";
private String getTest() { return test; }
private void setTest(String test) { this.test = test; }
}
And your call to Sample1().text would look like this in Java (and you can actually do this from Java code that calls this Kotlin class):
new Sample1().getText();
All that to say is that the solution is to change the visibility of the property to whatever you'd set the getter and setter visibilities to in Java, for example, to the default public visibility:
class Sample1 {
var test = ""
get() = field
set(value) {
field = value
}
}
Note that if you don't have an explicit getter and setter declared, you'll get ones automatically which do the same thing as the implementations above, so you can shorten your code to this:
class Sample1 {
var test = ""
}
This final code is equivalent to this Java class:
public final class Sample1 {
private String test = "";
public String getTest() { return test; }
public void setTest(String test) { this.test = test; }
}

Instantiate public object inside method

I'm trying to instantiate an object inside a method of a class so it can be used anywhere in the class. I come from a python background and it is quite easy, you can just pass the instantiated object to an instance of it's "self" like below.
self.camera = CameraInstance()
How do you do this in Java? I tried something like below but it doesn't like it.
private void init_camera_settings() {
public CameraInterface camera;
camera.TakePhoto()
}
private void someotherMethod() {
camera.TakePhoto()
}
Both methods are in the same class. The reason for this is because I only want to instantiate the camera object only in certain scenarios.
Thanks!
You can't declare a field inside a method. In Java, a type either has a field, or it doesn't. Every instance of the same class has the same set of fields.
But you can declare the field (not in a method) and decide to only assign a value to it in a method:
// Note: avoid public fields
public CameraInterface camera;
private void initCameraSettings() {
camera = new Camera();
}
private void someotherMethod() {
camera.takePhoto();
}
(The field will have a default value, in this case null, until you assign a different value to it.)
As an aside, I'd strongly advise against public fields. I make every field private, and add properties to allow access where necessary. This allows you to change implementation details later. The one exception to this is public static final fields of immutable types, basically for constants, but even there I'd be cautious.
To use the variable throughout the class in different methodsm the variables should have class scope. You usually use new to create a new Object
public MyClass {
public CameraInterface camera = new Camera ();
private void init_camera_settings() {
camera.TakePhoto()
}
private void someotherMethod() {
camera.TakePhoto()
}
}
self.camera = CameraInstance()
is equivalent to:
class Foo {
private CameraInstance camera;
public Foo() {
this.camera = new CameraInstance();
}
// use "this.camera" in methods.
}

What is the Java best practice to initialize a class with many optional data members?

I'm migrating a project from C# to Java.
I have many classes, which have a lot of properties and the user can set any subset of them.
So to initialize the class I provide an empty constructor and the user can initialize any property using the C# initialization list as following:
var a = new MyClass() { Prop1 = "something", Prop2 = 8, Prop15 = new Point(2,3) };
What is the best practice for such a case in Java?
I've seen the following syntax:
MyClass a = new MyClass(){
{
setProp1("Something");
setProp2(8);
setProp15(new Point(2,3));
}
};
However, I understand this is a lot more than a syntactic sugar, it actually creates an anonymous class and places all the methods in the initialization block of the new class.
So I'm not sure that it is the recommended way to initialize such a class.
What is the recommendation for such a case?
You have to create POJO for your class and then initialize it field by using it's setter method.
class MyClass{
Prop1 = null;
Prop2 = null;
// getter and setter method
}
I like to use a definition class.
public class VehicleDef
{
int wheels;
Color color;
Brand brand;
Type type;
int cylinderVolume;
....
}
Now, you can create a constructor that takes this VehicleDef class as an argument:
public class Vehicle
{
// all props here:
public Vehicle (VehicleDef def)
{
// set properties and do stuff
}
}
Now, you can use it like this:
VehicleDef def;
def.wheels = 4;
def.color = Color.RED;
def.brand = Brands.HONDA;
def.type = VehicleTypes.CAR;
def.cylinderVolume = 400;
Vehicle vehicle = new Vehicle(def);
Having an object of an anonymous subclass isn't that bad usually. It only becomes a problem when you use constructs like if (object.getClass() == MyClass.class) but these shouldn't really be necessary when you write proper object-oriented code. Better use if (object instanceof MyClass) which is also true for subclasses of MyClass or even better put any class-specific code into the class itself.
An alternative way to initialize an object with many attributes is to use the Builder pattern.
Create a public class nested inside MyClass which has the purpose to create an instance of MyClass. Because it is nested inside MyClass it can access all the private fields of the instance it is initializing. Using such a builder could look like this:
MyClass a = new MyClass.Builder().setProp1("Something")
.setProp2(8)
.setProp15(new Point(2,3))
.build();
This example uses a builder with a fluent interface: All setters return this which allows you to chain method-calls with a simple . between them.
Without double-brace-initialization:
MyClass a = new MyClass();
a.setProp1("Something");
a.setProp2(8);
a.setProp15(new Point(2,3));
This is the way to go if the number of (mutable) properties is large.
When some properties are immutable (final), adding a specific constructor is necessary.
Any number of additional constructors can be added to pass properties at construction time (if possible, also add a default constuctor with no args):
public class MyClass {
// default constructor
public MyClass() {
}
// convenience constructor
public MyClass(String s, int i, Point p) {
setProp1(s);
setProp2(i);
setProp15(p);
}
}

Exposing instance constants with non-static public final variables

I never see this kind of constants declaration in any Java code around me...
So i'd like to know if you see any drawback of using non-static final constants.
For exemple, i've declared a Guava function as a public constant of a given MaintenanceMode instance. I think it's better because if i created a getDecoratorFunction() it would create a new function instance each time...
Or the get function could return the single instance function that is kept private in the class, but it hads useless code... When we declare constants at class level, we declare directly the constants being public, we do not put them private and provide a public getter to access them...
public class MaintenanceMode {
/**
* Provides a function to decorate a push service with the appropriate decorator
*/
public final Function<PushService,PushService> MAINTENANCE_DECORATION_FUNCTION = new Function<PushService,PushService>() {
#Override
public PushService apply(PushService serviceToDecorate) {
return new PushServiceMaintenanceDecorator(serviceToDecorate,MaintenanceMode.this);
}
};
private final EnumMaintenanceMode maintenanceMode;
private final long milliesBetweenMaintenances;
private final Optional<ExecutorService> executorService;
public EnumMaintenanceMode getMaintenanceMode() {
return maintenanceMode;
}
public long getMilliesBetweenMaintenances() {
return milliesBetweenMaintenances;
}
public Optional<ExecutorService> getExecutorService() {
return executorService;
}
private MaintenanceMode(EnumMaintenanceMode maintenanceMode, long milliesBetweenMaintenances, ExecutorService executorService) {
Preconditions.checkArgument(maintenanceMode != null);
Preconditions.checkArgument(milliesBetweenMaintenances >= 0);
this.maintenanceMode = maintenanceMode;
this.milliesBetweenMaintenances = milliesBetweenMaintenances;
this.executorService = Optional.fromNullable(executorService);
}
}
And i can access this variable with:
pushServiceRegistry.decoratePushServices(maintenanceMode.MAINTENANCE_DECORATION_FUNCTION);
I guess it could lead to strange behaviours if my maintenanceMode was mutable and accessed by multiple threads, but here it's not.
Do you see any drawback of using this kind of code?
Edit: I can have multiple instances of MaintenanceMode, and all instances should be able to provide a different constant function according to the MaintenanceMode state. So i can't use a static variable that would not access the MaintenanceMode state.
The point of a getter would be dynamic dispatch. If you have no need for it, using a public final field is perfectly fine. I even routinely write bean-like objects that have no getters, just public final fields.
By making a constant non-static, you are basically saying that the constant can only be accessed when you have an instance of that class. But it is public (in the case of MAINTENANCE_DECORATION_FUNCTION) and it is part of that class so why not make it static? The constant is, after all, a constant and it does not require an instance of that class to be used elsewhere. The variable maintenanceMode is fine as it is a private constant.

Make sure method is called on all declared and inherited members of some type

I want to apologize for the title, but I didn't know how to summarise this problem.
I've got the following class called AbstractWriter:
public class AbstractWriter {
private boolean changePerformed = false;
// Some Setters
private void changePerformed() {
if (!changePerformed)
changePerformed = true;
}
public boolean isChangePerformed() {
return changePerformed;
}
protected <S> void setValue(
Class<S> type, Object oldValue, Object newValue, Setter setter) {
// Do something
changePerformed();
}
}
Whenever a setter is called, the method setValue(…) is invoked. All setter implement this rule.
Then there's AgeWriter, extended from AbstractWriter:
public class AgeWriter extends AbstractWriter {
// Some Setters
}
And then again, there's HumanWriter:
public class HumanWriter {
// Some setter calls are delegated to this Writer
private AgeWriter ageWriter = new AgeWriter();
// Some Setters
}
When I now invoke the method isChangePerformed() on HumanWriter, I only know if a setter on HumanWriter has been called, but not if one of those delegate setters to AgeWriter.
I'm now looking for a general way to solve this problem. Here are some ways I tried respectively thought about:
Try to find all members of type AbstractWriter with Reflection. But getDeclardFields misses out on inherited ones and getFields on private ones.
Make isChangePerformed() abstract so that every implementation has to make sure it's implemented correct.
Create the abstract method getAbstractWriters that returns all AbstractWriters used inside this type.
What would be your ideas to solve this problem?
If you keep the ageWriter private to HumanWriter, there is no way any external object calls a setter on AgeWriter directly. Use encapsulation, by not providing any accessor to the ageWriter, and use methods on HumanWriter that delegate to the ageWriter.
You could also use an observable/observer pattern (JavaBeans property change listeners) and add the HumanWriter as a listener to the AgeWriter. This way, every property change on the ageWriter will trigger an event that will be sent to the HumanWriter.
My idea may be stupid. But I thing it should work:). You can use the list of writers...
public abstract class AbstractWriter {
private List<AbstractWriter> writers;
//...
private boolean changePerformed = false;
//...
public boolean isChangePerformed() {
for (AbstractWriter writer : writers) {
if(writer.isChangePerformed() && changePerformed) {
return true;
}
}
return false;
}
}

Categories

Resources