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...
Related
So, this is my design. AccessDecorator classes have a reference to another Access just like normal Decorator Pattern.
But the problem is when I create an AccessDecorator wrapping a ConcreteAccess and then try to see which type the Access is:
Access access = new InAllowedAccess();
Access wrapperAccess = new MismatchAccess(access);
if (wrapperAccess instanceof InAllowedAccess) //this condition could be used to be a predicate for a filtering over an access list for example
//do something
Of course this won't work because wrapperAccess is not of type InAllowedAccess but what I really want to know is all the types of some Access. In this case, the wrapperAccess would be not only of type MismatchAccess but also of type InAllowedAccess
I thought about implementing methods like isInstanceofInAllowed(), isInstanceofOutAllowed(), isInstanceofInDenied() and isinstanceofOutDenied(), isinstanceofMismatch() in Access classes but don't seems a good solution, I don't know...
Otherwise should I create a big hierarchical tree with MismatchAccesses for each 4 types InAllowedMismatchAccess, OutAllowedMismatchAccess, InDeniedMismatchAccess and OutDeniedMismatchAccess? And then, when I develp another decorator?...
Or is there another better design?
How can I know all the types of an Access? Not only the type of the wrapper access but also the type of the wrapped access.
EDIT:
One of my needs is: filter a collection of Accesses by their type - ÌnAllowedAccess, InDeniedAccess, OutAllowedAccess, OutDeniedAccess, MismatchAccess (which is a decorator) and other types of decorators that I might develop
Avoiding type checking is the usually the best way to do things. Unfortunately you haven't given enough context how you are going to use your classes so that I can give an example on how you can use polymorphism and avoid it.
Adding type checking will limit the ability of your system to grow because as new classes are added, these types need to be included in your type checks. Sometimes this can lead to bugs as your code can make assumptions of the number of classes or their types. Here's an example:
Note: I just made this up for illustrational purpose. It's not about having to represent your logic or anything like that.
public void someMethod(Access access) {
if(access instance of InAccess) {
InAccess inAccess = (InAccess)access;
}
else {
OutAccess outAccess = (OutAccess)access;
}
}
When we started our system had two classes that inherit from Access. Assume that we add another Access class to our system. This code will crash on the else because we may pass the new third access type and the cast won't succeed.
Of course this isn't always the case. Sometimes the number of classes that you have won't grow too much. It's possible that you can predict all types that will have.
And of course, since all things can happen in programming, sometimes you do need to know the types of objects you are using.
Let's assume that your system do need to know the type of objects. Here are two solutions:
Add an enum that will represent all types that you have.
public enum AccessType {
InAccessAllowed,
InAccessDenied,
OutAccessDenied,
// other types
}
public interface Access {
AccessType getType();
// other stuff
}
This way you will use the enum AccessType instead of type casting.
Use interfaces.
Instead of using classes define an interface for each type of Access. Then you will check for the interfaces instead of classes. This way your decorators can implement the same interface as the class it decorates.
public interface InAllowedAccess { }
public class InAllowedAccessImp implements InAllowedAccess { }
public class InAllowedAccessDecorator implements InAllowedAccess { }
I just wan't give an example of an alternative implementations. Since context is lacking in your description, I'll just try to guess how you are going to use your classes and add behavior to them. It's just an idea an nothing more.
Let's assume that your system grant access to users. Users can be given In and Out access and some part of your system need to ask if an access is granted or denied to a specific user so that it can execute a specific logic.
If you don't have any behavior associated with your Access classes you can just use it as a descriptor that will carry the information necessary for other classes to do their jobs.
public enum PortType { In, Out }
public enum Permissions { Allowed, Denied }
public class Access {
private PortType mPortType;
private Permissions mPermissions;
public Access(PortType portType, Permissons permissions) {
mPortType = portType;
mPermissions = permissions;
}
public PortType getType() { return mPortType; }
public Permissions getPermissions() { return mPermissions; }
}
If you do have behavior, then you can use polymorphism. Define the behavior in your Access interface and let classes that impelement this interface define the behavior.
Let's say we have messaging system that a user can receive (In) and send (out) messages. These messages go trough a channel. These channels will either accept or reject messages. Here's a way you can use polymorphism instead of type checking.
public interface MessageChannel {
public bool canSendMessages(); // out
public bool canReceiveMessages(); // in
public void receiveMessage(Message m);
public void sendMessage(Message m);
}
public class InMessageChannel implements MessageChannel {
// out messaging is not allowed, cannot send
public bool canSendMessages() { return false; }
// In messaging allowed, can receive
public bool canReceiveMessages() { return true; }
public void sendMessage(Message m) {
throw new SendingMessagesIsNotAllowd();
}
public void receiveMessage(Message m); {
// do something with the mssage
}
}
public class OutMessageChannel implements MessageChannel {
// out messaging allowed
public bool canSendMessages() { return true; }
// In messaging not allowed
public bool canReceiveMessages() { return false; }
public void sendMessage(Message m) {
// send the message
}
public void receiveMessage(Message m); {
throw new ReceivingMessagesIsNotAllowd();
}
}
As you can see each MessageCahnnel has a behavior accosiated with it. It can either send of receive messages if it's allowed or not. This way other classes that use the MessageChannel won't have to do type casting.
I thought about implementing methods like isInstanceofInAllowed(), isInstanceofOutAllowed(), isInstanceofInDenied() and isinstanceofOutDeniedd() in Access classes but don't seems a good solution, I don't know...
You are right. That’s a bad solution. An interface often belongs to a layer with high level of abstraction in software, thus the list of its methods should be stable. If you put such a bunch of methods like above into the Access interface, the interface would be very unstable since in the future it’s very likely that you will add more such methods to it.
The simplest solution to your problem is adding (only one time) a new method named core() to the Access interface. Every decorator just implements this method by returning the wrapped/core object.
interface Access {
...
Access core();
}
Access a = ...
if (a.core() instanceof ...
Lets say I have a Namespace class like follows:
abstract class Namespace {
protected prefix;
protected Map<String, String> tags;
public setTag(String tagKey, String tagValue) {
tags.put(tagKey, tagValue);
}
}
I have been told that a good design is to have separate implementations of each namespace with getters defining the information being retrieved from the tags map. ie.
class FooNamespace extends Namespace {
public String getNameTag() {
return tags.get("name");
}
}
We can have separate implementations of a namespace like BarNamespace which will have different tags stored (BarNamespace does not have a name tag for ex. and instead has an age tag). Why does the above design make more sense than simply having the consumer of a simple Namespace class request the tag they want. ie:
class Namespace {
private prefix;
private Map<String, String> tags;
public String getTag(String key) {
return tags.get(key);
}
}
The above is used like
Namespace.getTag("name");
The answer depends a lot on what you wish to achieve - but if I have to type getTag("name") a few hundred times, I'm bound to make a mistake.
getNameTag takes out some of the guess work and reduces the possibility that I'll type "name" wrong without noticing. It also reduces the amount of knowledge I need to have about the API - I know I can get the value for the name tag, but I don't need to know how that is actually implemented - and it might change between implementations.
Is it a "good design" is a matter of opinion and is dependent on how the intended class is to be used. Is "name" common enough in the application to be useful? What about "date" or "numeric" values - some helper methods there might be nice ;)
The one thing that bugs me about this is that while Bar does not have an accessor for "name", its backed by an abstract Namespace class that contains a raw Map so anyone can shove in a "name" tag by doing a Bar.putTag("name", "nameValue"); Any ideas on how to implement the "setters"?
This is also a bug-bear I have to the collections API generally.
You could create a non-mutable and mutable concepts...
public interface Namespace {
public String getTag(String key);
}
public interface MutableNamespace extends Namespace {
public void setTag(String key, String value);
}
Then you can begin to abstract those...
public abstract class AbstractNamespace implements MutableNamespace {
private prefix;
private Map<String, String> tags;
public setTag(String tagKey, String tagValue) {
tags.put(tagKey, tagValue);
}
public String getTag(String key) {
return tags.get(key);
}
}
And finally provide useful implementations for the context that it might be used in...
public interface MySuperHelpfulNamespace extends Namespace {
public String getNameTag();
}
public class DefaultMySuperHelpfulNamespace extends AbstractNamespace implements MySuperHelpfulNamespace {
public String getNameTag() {
return tags.get("name");
}
}
Then write you app to support them...
public void someMethodWhichDoesNotNeedToChangeTheValues(MySuperHelpfulNamespace namespace) {
//...
}
public void someMethodWhichDoesNeedToChangeTheValues(MutableNamespace namespace) {
//...
}
This is essentially an example of "coding to interface (not implementation)
The problem stems from..
Your attempt to reuse Namespace via inheritance for it's property: the Map.
The idea behind object orientation is to..
Tell objects to perform behaviors.
What is an Object?
Hiding internal state and requiring all interaction to be performed through an object's methods is known as data encapsulation — a fundamental principle of object-oriented programming.
When ClassA extends ClassB, the subtype ClassA should inherit the behaviors, or the public interface, of it's supertype ClassB. Your Namespace type doesn't seem to define any behaviors.
You may consider the setter or getter to be behaviors,
But don't be fooled. There is currently no reason for a developer to prefer your Namespace type over just using a Map, other than changing the interface they use from get to getTag.
getter & setter methods violate OOP. Feel free to read up on the discussion.
How should Namespace actually be used? What requirement is it fufilling? What behaviors should Namespace define?
You can answer this by analyzing how the getter is being used. To give an example, maybe you plan to append it to a StringBuilder to conjure some XML.
Imagine your requirement was..
Append an individual tag from a variety of XML tag sets to a StringBuilder that'll be used for rendering.
Instead of doing..
StringBuilder builder = ...;
Namespace namespace = ...;
builder.append(namespace.getTag("name"));
Namespace could be responsible for appending it's tags (Namespace is the owner of the Map storing the tags) to whatever is requesting it.
public final class Namespace {
private final Map<String, String> tags;
public Namespace(Map<String, String> tags) {
this.tags = tags;
}
// if you REALLY need to add tags after instantiation
public Namespace addTag(String key, String value) {
Map<String, String> tags = new HashMap<>(this.tags);
tags.put(key, value);
return new Namespace(tags);
}
// the behavior that fufills the requirement
public void appendTo(StringBuilder builder, String key) {
builder.append(tags.get(key));
}
}
Notice how Namespace has behavior (appends to a StringBuilder) rather than act as a proxy for Map.
StringBuilder builder = ...;
Namespace namespace = ...;
namespace.appendTo(builder, "name");
I'm not looking for reasons to create subtypes (not forcing it). You should only create subtypes when you must extend upon the behavior of the supertype. If BarNamespace doesn't add any functionality to Namespace, there's no need for it.
After creating Namespace to cover the functionality your post exposes, I had no need for subtypes. It seemed as if everything was elegantly handled by Namespace.
You didn't specify your requirements, but hopefully this answer will guide you towards determining them (based on how you're using the getter) and implementing them in an object oriented manner.
As #MadProgrammer pointed out:
if I have to type getTag("name") a few hundred times, I'm bound to make a mistake.
If you find yourself needing to type "name" quite often, then you may wanna include a type-safe way for performing that behavior.
In a situation like this, you could prefer composition over inheritance. Instead of having subtypes extend Namespace, you could create types that reference a Namespace to perform what you want to do.
public final class Bar {
private final Namespace namespace;
public Bar(Namespace namespace) {
this.namespace = namespace;
}
public void appendNameTo(StringBuilder builder) {
namespace.appendTo(builder, "name");
}
}
You may say "Wait! I wanna pass Bar to where a Namespace is expected!"
This would be pointless. If code relies on Namespace, there would be no type safety to be expected, even in your code. For example:
void doSomething(Namespace namespace) {
}
Unless you casted or declares appendNameTo to Namespace, you wouldn't have access to any methods defined in Bar anyways. You said subtypes may have different tags. This means if you're going for type safety, your subtypes would all have different public interfaces, hence why I didn't extend Namespace.
I have multiple services (in Spring MVC) that are children of a global Service. So I need to know about the best practice (or your opinions) with multiple methods with this example:
//Domain classes
public class MyParentObject{}
public class MyObj extends MyParentObject{}
//Services
public class MyParentObjectServiceImpl implements MyParentObjectService{
#Override
public MyParentObject findObjectByProp(String prop, String objectType){
//myCode (not abstract class)
}
}
public class MyObjServiceImpl extends MyParentObjectServiceImpl implements MyObjectService{
private myObjType = "MyObj";
#Override
public MyObj findMyObjByProp(String prop){
return (MyObj) super.findObjectByProp(prop, this.myObjType);
}
}
And in this approach, I use calls like this:
MyObj foo = myObjService.findMyObjByProp(prop);
So I need to know if this approach is "better" or more apropiate that calling directly the parent method with the second parameter. E.g:
MyObj foo = (MyObj)myParentObjectService.findObjectByProp(prop, "MyObj");
..and avoiding the creation of second methods, more specific. It is important to know that the children services will be created anyway, because we have lot of code that is specific of a domain objects.
I have the idea that the first approach is better, because is more readable, but I need to support that decision with some documents, blog, or opinions to discuss this designs with my colleagues.
This looks like a tagged class hierarchy. It's difficult to comment on the value of this design in general without knowing the details. However, a slightly different approach that I would recommend is to generify your base class to gain a little bit of type safety.
In particular:
public /* abstract */ class MyParentObjectServiceImpl<T extends MyParentObject>
implements MyParentObjectService{
MyParentObjectServiceImpl(Class<T> type) { this.type = type; }
private final Class<T> type; // subclasses provide this
#Override
public T findObjectByProp(String prop){
//you can use type for object specific stuff
}
}
public class MyObjServiceImpl extends MyParentObjectServiceImpl<MyObj>
// You might not need this interface anymore
// if the only method defined is findMyObjByProp
/* implements MyObjectService */ {
MyObjServiceImpl() {
super(MyObj.class);
}
#Override
public /* final */ MyObj findMyObjByProp(String prop) {
return (MyObj) super.findObjectByProp(prop, this.myObjType);
}
}
You definitely gain in type safety (casting will only appear in the base class), you get rid of the "tags" (the strings that identify the different objects) and possibly reduce the number of classes/interfaces required to implement the whole hierarchy. I successfully used this approach several times. Note that this works best if the base class is abstract. Food for thoughts.
It is more complex than it sounds, but I think I am obliged to try something like it. I want to make an abstract parent class with a prototyping of an enum (I want to declare the enum with only one value probably that will be the default unitialized one and also declaring a couple of methods that I will be using from the subclass), then I want to class that will extend the abstract parent to actually intialize the very same enum (I know that this practically hides the parent enum) so that the kid class will define a set of items inside the enum, but keep the methods probably.
I do not know much about this level of abstraction so I will now describe the nature of my problem, in case there is a more practical solution:
I have a bunch of files that contain classes that implement a lot of commands based on enums. (e.g. class1 implements Observer has an update method that uses an enum-based switch to decide what command was picked, same applies for the other classes) I now want to abstract this whole thing in a way that I have an enum variable with the exact same name in all classes (e.g. CommandSet) so that I can have a generic method inside the parent that will be able to print a help list to my system using the inside methods of the enum. Now I know I can rewrite the exact same method in every class, but I want to abstract it so that others can keep on extending the library I am making!
Hopefully I am not too confusing or too confused and somone can help me! :)
Edit: Here is an idea of the code (Probably not right):
public abstract class Commands{
enum CommandSet{
// empty command, placeholder
null_command ("command name", "command description");
// the Strings used for name and description
private final String name;
private final String description;
// constructor
CommandSet(String name, String description){
this.name=name;
this.description=description;
}
// get parameters
public String getName(){
return name;
}
public String getDescription(){
return description;
}
}
public void showHelp(){
for (CommandSet i : CommandSet.values()) {
printf(i.getName(),":",i.getDescription());
}
}
}
public class StandardCommads extends Commands implements Observer{
// I want to change the enum here, just changing the values so that null_command ("command name", "command description") will get removed and I will add a dozen other values, but keep the methods that the parent had
// update inherited from Observer
#Override
public void update(Observable observable, Object object) {
// I want the commands inside the switch cases defined inside this class's enum
switch(CommandSet.valueOf(String.valueOf(object)){
case command1: doStuff1();break;
case command2: doStuff2();break;
...
case commandN: doStuffN();break;
}
// other methods
void doStuff1(){
...
}
...
void doStuffN(){
...
}
}
public class NonStandardCommads extends Commands implements Observer{
// Another set of commands here for the enum keeping the same methods it had in the parent
// update inherited from Observer
#Override
public void update(Observable observable, Object object) {
// Other set of commands inside this class used in the switch statement
switch(CommandSet.valueOf(String.valueOf(object)){
case Zcommand1: doStuffz1();break;
case Zcommand2: doStuffz2();break;
...
case ZcommandN: doStuffzN();break;
}
// other methods
void doStuffz1(){
...
}
...
void doStuffzN(){
...
}
}
Impossible: Java enums can neither extend another class nor be extended themselves.
They can however implement interfaces. Perhaps you can use that to your advantage.
There is something else about enums that may help you: enums are not immutable. You could change field values of the enums, however that would change them for the whole JVM.
Another approach maybe to pass your subclass instances into a method of the enum and have the enum use your subclass as a call back to get different functionality out of an enum for a different user of the enum.
Nope, you can't do that.
Java Enums run out of gas very quickly & definitely, when you want to add/extend more definitions or instantiate the enum instances, at a later time. (eg load them from database, configure them in an instance method, not just statically.)
Behaviour/ or logic in Java enums is kinda limited too -- you can define & set properties, but only what's statically initializable, and logic seems basic (you end up mainly just comparing references or ordinals, with the other defined enum constants).
What you can do:
You can implement an ancestor Command or AbstractCommand class, with a integer Code, and then subclass it to define concrete values/ additional codes/ load or configure instances, etc.
For further benefit, you get efficient switch & despatch (by Code) plus the ability to define further details/properties, instantiate commands as-needed, etc.
Essentially, this is how you used to define an Enum before Java supported them. Though you may be using them as value objects, rather than strictly static.
My expertise:
I've done extensive compiler & type-system work, tried enums for file-types and associated data/behaviour.. explored the outer limits, and reached the definite boundaries.
I also like being able to instantiate & return a new UnknownFileType("") as an answer, too. Enums can't do that.
Example:
(We'll despatch by String, not int -- since your code appears to be using Java 7. This makes command resolution easier, than requiring both a syntactical "name" and an internal integer "code".)
public static class Command {
protected String code;
protected String desc;
public String getCode() {return code;}
public String getDesc() {return desc;}
public Command (String code, String desc) {
this.code = code;
this.desc = desc;
}
public String toString() {return code;}
}
public class StandardCommands {
public static Command READ = new Command("READ", "read a record");
public static Command CREATE = new Command("WRITE", "create a record");
public static Command EDIT = new Command("WRITE", "modify a record");
}
public class FurtherCommands extends StandardCommands {
public static Command LIST = new Command("LIST", "list all records");
}
public class QueryCommands extends FurtherCommands {
public static class QueryCmd extends Command {
protected String search;
public String getSearch() {return search;}
// constructor..
}
public static QueryCmd QUERY_EXAMPLE = new QueryCmd("QUERY", "example", "query for specified string");
public static QueryCmd createQuery (String search) {
return new QueryCmd( "QUERY", search, "query for specified string");
}
}
I often find I want to do something like this:
class Foo{
public static abstract String getParam();
}
To force a subclasses of Foo to return a parameter.
I know you can't do it and I know why you can't do it but the common alternative of:
class Foo{
public abstract String getParam();
}
Is unsatisfactory because it requires you to have an instance which is not helpful if you just want to know the value of the parameter and instantiating the class is expensive.
I'd be very interested to know of how people get around this without getting into using the "Constant Interface" anti pattern.
EDIT: I'll add some more detail about my specific problem, but this is just the current time when I've wanted to do something like this there are several others from the past.
My subclasses are all data processors and the superclass defines the common code between them which allows them to get the data, parse it and put it where it needs to go.
The processors each require certain parameters which are held in an SQL database. Each processor should be able to provide a list of parameters that it requires and the default values so the configuration database can be validated or initialised to defaults by checking the required parameters for each processor type.
Having it performed in the constructor of the processor is not acceptable because it only needs to be done once per class not once per object instance and should be done at system startup when an instance of each type of class may not yet be needed.
The best you can do here in a static context is something like one of the following:
a. Have a method you specifically look for, but is not part of any contract (and therefore you can't enforce anyone to implement) and look for that at runtime:
public static String getParam() { ... };
try {
Method m = clazz.getDeclaredMethod("getParam");
String param = (String) m.invoke(null);
}
catch (NoSuchMethodException e) {
// handle this error
}
b. Use an annotation, which suffers from the same issue in that you can't force people to put it on their classes.
#Target({TYPE})
#Retention(RUNTIME)
public #interface Param {
String value() default "";
}
#Param("foo")
public class MyClass { ... }
public static String getParam(Class<?> clazz) {
if (clazz.isAnnotationPresent(Param.class)) {
return clazz.getAnnotation(Param.class).value();
}
else {
// what to do if there is no annotation
}
}
I agree - I feel that this is a limitation of Java. Sure, they have made their case about the advantages of not allowing inherited static methods, so I get it, but the fact is I have run into cases where this would be useful. Consider this case:
I have a parent Condition class, and for each of its sub-classes, I want a getName() method that states the class' name. The name of the sub-class will not be the Java's class name, but will be some lower-case text string used for JSON purposes on a web front end. The getName() method will not change per instance, so it is safe to make it static. However, some of the sub-classes of the Condition class will not be allowed to have no-argument constructors - some of them I will need to require that some parameters are defined at instantiation.
I use the Reflections library to get all classes in a package at runtime. Now, I want a list of all the names of each Condition class that is in this package, so I can return it to a web front end for JavaScript parsing. I would go through the effort of just instantiating each class, but as I said, they do not all have no-argument constructors. I have designed the constructors of the sub-classes to throw an IllegalArgumentException if some of the parameters are not correctly defined, so I cannot merely pass in null arguments. This is why I want the getName() method to be static, but required for all sub-classes.
My current workaround is to do the following: In the Condition class (which is abstract), I have defined a method:
public String getName () {
throw new IllegalArugmentException ("Child class did not declare an overridden getName() method using a static getConditionName() method. This must be done in order for the class to be registerred with Condition.getAllConditions()");
}
So in each sub-class, I simply define:
#Override
public String getName () {
return getConditionName ();
}
And then I define a static getConditionName() method for each. This is not quite "forcing" each sub-class to do so, but I do it in a way where if getName() is ever inadvertently called, the programmer is instructed how to fix the problem.
It seems to me you want to solve the wrong problem with the wrong tool. If all subclasses define (can't really say inherit) your static method, you will still be unable to call it painlessly (To call the static method on a class not known at compile time would be via reflection or byte code manipulation).
And if the idea is to have a set of behaviors, why not just use instances that all implement the same interface? An instance with no specific state is cheap in terms of memory and construction time, and if there is no state you can always share one instance (flyweight pattern) for all callers.
If you just need to couple metadata with classes, you can build/use any metadata facility you like, the most basic (by hand) implementation is to use a Map where the class object is the key. If that suits your problem depends on your problem, which you don't really describe in detail.
EDIT: (Structural) Metadata would associate data with classes (thats only one flavor, but probably the more common one). Annotations can be used as very simple metadata facility (annotate the class with a parameter). There are countless other ways (and goals to achieve) to do it, on the complex side are frameworks that provide basically every bit of information designed into an UML model for access at runtime.
But what you describe (processors and parameters in database) is what I christened "set of behaviors". And the argument "parameters need to be loaded once per class" is moot, it completely ignores the idioms that can be used to solve this without needing anything 'static'. Namely, the flyweight pattern (for having only once instance) and lazy initialization (for doing work only once). Combine with factory as needed.
I'm having the same problem over and over again and it's hard for me to understand why Java 8 preferred to implement lambda instead of that.
Anyway, if your subclasses only implement retrieving a few parameters and doing rather simple tasks, you can use enumerations as they are very powerful in Java: you can basically consider it a fixed set of instances of an interface. They can have members, methods, etc. They just can't be instanciated (as they are "pre-instanciated").
public enum Processor {
PROC_IMAGE {
#Override
public String getParam() {
return "image";
}
},
PROC_TEXT {
#Override
public String getParam() {
return "text";
}
}
;
public abstract String getParam();
public boolean doProcessing() {
System.out.println(getParam());
}
}
The nice thing is that you can get all "instances" by calling Processor.values():
for (Processor p : Processorvalues()) {
System.out.println(String.format("Param %s: %s", p.name(), p.getParam()));
p.doProcessing();
}
If the processing is more complex, you can do it in other classes that are instanciated in the enum methods:
#Override
public String getParam() {
return new LookForParam("text").getParam();
}
You can then enrich the enumeration with any new processor you can think of.
The down side is that you can't use it if other people want to create new processors, as it means modifying the source file.
You can use the factory pattern to allow the system to create 'data' instances first, and create 'functional' instances later. The 'data' instances will contain the 'mandatory' getters that you wanted to have static. The 'functional' instances do complex parameter validation and/or expensive construction. Of course the parameter setter in the factory can also so preliminary validation.
public abstract class Processor { /*...*/ }
public interface ProcessorFactory {
String getName(); // The mandatory getter in this example
void setParameter(String parameter, String value);
/** #throws IllegalStateException when parameter validation fails */
Processor construct();
}
public class ProcessorA implements ProcessorFactory {
#Override
public String getName() { return "processor-a"; }
#Override
public void setParameter(String parameter, String value) {
Objects.requireNonNull(parameter, "parameter");
Objects.requireNonNull(value, "value");
switch (parameter) {
case "source": setSource(value); break;
/*...*/
default: throw new IllegalArgumentException("Unknown parameter: " + parameter);
}
}
private void setSource(String value) { /*...*/ }
#Override
public Processor construct() {
return new ProcessorAImpl();
}
// Doesn't have to be an inner class. It's up to you.
private class ProcessorAImpl extends Processor { /*...*/ }
}