I like creating public helpers for private members when creating functions. I made a public helper
public void create(String key, String value) { ... }
for a private member
private void create(String key, String value) { ... }
Now, I am overloading the private member and know I need to do so in Java by
Method signature (type or quantity)
and I am unable to overload by return type. Thus, I decide to modify my private member to accept a boolean argument.
private void create(String key, String value, boolean status) { ... }
I admit this parameter is not one I plan to use or consider. Have I become complacent to accept poor coding behavior?
The public helper merely calls the private member passing supplied arguments
public void create(String key, String value) { create(key, value, true); }
While a helper class might be a quick solution, you are still coupling the implementation to the classes you are exposing (the "caller" class). Interfaces were created to create the abstraction you intend to create (i.e. hiding private implementation from public view) but the added flexibility that:
Could be used by other classes wanting to have their own implementations of similar behaviour
De-couples the implementation from the calling class.
At run-time you could choose which implementation to use (via IoC or similar)
Here's my suggestion:
MyObjectImpl.java -> implements MyObject.java
private Object createObjectNotInitialized( String name ){
return new Object();
}
private Object createObjectInitialized( String name ){
Object newObj = new Object();
newObj.setName( name );
return newObj;
}
public Object createObject( String name, boolean doInit ){
if( doInit ){
return createObjectInitialized(name);
}else{
return createObjectNotInitialized(name);
}
}
// you can chose to init objects by default - I chose not to for this example
public Object createObject( String name ){
return createObjectNotInitialized(name);
}
MyObject.java -> Interface
Object createObject( String name, boolean doInit );
Object createObject( String name );
Caller.java Calling Class
MyObject myObj = new MyObjectImpl();
Object o = myObj.createObject( "Hello" );
Related
In previous C++ code I've used friend classes when creating a factory that can output "read only" objects which means that as the objects are consumed throughout the code there is no risk that they can be inadvertently changed/corrupted.
Is there is there a similar way to implement this in Java or am I being overly defensive?
Make use of the final keyword. This keyword can mark a class/methods as non-extendable, and mark fields/variables as non-mutable.
You will hide the default constructor of the object using the private constructor, and force parameterised constructors which will initialise all necessary final fields.
Your only problem is that the factory is kind of redundant. Since all fields of the object are final, you will have to use all factory methods at object build-time.
Example:
public final class DataObject
{
protected final String name;
protected final String payload;
private DataObject()
{
}
public DataObject(final String name, final String payload)
{
this.name = name;
this.payload = payload;
}
}
// Using the factory
DataObject factory = new Factory().setName("Name").setPayload("Payload").build();
// As opposed to
DataObject dao = new DataObject("Name", "Payload");
// ==> Factory becomes redundant, only adding extra code
Solution without final:
I'm afraid you will have to forget about the immutability mechanism of C++. The factory pattern is never a bad choice if you have huge data objects (i.e. with a lot of setters), but you can't really avoid mutability of the constructed object. What you could do, is make the data object an inner class of the factory, and make the setters private. That way, ONLY the factory can access the setters. This would be the best approach for you (i.e. simulate immutability).
Example:
public class Factory
{
private String name;
private String payload;
public Factory setName(final String name)
{
this.name = name;
}
public Factory setPayload(final String payload)
{
this.payload = payload;
}
public DataObject build()
{
DataObject newObj = new DataObject();
newObj.setName( this.name );
newObj.setPayload( this.payload );
return newObj;
}
public class DataObject
{
// fields and setters, ALL PRIVATE
}
}
You can either put the object class and factory in the same package, and make the mutable methods package-scoped (this is the default visibility in Java, simply don't declare the methods to be public, private or protected), or make the class truly immutable and do all the work in the constructor. If you find that there are too many arguments in the constructor and it is difficult to understand, consider the Builder Pattern.
There is no direct equal to friend classes in Java. However have a look at http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html.
If your object implements an interface and the factory returns interface type rather than the concrete type (which is better) then you can use java.lang.reflect.Proxy to create dynamic proxy at runtime that intercepts all method calls to the target object. As in the following code example FooFactory class creates a Foo instance (every time its createFoo method is called) but does not directly return instance but instead returns a dynamic proxy that implements the same interface as Foo and dynamic proxy intercepts and delegates all method calls to the Foo instance. This mechanism can be helpful to control access to a class when you dont have class code.
public class FooFactory {
public static IF createFoo() {
//Create Foo instance
Foo target = new Foo(); // Implements interface IF
//Create a dynamic proxy that intercepts method calls to the Foo instance
IF fooProxy = (IF) Proxy.newProxyInstance(IF.class.getClassLoader(),
new Class[] { IF.class }, new IFInvocationHandler(target));
return fooProxy;
}
}
class IFInvocationHandler implements InvocationHandler {
private Foo foo;
IFInvocationHandler(Foo foo) {
this.foo = foo;
}
#Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if (method.getName().equals("setMethod")) {
// Block call
throw new IllegalAccessException();
} else {
// Allow call
method.invoke(proxy, args);
}
return null;
}
}
class Foo implements IF {
public void setMethod() {
} // method that is not allowed to call
public void getMethod() {
}
}
interface IF {
void setMethod(); // method that is not allowed to call
void getMethod(); // method that is allowed to call
}
The closest thing to a C++ friend class in Java is package-private access.
SomeObject.java:
package somewhere.someobjandfriends;
public class SomeObject {
Object aField; // field and constructor
SomeObject() {} // are package-only access
public void aMethod() {
System.out.println(this);
}
}
SomeObjFactory.java:
package somewhere.someobjandfriends;
public class SomeObjFactory {
public SomeObject newHelloWorld() {
return new SomeObject() {
{
aField = "hello world!";
}
#Override
public String toString() {
return aField.toString();
}
};
}
}
Anywhere outside of the package can see SomeObject and aMethod but can only create new instances through the factory.
So let say I have such prototyping:
private static Hashtable<String, Furniture> map =
new Hashtable<String, Furniture>();
public My_product() {
loadCache();
}
public My_Product createProduct(String type, String name) {
Furniture cachedproduct = map.get(type);
return (Furniture) cachedproduct.clone();
}
private static void loadCache() {
Sub_product1 pr1 = new Sub_product1(null);
map.put("pr1", pr1);
Sub_product2 pr2 = new Sub_product2(null);
map.put("pr2", pr2);
}
So when I make an instance of an object, I don't know what value will be entered after cloning it (creating object using cloning). So I chosen null value for object instance. But when I clone it then I know what value needs to be assigned for that object. So how could I specify while cloning to put some value instead of null one from object instance?
As you can see in method createProduct method, there is argument called name. I would like that name to be used in cloned object, but how could I do that?
Can you use setter methods?
public My_Product createProduct(String type, String name) {
Furniture cachedproduct = map.get(type);
Furniture clonedProduct = (Furniture) cachedproduct.clone();
clonedProduct.setType(type);
clonedProduct.setName(name);
return clonedProduct;
}
However, I'm still not clear on the whole idea of this cloning of cached objects from the map. Is your product instantiation very expensive? What's the trick?
You cannot pass arguments through the Java built-in clone mechanism. You could provide a setter on the Furniture class to change the name after it has been cloned.
Note that cloning in Java is generally considered broken. It is a brittle way to create objects. Generally you are better of using the factory pattern, e.g. something like:
interface FurnitureBuilder {
Furniture build(String name);
}
class SubProduct1Builder implements FurnitureBuilder {
public Furniture build(String name) { return new SubProduct1(name); }
}
class MyFurnitureFactory {
private final Map<String, FurnitureBuilder> builderByType = ...
// initialization omitted
public Furniture create(String type, String name) {
return builderByType.get(type).build(name); // null check omitted!
}
}
I am trying to implement an interface in Java to use different types of databases for one application.
My though was to create an abstract class with the common interface and two static variables which are then overwritten by the subclasses. I then wanted to add a Class[] List with the classes of all available subclasses to the abstract class as well as a couple of functions that allow the determination of the correct class to be used.
The goal is to first get a list of all available database types and let the user choose one. Afterwards another function should translate the name (which could be localized) to the IDENTIFIER which is specified in the subclass. Finally a third function allows the instantiation of an object by giving such an IDENTIFIER.
My abstract class would look something like this:
public abstract class DataBase {
public static final IDENTIFIER = "";
public static final NAME = "";
private static final Class[] dbTypes = new Class[]{PostgreSQL.class, MySQL.class};
public static String[] getNameList() {
String[] names = new String[dbTypes.length];
for(int i = 0; i < dbTypes.length; i++){
names[i] = dbTypes[i].NAME; //Cannot access the static variable this way.
}
return names;
}
public static String getIdentifierForName(String name) {
for(int i = 0; i < dbTypes.length; i++){
if(name.equals(dbTypes[i].NAME){
return dbTypes[i].IDENTIFIER;
}
}
return "";
}
public static DataBase getInstanceOf(String identifier) {
for(int i = 0; i < dbTypes.length; i++){
if(identifier.equals(dbTypes[i].IDENTIFIER) {
return dbTypes[i].newInstance();
}
}
return null;
}
}
The Child classes would look something like this:
public class MySQL extends DataBase {
public static final IDENTIFIER = "ab.cde.MySQL";
public static final NAME = "MySQL";
...
}
public class PostgreSQL extends DataBase{
public static final IDENTIFIER = "ab.cde.PostgreSQL";
public static final NAME = "PostgreSQL";
...
}
My problem now is, that I cannot access the static variables from the Class object. Obviously the dbTypes list does not contain any typed classes. I tried changing the type of the Array to Class<? extends DataBase>, but I get an error Cannot create a generic array of Class<? extends DataBase> I also tried checking the classes with isAssignableFrom() and then casting the class, but I was still not able to access the static variables.
For now I have two solutions which are working:
Hardcode all existing subclasses into each function if(PostgreSQL.NAME.equals(name)){...}etc.
However, if I add new subclasses, I only want to have to add them at one point in my implementation.
Instead of using a Class[] array, I can use an array of DataBase[] with instances of each class. However, I would think this is bad practice to instantiate each available DataBase subclass, even though I only need one in the end.
Since I have never done such a thing before I might also be approaching the problem completely wrong. Maybe I am missing the correct way in which something like this is usually done?
Thank you for your help.
There are no "abstract properties" in Java. You have to create two astract methods in the DataBase class, like this:
public abstract class DataBase {
// No "abstract propeties"
public abstract String getDBName();
public abstract String getDBIdentifier();
// etc etc...
}
and then, in each subclass:
public class MySQL extends DataBase {
public static final IDENTIFIER = "ab.cde.MySQL";
public static final NAME = "MySQL";
#Override
public String getDBName() {
return NAME;
}
#Override
public String getDBIdentifier() {
return IDENTIFIER;
}
// etc etc...
}
When using the classes, you can just cast to DataBase (not MySQL or PostgreSQL) and call the two abstract methods.
Therefore, in order to solve your "pick a database class" problem, I would create a configuration file that contains the names of the databases and the corresponding class, and instantiate it with reflection (newInstance()) as needed.
As an alternative, you can use reflection to access the static variables like Nikita's answers suggested, or you can just use the name of the class as the identifier of the database it supports, like this (not tested):
public abstract class DataBase {
private static final Class[] dbTypes = new Class[]{PostgreSQL.class, MySQL.class};
public static Class getDBClass(String type) {
for (Class c : dbTypes) {
if (c.getSimpleName().toLowerCase().equals(type.toLowerCase())) {
return c;
}
}
return null;
}
public static Set<String> getSupportedDB() { // <-- you populate a dropdown menu with this
Set<String> supported = new HashSet<String>();
for (Class c : dbTypes) {
supported.add(c.getSimpleName());
}
return supported;
}
// etc etc...
}
However, I don't like this solution and I would not use it.
You can use reflection to get values for each class:
public static String[] getNameList(){
String[] names = new String[dbTypes.length];
for(int i=0; i<dbTypes.length; i++){
Field f = dbTypes[i].getField("NAME");
names[i] = f.get(null);
}
return names;
}
But it might be slow.
Also I'd suggest to create separate enum DBRegistry that will contain names, identifiers and classes:
public enum DBRegistry {
MYSQL("ab.cde.MySQL", "MySQL", MySQL.class),
POSTGRESQL("ab.cde.PostgreSQL", "PostgreSQL", PostgreSQL.class);
private String name;
private String identifier;
private Class<?> dbClass;
private DBRegistry(String identifier, String name, Class<?> dbClass) {
this.identifier = identifier;
this.name = name;
this.dbClass = dbClass;
}
// Getters...
}
You can iterate on all items in registry using DBRegistry.values
Not tested, but I would suggest something like this. You could register databases by calling DataBase.registerDataBase(new DataBase(...))); which may be invoked from the main file.
public class DataBase {
private final static List<DataBase> INSTANCES = new ArrayList<DataBase>();
private final String identifier;
private final String name;
private final Class<?> dbType;
public DataBase(String identifier, String name, Class<?> dbType) {
this.identifier=identifier.toString();
this.name=name.toString();
this.dbType=dbType;
}
String getIdentifier() {return identifier;}
String getName() {return identifier;}
Class<?> getDbType() {return dbtype;}
public synchronized static void registerDatabase(DataBase database) {
database.getClass();
INSTANCES.add(database);
//may check if already registered and either fail or replace it
}
public synchronized static List<DataBase> getNameList() {
return new ArrayList<DataBase>(INSTANCES);
}
public synchronized static List<String> getNameList() {
List<String> names = new ArrayList<String>(INSTANCES.size());
for (Database db:INSTANCES) names.add(db.getName());
return names;
}
public synchronized static String getIdentifierForName(String name) {
for(DataBase db:INSTANCES){
if(name.equals(db.getName())) return db;
}
return null;
}
public synchronized static DataBase getInstanceOf(String identifier) {
for(DataBase db:INSTANCES){
if(identifier.equals(db.getIdentifier())) return db;
}
return null;
}
}
}
I would advise to keep it simple, never more than necessary to utilize in the actual application. It is easier to extend things than to re-factor code to accomodate for additional complexity. Most of the stuff you mention are merely artefacts of your problem solving, not the actual requirements of your application per se. And it so happens, that a modern object-oriented language has everything you need, and you can implement a good design without reflection and without resorting to static properties and string identifiers.
Remember to rely on the compiler rather than runtime for whatever you know in advance - anything that is known not to change from one application run to another, does not need reflection, because it does not involve runtime variables! I would go for interfaces, classes implementing them, and more importantly the Factory pattern to abstract using these classes:
interface Database
{
void query(String sqlString);
}
class MySQLDatabase implements Database
{
public void query(String sqlString)
{
}
}
class PostgreSQLDatabase implements Database
{
public void query(String sqlString)
{
}
}
class DatabaseFactory
{
Database connectDatabase()
{
/// F.e. return new MySQLDatabase();
}
}
The whole "database abstraction layer" has been done to death already anyway, giving birth to DBA, ODBC and other software stacks that solve your problem. You should let yourself be inspired by these, unless you are sure your particular way of solving this yields advantages that can be proven. If you want to go about this in a professional way, of course. If you want to educate yourself, by all means, use reflection, strings in place of more specific objects, and tight-coupling instead of aggressive modularity.
Lets say I have two similar class:
public class First {
public static final String ONE = "1";
public static final String TWO = "2";
public static final String THREE = "3";
}
public class Second {
public static final String ONE = "one";
public static final String TWO = "two";
public static final String THREE = "three";
}
Now in other class Im using one of them:
public class Third {
//....
#Override
public String toString()
{
System.out.println( First.ONE );
}
}
But what I'm trying to do now, is make kind of selector, lets say constructor of class Third gets boolean value and based on it select which class use, but I dont want to make if (..) statement everywhere, cause its simply too much.
So in abstract I'd like this:
public class Third {
//some global var with reference? to static class
public Third(boolean first)
{
if( first ) {
//set class First as source of static fields
} else {
//set class Second
}
}
//....
#Override
public String toString()
{
System.out.println( globalVariableWithReference.ONE );
}
}
Is it possible without making an istance of these class?
You could use an interface with getter methods, then have the two classes implement that interface (and return their respective values when the getter methods are called). Then you can create a map to map between the boolean value and the two implementation classes (via the interface), and call the object that maps to the boolean. Of course, this requires that you create an object of each class, but you would get the same behavior.
Another option is to create a wrapper class that wraps the if/else logic into its own static methods and return the appropriate value from the two classes based on the boolean value. While you will need to write the if/else logic for this wrapper clasee, you do not need to write it more than once, just call the wrapper class's methods
You can use reflection:
Class x = if (first) First.class : Second.class;
String one = (String) x.getField("ONE").get(null);
I am trying to use polymorphism to enable different processing of an object based on its class, as follows:
public class GeneralStuff {
private int ID;
}
public class IntStuff extends GeneralStuff {
private int value;
public void setValue(int v)
{
value = v;
}
public int getValue()
{
return value;
}
}
public class DoubleStuff extends GeneralStuff {
private double value;
public void setValue(double v)
{
value = v;
}
public double getValue()
{
return value;
}
}
public class ProcessStuff {
public String process(GeneralStuff gS)
{
return doProcess(gS);
}
private String doProcess(IntStuff i)
{
return String.format("%d", i.getValue());
}
private String doProcess(DoubleStuff d)
{
return String.format("%f", d.getValue());
}
}
public class Test {
public static void main(String[] args)
{
IntStuff iS = new IntStuff();
DoubleStuff dS = new DoubleStuff();
ProcessStuff pS = new ProcessStuff();
iS.setValue(5);
dS.setValue(23.2);
System.out.println(pS.process(iS));
System.out.println(pS.process(dS));
}
}
This, however, doesn't work, because calling doProcess(gS) expects a method with a signature doProcess(GeneralStuff gS).
I know I could just have two exposed polymorphic process methods in the ProcessStuff class, but the actual situation won't allow it because I'm working within the constraints of an existing library mechanism; this is just a contrived example for testing.
I could, of course, define process(GeneralStuff gS) as
public String process(GeneralStuff gS)
{
if (gS instanceof IntStuff)
{
return doProcess((IntStuff) gS);
}
else if (gS instanceof DoubleStuff)
{
return doProcess((DoubleStuff) gS);
}
return "";
}
which works, but it seems that I shouldn't have to do that (plus, the Programming Police would skewer me for using instanceof in this way).
Is there a way that I can enforce the polymorphic calls in a better way?
Thanks in advance for any help.
The type of dynamic dispatch you are looking for is not possible in Java without using reflection. Java does its linking at compile time based on the declared type (so even though a method is overloaded, the actual method invoked is based on the declared type of the variable not the runtime type).
So you are left with either using instanceof as you propose, using reflection, or putting the process methods in the objects themselves (which is the "oop" way to do it, but is often not suitable or advisable).
One potential alternative is to create a map of processing objects by class, eg:
Map<Class<? extends GeneralStuff>,Processor> processors;
public String process(GeneralStuff stuff)
{
Processor processor = processors.get(stuff.getClass());
if (processor != null)
{
return processor.process(stuff);
}
}
public interface Processor
{
public String process(GeneralStuff stuff);
}
public class IntegerProcessor implements Processor
{
public String process(GeneralStuff stuff)
{
return String.format("%i",((IntegerStuff) stuff).getValue());
}
}
However, for your specific example, String.format takes objects as the parameters, so you could avoid this whole issue by having getValue and getFormatString methods in GeneralStuff which are overriden in the specific subclasses.
You are actually on the right track, you indeed need to use reflection in this case. What you are looking for is sort of double dispatch, because you want the dispatch to be done on the dynamic type of the stuff parameter.
This type of switching-on-dynamic-type is not as rare as you think. See for example this javaworld tipe, which reflects on the visitor pattern
The compiler complains for good reason. There is no guarantee that your GeneralStuff object is an IntStuff or a DoubleStuff. It can be a plain GeneralStuff or any other extension of GeneralStuff, which is a case you also did not cover in your process method with the instanceof (unless returning the empty String was the desired behavior).
Is it not possible to move that process method into the GeneralStuff class and override it in the extensions ?
Another possible solution is to have a sort of composite ProcessStuff class in which you plug a IntStuffProcess, DoubleStuffProcess, ... instance . Each of those instances will still have the instanceof check to decide whether they can handle the GeneralStuff object passed to them, but this is at least more scalable/maintainable then one big instanceof construct
Perhaps, it's better to have overloaded process method in ProcessStuff:
public class ProcessStuff {
private String process(IntStuff i) {
return String.format("%d", i.getValue());
}
private String process(DoubleStuff d) {
return String.format("%f", d.getValue());
}
}
Define an GeneralStuff as an abstract class, with a doProcess method (abstract) which is filled in in the inheriting classes. This way you avoid all problems with instanceof values and such. Or you can do what is suggested by βнɛƨн Ǥʋяʋиɢ, but then you still would have to define an overload for each specific class, whereas in mine you just call it directly.
So my suggestion would be:
public abstract class GeneralStuff {
private int ID;
public abstract String process();
}
public class IntStuff extends GeneralStuff {
private int value;
public void setValue(int v)
{
value = v;
}
public int getValue()
{
return value;
}
#override
public String process(){
return String.format("%d", getValue());
}
}
public class DoubleStuff extends GeneralStuff {
private double value;
public void setValue(double v)
{
value = v;
}
public double getValue()
{
return value;
}
#override
public String process(){
return String.format("%f", getValue());
}
}
public class Test {
public static void main(String[] args)
{
IntStuff iS = new IntStuff();
DoubleStuff dS = new DoubleStuff();
ProcessStuff pS = new ProcessStuff();
iS.setValue(5);
dS.setValue(23.2);
System.out.println(iS.process());
System.out.println(dS.process());
}
}