All methods in one class or polymorphism implementation? - java

Here is what you need to know to understand the question:
I want to connect a class called SCL to a class called Region.
Now I have many different ways I want to connect a instance of
these 2 classes.
Writing this is Java
There are no global variables in use
So I can either create several classes(about 9) that utilizes polymorphism but then each class has only one method called connect(...) with many different parameter lists. I think this is called a functor class.
For example a class "SCLToRegionOverlapCircleConnect" will have a connect method that looks like
public void connect(SCL scl, Region region, int radius, int overlapPercentage) {...}
while a class "RegionToRegionNonOverlapSquareConnect" will have a connect method that looks like
public void connect(Region bottomRegion, Region topRegion, int sideLength) {...}
OR
I can just make one class called ConnectionTypes and just have 9 different methods each with a different method signature.
What are the PROs and CONs of each implementation? Thanks!

If you use polymorphism, then you're determining the connection method when you instantiate the SCL object. Does that make sense? Or could an SCL class be connected to the Region in various different ways thoughout its life? In that case, polymorphism doesn't make sense. One important aspect that we have no information about is what happens to the parameters of the connect(...) method. Do they need to be stored in the SCL class, in which case with different parameters polymorphism might again make sense so that each class can store the appropriate parameters.
Another thought is, is the act of connecting an SCL class to a region really a method for the SCL class at all, or should it live somewhere else?

I suggest you to use the second.
less classes, so the project is clarelier than in the other way.
you don't need to move 9 classes when you want to use your
methods in another project (ex.), but only one class.
while programming, one rule is not to duplicate the code; using 9 classes,
you have to write 9 times the declaration, and maybe to declare 9
times the same global variables, using a lot more memory than using
one.
overloading, that means that if you have to make one thing
but in multiple ways (ex. you have to print some objects, and the
result will be one string, but you need to write it different for
one type of object, etc., you can use this technique) you can write
9 methods with the same name, same output, but different inputs.
inheritance: if you want to make a class that inherits those
methods, you MUST use only one class, because java does not support
multiple inheritance.
I can't see any CONs, except that you have to reinitialize the global variables to avoid problems.

Let me put two things straight:
You are thinking of the Command pattern, not the Functor pattern. The difference is that the latter also has a method to retrieve the return value, but your connect method is void.
The Functor pattern would not have a different signature for each of your connect methods; instead, each concrete class would have dedicated setters for the parameters (specific to the particular way you want to connect) and the same, parameterless public void connect() method. The latter would be the only method declared in the common Connect supertype.
I can throw in some example code if you want.
Pro: if it makes sense anywhere in your code to work with Connect commands without needing to know which of the 9 ways you're dealing with, then the Command pattern is your friend.
Con: you will have more code, and encapsulating pure functionality can reduce the understandability of your code quite a bit.

Related

Only one class can instantiate all other clases

What is best practice to restrict instantiation of the classes to only one class? Something like this but in Java.
Let's say there is Main class, then there are User, Admin, View, Data, Client etc. classes. Only 'Main' class should be able to instantiate all other classes.
So if 'User' need to call 'getUser' method in 'Data' class, it can't instantiate 'Data' class and call method, but it has to call 'Main' class, and then 'Main' will instantiate 'Data' class and pass arguments to its 'getUser' method.
What I am thinking is using private constructor, Factory Pattern etc., but not sure if this will result in what I need. Due to the complexity I don't think inner classes would be good solution.
Any advice on this?
A distinct answer on the conceptual level (as there are already good answers on the technical "how to do it"):
Let's say there is Main class, then there are User, Admin, View, Data, Client etc. classes. Only 'Main' class should be able to instantiate all other classes.
I don't think this is a good starting point. Of course, when one follows Domain Driven Design, using factories is well established.
But there is one subtle point to add: you still want to cut your "boundaries" in reasonable ways. Meaning: don't force all objects into a single factory. Your objects should somehow resemble their domains, and be separated where needed.
Meaning: using factories is fine, but don't force yourself into the wrong corner by enforcing that there is exactly one factory that is supposed to handle all kinds of objects you deal with. Instead: try to reasonably partition your object model, and have as many factories as it makes conceptually sense to have.
Also note that you probably should distinguish between objects that mainly provide data/information, and "behavior" on the end. Thus it might be worth looking into the idea of having a service registry (for example what you do with the netflix Eureka framework, see here).
And finally, to quote an excellent comment given by tucuxi here: For small applications, factories are over-engineering. For larger applications, I find it questionable to have a single factory called "Main", instead of splitting responsibilities in a more orthodox way.
You can use a subclass with a private constructor:
With this, only InstantiatonClass can create InstantiatonClass.ArgClass and the constructor of ProtectedClass.
public class ProtectedClass{
//constructor that can only be invoked with an instance of ArgClass
public ProtectedClass(InstantiatonClass.ArgClass checkArg){}
}
public class InstantiatonClass{
public static class ArgClass{
//constructor that can only be invoked from InstantiatonClass
private ArgClass(){}
}
}
You should be able to get caller's class in a Class's constructor:
How to get the name of the calling class in Java?
Then in the classes where you only want to be instantiated by Main, simply check the caller class is Main in its constructor, if not throw a RuntimeException.

Should I make 'count' as static in derived class, how to access it

