Recently at my company a debate started after reviewing a different approach for writing heavy duty classes.
A big Java class holding component specific logic (no standard OOP principles made sense) had to be rewritten in Kotlin. The solution provided was splitting the logic in categories and the categories into separate files with internal extension functions to the main class.
Example:
Main.kt
class BigClass {
// internal fields exposed to the extension functions in different files
// Some main logic here
}
BusinessLogic.kt
internal fun BigClass.handleBussinessCase() {
// Complex business logic handled here accessing the exposed internal fields from BigClass
}
What are your thoughts on this? I haven't seen it used anywhere maybe for a good reason, but the alternative of thousand lines classes seems worse.
You have to consider that an extension function is nothing more than a function with an implicit first parameter which is referenced with this.
So in your case you'd have something like:
internal fun handleBussinessCase(ref: BigClass)
which would translate to Java as:
static void handleBussinessCase(BigClass ref)
But this could be assumed to be a delegate pattern, which could be encapsulated much cleaner in Kotlin as well.
Since the properties have to be internal anyhow, you could just inject these as a data class into smaller use-cases. If you define an interface around these (which would make the properties public though), you could create a delegate pattern with it and still reference each property with this in your implementation.
Here are some thoughts on making extension functions for the class:
It will be a utility function that will operate with the object you're extending, it will not be an object function, meaning that it will have access to only public methods and properties;
If you're planning to use class that being extended in unit tests, these methods (extensions) will be harder to mock;
Most likely they wont behave as you expect when used with inherited objects.
Maybe I missed something, so please read more about extensions here.
I have a class that consists only of static member variables and static methods. Essentially, it is serving as a general-purpose utility class.
Is it bad practice for a class to contain only static member variables and static methods?
No, I don't think so at all. It is worse practice to have a class full of instance methods which don't actually depend on a particular instance. Making them static tells the user exactly how they are intended to be used. Additionally, you avoid unnecessary instantiations this way.
EDIT: As an afterthought, in general I think its nice to avoid using language features "just because", or because you think that that is the "Java way to do it". I recall my first job where I had a class full of static utility methods and one of the senior programmers told me that I wasn't fully harnessing the OO power of Java by making all of my methods "global". She was not on the team 6 months later.
As long as the class has no internal state and is essentially what is known as a leaf class (utility classes fall into this category), in other words it is independent of other classes. It is fine.
The Math class being a prime example.
Sounds reasonable.
Note: Classes that do this often have a private no-arg constructor just so that the compiler yields an error if a programmer tries to create an instance of the static class.
Static methods don't worry me much (except for testing).
In general, static members are a concern. For example, what if your app is clustered? What about start-up time -- what kind of initialization is taking place? For a consideration of these issues and more, check out this article by Gilad Bracha.
It's perfectly reasonable. In fact, in C# you can define a class with the static keyword specifically for this purpose.
Just don't get carried away with it. Notice that the java.lang.Math class is only about math functions. You might also have a StringUtilities class which contains common string-handling functions which aren't in the standard API, for example. But if your class is named Utilities, for example, that's a hint that you might want to split it up.
Note also that Java specifically introduced the static import: (http://en.wikipedia.org/wiki/Static_import)
Static import is a feature introduced
in the Java programming language that
members (fields and methods) defined
in a class as public static to be used
in Java code without specifying the
class in which the field is defined.
This feature was introduced into the
language in version 5.0.
The feature provides a typesafe
mechanism to include constants into
code without having to reference the
class that originally defined the
field. It also helps to deprecate the
practice of creating a constant
interface: an interface that only
defines constants then writing a class
implementing that interface, which is
considered an inappropriate use of
interfaces[1].
The mechanism can be used to reference
individual members of a class:
import static java.lang.Math.PI;
import static java.lang.Math.pow;
or all the static members of a class:
import static java.lang.Math.*;
While I agree with the sentiment that it sounds like a reasonable solution (as others have already stated), one thing you may want to consider is, from a design standpoint, why do you have a class just for "utility" purposes. Are those functionals truly general across the entire system, or are they really related to some specific class of objects within your architecture.
As long as you have thought about that, I see no problem with your solution.
The Collections class in Java SDK has static members only.
So, there you go, as long as you have proper justification -- its not a bad design
Utility methods are often placed in classes with only static methods (like StringUtils.) Global constants are also placed in their own class so that they can be imported by the rest of the code (public final static attributes.)
Both uses are quite common and have private default constructors to prevent them from being instantiated. Declaring the class final prevents the mistake of trying to override static methods.
If by static member variables you did not mean global constants, you might want to place the methods accessing those variables in a class of their own. In that case, could you eleborate on what those variables do in your code?
This is typically how utility classes are designed and there is nothing wrong about it. Famous examples include o.a.c.l.StringUtils, o.a.c.d.DbUtils, o.s.w.b.ServletRequestUtils, etc.
According to a rigid interpretation of Object Oriented Design, a utility class is something to be avoided.
The problem is that if you follow a rigid interpretation then you would need to force your class into some sort object in order to accomplish many things.
Even the Java designers make utility classes (java.lang.Math comes to mind)
Your options are:
double distance = Math.sqrt(x*x + y*y); //using static utility class
vs:
RootCalculator mySquareRooter = new SquareRootCalculator();
mySquareRooter.setValueToRoot(x*x + y*y);
double distance;
try{
distance = mySquareRooter.getRoot();
}
catch InvalidParameterException ......yadda yadda yadda.
Even if we were to avoid the verbose method, we could still end up with:
Mathemetician myMathD00d = new Mathemetician()
double distance = myMathD00d.sqrt(...);
in this instance, .sqrt() is still static, so what would the point be in creating the object in the first place?
The answer is, create utility classes when your other option would be to create some sort of artificial "Worker" class that has no or little use for instance variables.
This link http://java.dzone.com/articles/why-static-bad-and-how-avoid seems to go against most of the answers here. Even if it contains no member variables (i.e. no state), a static class can still be a bad idea because it cannot be mocked or extended (subclassed), so it is defeating some of the principles of OO
I wouldn't be concerned over a utility class containing static methods.
However, static members are essentially global data and should be avoided. They may be acceptable if they are used for caching results of the static methods and such, but if they are used as "real" data that may lead to all kinds of problems, such as hidden dependencies and difficulties to set up tests.
From TSLint’s docs:
Users who come from a Java-style OO language may wrap their utility functions in an extra class, instead of putting them at the top level.
The best way is to use a constant, like this:
export const Util = {
print (data: string): void {
console.log(data)
}
}
Examples of incorrect code for this rule:
class EmptyClass {}
class ConstructorOnly {
constructor() {
foo();
}
}
// Use an object instead:
class StaticOnly {
static version = 42;
static hello() {
console.log('Hello, world!');
}
}
Examples of correct code for this rule:
class EmptyClass extends SuperClass {}
class ParameterProperties {
constructor(public name: string) {}
}
const StaticOnly = {
version: 42,
hello() {
console.log('Hello, world!');
},
};
Why the R class in android is not static? when it contains all static content.
public final class R {
//static content
}
As per Java language policies, A top level public class cannot be static. And when you dive deep into the usage of static class you will find it is used to create independent inner class that does not hold anonymous reference of outer class. Therefore the purpose and use of static keyword before class is completely different.
non-static inner class
class A
{
int var1;
class B{
int calc(){
// can access A.var1 directly
}
}
}
static inner class
class A
{
int var1;
static class B{
int calc(){
// cannot access A.var1 directly, need object to be passed
}
}
}
R.java is the dynamically generated class, created during build process to dynamically identify all assets (from strings to android widgets to layouts), for usage in java classes in Android app. Note this R.java is Android specific (though you may be able to duplicate it for other platforms, its very convenient), so it doesn't have much to do with Java language constructs.
android.R.java is not just where XML ids are stored. It also contains access to resources - such as drawables, layouts, strings, arrays, and basically anything you can declare in resources.
Personally I find that it is useful when using Eclipse. I can simply type findViewById(R.id. and Eclipse will show a tooltip with a list of options to choose from.
However at a platform level, I would say that the hardcoded id variables help prevent errors when using Strings to identify resources -- something that can be debuggable while programming (or during compilation, rather than runtime).
I am trying to write an Android app using Xtend, however, I am more or less new in both. I have created a couple of Android examples with Java, but I'm still learning.
In these apps i used the android.app.Instrumentation.ActivityMonitor
in order to check that an Activity had started.
I have read that Xtend does not support Nested classes
No var args, no nested classes, no anonymous classes?
Those language features are not mentioned in the docs, and I could not guess a valid syntax. >I assume they are not available, but I could be wrong.
http://blogs.atlassian.com/2011/11/xtend-first-impressions/
Does this mean the ActivityMonitor cannot be accessed when using Xtend or am I just doing something wrong?
It depends how you used the ActivityMonitor. You cannot define inner classes on your own right now, but static inner classes can be accessed from within Xtend. There are issues with non-static inner classes. The syntax is different to Java, though. Instead of the '.' dot as the delimiter of declaring class and inner class, Xtend uses the '$'. A respective import declaration can ease the pain, here, e.g. import android.app.Instrumentation$ActivityMonitor.
Suppose I have my Android app's source code packaged this way:
src/
my/
app/
Module.java
ModuleManager.java
module/
ModuleA.java
ModuleB.java
where Module is:
public abstract class Module {
public abstract void run();
}
, ModuleA and ModuleB extends Module:
public class ModuleA extends Module {
#Override
public void run() { /* do something */ }
}
and ModuleManager has some helper methods, among which one to retrieve all the Modules:
public class ModuleManager {
private final static List<Module> modules;
static {
List<Module> tmp= new ArrayList<Module>();
tmp.add(new ModuleA());
tmp.add(new ModuleB());
modules= Collections.unmodifiableList(tmp);
}
public static List<Module> getModules(){
return modules;
}
}
As you can see I manually filled the list of modules in ModuleManager. Instead, I would like it to be automatically filled with an instance of all the Module's subtypes in the module package.
I tried in several ways reflection-based solutions like this, which involve the use of ClassLoader::getResource(String path) to retrieve every .class file inside the module package, but it always returns an empty enumeration. I learnt this is due to the difference between Dalvik's VM and Java SE's one, and its optimized packaging of .class files inside classes.dex. I then tried to import the application's apk from /data/app/ with DexClassLoader or PathClassLoader and unsuccesfully tried their getResource() method again. Anyway I think this is not the right direction, and probably this stuff was already hackish/flawed in Java, and it would be even more in Android.
Could you suggest me a way to do that?
Thank you very much.
One way to do this in a build script, after compilation but before dex is called to create classes.dex, run a small script to get the class names in modules folder and write it to say an application.properties file to read from (or strings.xml in resources).
The disadvantage of this is it is not a pure java method you were asking for, the advantage being it will work for 2 or 10+ subclasses. Hope this helps.
What if you add an XML or a Properties with the module classes and you dynamicly created from it... it might goes something like this
<modules>
<module>
my.app.module.ModuleA
</module>
<module>
my.app.module.ModuleB
</module>
</modules>
Another solution could be to exploit a naming convention on classes' names and retrieve all of them one-by-one with Class.forName(className). In the example I made, if I know that all modules are named sequentially as ModuleA, ModuleB, ModuleC and so on, I can retrieve all of them starting from ModuleA and continuing until Class.forName("ModuleX") fails. If gaps were allowed but the number of modules was bounded (and very low), an exhaustive search on the entire range could be done.
Of course this could be applied in a very few cases, and at the expense of class' name readability.