I have a class, lets say CargoShip, which is a derived class of 'Starcraft', which implements the interface IStarcraft.
This is the function that should return the count (number of instances) of every ship:
public static void printInstanceNumberPerClass (ArrayList<ISpacecraft> fleet){}
There's a solution which I thought of and I'm sure it will work, declaring 'getCount()' in ISpacecraft, then overriding it in each SpaceCraft ship (I have 4 ships), and just iterating through everyone of them, polymorphism.
Fine, I got that. but because the function is static (yes, I know we dont need to create an object to use it) I thought it might tell me something different. What do I mean by that? Is it possible to create 'static count = 0' instead, in every ship, and somehow access it?
The question is then, how can I access that static field when I get an arraylist of ISpacecraft objects?
Polymorphism doesn't work with static methods, method resolution is very different. For virtual methods on an instance the code may be referring to the object with a variable typed as a superclass or interface, and calling a method is resolved at runtime without your application code needing to know the exact concrete type. For static methods you call it on a specific class and if the method isn't found then it's called on a superclass. Your code has to start with some subclass and resolution works up the hierarchy from there. For static methods you can't not know a low-level class to call the method on, the way you can with instance methods on objects. You can't have the level of abstraction you take for granted with objects.
The comment by markspace provides a much better alternative. Use static methods for stateless functions like java.lang.Math.

Override an interface?

I am creating a mod for the game Minecraft, which has an interface to implement in-game commands. I need the mod to implement that interface, but override one of its methods with a non-compatible method (different return type). But I need to prevent a situation where other classes that implement that interface will not work or not be recognized by the game.
I think this would require overriding the interface with a new interface that is the same as the original, but with an overloaded version of that method to support the mod's needs. Is this possible (or is there another way I can accomplish this?)
One way to think about interfaces is as a contract.
Implementing classes must strictly adhere to this contract.
This means that the method signatures (including return values and parameter) must match exactly.
The entire point of interfaces is to define the interaction without strictly knowing the implementation.
If the interaction you are looking to implement is different then it's possible that you are trying to use something in a way it wasn't intended for.
Even if it is possible to subclass an interface, it's going to quickly get messy.
It's probably in you best interest to create a new interface (with all the other methods the same).
Since it's not going to be comparable with classes that use interface A, you are saving yourself trouble by separating it entirely.
The interfaces supplied by Mojang/forge team are intended for use within the mojang/forge code. They expect the result types to be returned that the interfaces return. If they don't get that as defined by the contract/interface the code will crash/not compile.
It seems as if you are trying to use an interface for a particular purpose for an own project/api.
Consider writing a new interface specifically for the purpose you intend to use it for. Don't modify core interfaces.
A class can inherit multiple interfaces, so that's not an issue. You can implement AND the forge/mojang interface AND your own.
You can implement the mod class. Then override the method. Also write another method which will overload the method in your implemented class. That way you won't have to change the interface.

Is it a good idea to merge all helper classes into one gigantic class?

As I develop my software, I tend to find myself creating a whole ton of ThingyHelper.java, FooHelper.java, BarHelper.java etc. I counted, and in the current project that I am working on, there are something like over 40 classes that look something like this:
public final class FoobarHelper {
// Prevent instantiation
private FoobarHelper() {throw new AssertionError();}
public static void doSomething() {}
public static int foobar() {}
// And many more
}
My question is this: Is it a good idea to merge all these classes into a huge Helper.java class? Looking around, there seems to be nothing written on this topic. My view is:
I should do it, because:
I don't have to remember which helper class is it in. (Was it FooHelper, or BarHelper?)
Just convenience. I don't have to decide if the new helper method deserves its own helper class, or if it fits into one of the existing 40 helper classes.
If I make a new helper method, and decided it deserves its own helper class, I will probably spend the rest of my day "hey, won't foobar() be better off in this new class?"
If #3 is true, other programmers would be like "where on earth did foobar() go? Its not in FoobarHelper!"
Is there a convention for helper classes, or if not, would it be a terrible idea?
I argue that your problem is not the fact that you have too many of those classes, it is that you need these classes altogether.
It is the core idea of object-orientation to merge functionality and data into objects which then represent your program flow. Without knowing your application, your utility classes suggest that you use inanimate bean classes which are then handled by a layer of service functions. This is a sign of procedural programming and nothing you want to implement with Java.
Besides that, there is no reason to merge your utility methods. So I would answer no to your question. There are some legitimate uses of utility classes such as Java's Math, Collections classes (those would also suite better as object methods but the language limits / limited this sort of definition) and you might just have encountered one of them. Note how Java decided to group such utility methods by their semantics. It makes sense to define utility methods in one name space such that your IDE can help you to pick a function when you only type the class (which does not represent a true class but rather a function namespace in this context). In the end, it is about finding a balance. If you have a single utility method per class, it is difficult for others to locate these methods as they need to know about the class's name. If there is only one utility class, it might be problematic to locate a function of all those offered. Think about the utility class as a form of navigation helper (name space) and decide after what you find intuitive.

Possible to have a function thats not a method in java?

In this Java program I'm writing I’m finding that I’m clogging up the main() method with a lot of code that would make it hard to quickly understand/read. Specifically due to a lot of error checking that I’m doing. As a result I want to write a quick function that is only going to be used by this one method to improve readability.
Is writing another method within the class my only option or are there other alternatives?
Is writing another method within the class my only option or are there other alternatives?
It depends:
If the methods should belong only to this class, they should be declared as private or protected methods in the class, depending if the class can be inherited or not.
If the methods should be reused in other classes, it would be better to move it to utility classes as public. For example, check if a String is empty and also validating if is not null. Note that for this example there are methods covering these validations in utility classes from Apache Common Langs, explicitely StringUtils#isEmpty(String).
By the way, Java has methods, no functions.
Answer is yes, generally private methods in the classes hold the code which is not used by outside world. But havig private methods help to reduce the cyclomatic complexity of your public methods. Smaller methods lead to more readable and understandable methods.
Since Java was designed that way, you can only have methods. So, yes, that's the only way. Usually you would use class methods (static) for instance independent methods. These can also be within another class, for example a utility or helper class.

Categories