There are 7-8 class (implements callable) which have some similar behaviour i.e. these have some similar functions with similar implementations. And also all of these makes use of a HashMap (only for reading purpose) which is same for all these classes.
So I decided to make a abstract superclass containing all the similar methods plus this hashMap as a static member.
And I will be making subclasses for these 7-8 callable classes (hence those will also be callable by inheritance), so that performance of app can be improved.
Now I have 3 queries :
1.) Is there any flaw in this design and can I even further improve it ?
2.) Can there occur any concurrency issues as it's a three level hierarchy with callable classes at bottom two levels?
3.) Is initializing static member(hashmap) inside static block wrong ? As my boss is obsessively against using static members and blocks. So what possible problems can occur if I initialize this map inside static block ?
public abstract class AbSuper {
private static HashMap hmap;
private static CompletionService<String> service;
private static int maxThreads = 10;
static{
initializeMap();
}
public static void initializeMap(){
//load from file
}
public HashMap getmap(){
return hmap;
}
public void commonMethodOne(){
//do something
}
public static CompletionService<String> getService(){
ExecutorService executor = Executors.newFixedThreadPool(maxThreads);
service = new ExecutorCompletionService<String>(executor);
return service;
}
}
public class CallableOne extends AbSuper implements Callable<String>{
private List<String[]> taskList;
protected HashMap resultMap;
public List<String[]> getTaskList(){
return taskList;
}
public String call(){
for(String[] task : getTaskList()){
getService().submit(new SubCallableOne(task));
}
return "done with Callable One";
}
}
public class SubCallableOne extends CallableOne {
String[] task;
public SubCallableOne(String[] task) {
this.task = task;
}
public String call(){
//do what you are suppose to do
//and then access and populate "resultMap" fom superclass
return "done with subCallableOne";
}
}
There will be 7-8 CallableOne/two/three and thier corresponding SubCallableOne/two/three.
1) Do you really need to use static members? If so, maybe you should encapsulate that in a separate class and use it through encapsulation instead of inheritance. I'd still keep a superclass with the common methods.
But in any case, your current code has issues. Namely:
You are exposing the map via the public method AbSuper.getMap and it is mutable. Any code could add, delete or overwrite entries. Should it really be public? It looks like only subclasses are using it. If so, you could make it protected and return them a read only map, or a copy, or create a protected function readFromMap(key) instead.
Same for the AbSuper.getService method: it is public and static. Any code in any class could submit tasks or shutdown it. Except that you are creating a new executor each time. This is probably a bug, as each call to getService will override the service variable. Looks like you were trying to implement a singleton here but failed.
2) Callable classes might be the ones at the bottom, but you are exposing functionality in the base class to every other class in your program due to public static methods, and to anyone holding an instance due to public methods. And even if these methods didn't exist, the fact that all your instances use a shared map and executor service could result in accidental side effects. Execution order of submitted tasks, for instance.
3) It is not wrong per se, but statics are well known code smells. It makes classes hard to test. And cannot be overriden. In pure OO design there should be no need for statics. In your case, the map will be initialized the first time the class is loaded, so any call to AbSuper.getMap will get the map populated. But there are two problems with your map. The first one is that this is usually no place for long operations like populating a map from file. You should make long operations explicit, don't hide them in constructors or static initializers. The second is that the map is mutable.
Related
I've seen this thread which may look like a duplicate but it doesn't explain two problems that I face: testability and mutability.
I have a class that implements the observable pattern. To make it simple, let's imagine it like this:
public class Observable {
private final Set<Listener> listeners;
public Observable(final Set<Listener> listeners) {
this.listeners = listeners;
}
public Observable() {
listeners = new HashSet<>();
}
public void registerListener(Listener listener) {
listeners.add(listener);
}
public void unregisterListener(Listener listener) {
listeners.remove(listener);
}
}
I created two constructors to show two options I am trying to choose from. I want to test this implementation and I cannot achieve it if I don't inject a set for my listeners from the outside. On the other hand, if I inject it I make it possible to mutate this object elsewhere and my implementation is not that safe.
Is there a way to achieve both testability and safety in this scenario?
Make the constructor that you created for testing packaged private, that would decrease the accessibility of this ctor and let users know that it is not something they should be using. Put your tests in the same package and you should be able to access this ctor.
change this:
public Observable(final Set<Listener> pListeners) {
// here pListeners is immutable
this.listeners = new HashSet(pListeners);
}
to this:
Observable(final Set<Listener> pListeners) {
// here pListeners is immutable
this.listeners = new HashSet(pListeners);
}
If immutability is you main concern during testing. You can use Immutable Sets.
Core Java
Collections.unmodifiableSet(listeners)
It still will return a java.util.Set but with an immutable property
Using libraries (e.g Guava)
Set<String> immutable = ImmutableSet.of(listener1, listener2);
For your requirement to manipulate the set only inside a certain class, you can create your own copy of the Set (deep copy) that is unaccessable from outside the class.
In the other hand you can instantiate your Set with immutable Sets as show above.
here is a full example
public class Observable {
private Set<Listener> listeners;
public Observable(final Set<Listener> pListeners) {
// here pListeners is immutable
this.listeners = new HashSet(pListeners);
}
public Observable() {
listeners = new HashSet<>();
}
public void registerListener(Listener listener) {
listeners.add(listener);
}
public void unregisterListener(Listener listener) {
listeners.remove(listener);
}
}
That being said JLS specifies :
final fields also allow programmers to implement thread-safe immutable objects without synchronization. A thread-safe immutable
object is seen as immutable by all threads, even if a data race is
used to pass references to the immutable object between threads. This
can provide safety guarantees against misuse of an immutable class by
incorrect or malicious code. final fields must be used correctly to
provide a guarantee of immutability.
The usage model for final fields is a simple one: Set the final fields for an object in that object's constructor; and do not write a
reference to the object being constructed in a place where another
thread can see it before the object's constructor is finished. If this
is followed, then when the object is seen by another thread, that
thread will always see the correctly constructed version of that
object's final fields. It will also see versions of any object or
array referenced by those final fields that are at least as up-to-date
as the final fields are.
I have 7-8 callable classes which makes use of some similar functionality and also read on some same list and HashMap.
So I created a static class containing all the functionality as static functions and static list and hashMap.
Now, I have some queries :
1.) Is it a wrong practice to have static classes in java as my senior scold me over using a static class and rather asked me to convert it into a singleton class.
But static classes are faster than singleton. Isn't it ?
2.) Is it a bad design to have a reference to a static/non-static method to obtain some data like a list inside a call method (in a thread) or to perform some task?
Does it violate thread safety or parallelism as my senior said ? And ask me to have the list inside the thread class as private member.
But isn't that bad use of memory as other 6-7 thread classes makes use of the same list to read only.
3.) How can I improve the OO design with improvement in performance as well.
A sample code would look like this :
public class StaticClass {
private static List<String> ListOne;
private static List<String> listTwo;
private static HashMap<String, String> hMap;
static{
//initialize list and maps by reading from file
}
public static List<String> getListOne() {
return ListOne;
}
public static List<String> getListTwo() {
return listTwo;
}
public static HashMap<String, String> gethMap() {
return hMap;
}
public static void commonMethodOne(){
}
public static String commonMethodTwo(){
}
public static String[] commonMethodThree(){
}
}
public class CallableThread implements Callable<String>{
public String call(){
HashMap<String, String> mapTask = StaticClass.gethMap();
List<String> taskOne =StaticClass.getListOne();
for(String temp : taskOne){
//do what you are suppose to do
}
for(String key : mapTask.keySet()){
//do what you are supposed to do
}
return "Done with CallableThread";
}
}
A method like this is a terrible idea (poor naming and failure to follow the Java coding standards aside):
public static List<String> getListOne() {
return ListOne;
}
You return a mutable reference, so anyone who gets this List can modify its contents as they see fit. Private is no longer private.
If you must return a reference to a private List or data structure (no reason to do so that I can see), you should either make it immutable or return a copy.
public static List<String> getListOne() {
return Collections.unmodifiableList(ListOne);
}
You've got mutable shared data without any synchronization of any kind, so this class is not thread safe at all.
I think Singletons are far better than Static classes
Below is Answers to your question serially :
1) No , It totally depends upon your requirements but yes static classes are faster but also allows more bugs into your project
2) Yes sometimes as long as its not affecting your private data members and make your data insecure
3) Using Singletons as it provides more OO funtionalities and thus increase performance
Here is a great reference article for you :
http://javarevisited.blogspot.in/2013/03/difference-between-singleton-pattern-vs-static-class-java.html
I have a class which contains a static field that acts like a singleton :
public class A {
private static MyAPI instance = null;
protected synchronized static MyAPI getAPI() throws Exception {
if (instance == null){
// init API;
}
return instance;
}
// other methods
}
And I have multiple classes which inherit from the class A and needs to perform actions on the API. I work in a multi-threaded environment and the API can work once at a time, so I have to ensure that all the subclasses don't work on the API at the same time. To do that, I synchronize the super class when I access the API in subclasses :
public class B extends A {
public void myMethod(){
synchronized (A.class) {
myAPI = getAPI();
// do stuffs with myAPI
}
}
}
With this solution, I lock the entire class instead of just the API instance, so the other methods of my class A are not available when a subclass work on the API and performances can be decreased.
Do you think this is the best solution or do you know a better way ?
Thanks.
There are two issues that I'd consider here:
First, because the MyAPI object acts as a singleton, the fact that other classes inherit from class A is irrelevant. You might as well just have other classes in a non-hierarchical structure refer to the singleton.
Secondly, the synchronization should be done inside the code of MyAPI, and this way you can control the synchronization granularity any way that you want. This lets you also achieve better encapsulation, and you don't need to worry about a bad-behaving caller who forgets to acquire a lock before proceeding. It can be per method, per functionality, etc.
For example:
class MyAPI {
public synchronized void doWork1() { // class level lock
...
}
public void doWork2 {
synchronized (someLockObject) {
...
}
}
public void doWork3 { // related to doWork2, lock the same object
synchronized (someLockObject) {
...
}
}
If you don't want to lock on the entire class, you may lock on a static object that you use only in that method:
public class A {
private static MyAPI instance = null;
protected static Object lockForMyMethod = new Object(); //have a static lock
// other methods
}
public class B extends A {
public void myMethod(){
synchronized (A.lockForMyMethod) { //do not lock on A.class
myAPI = getAPI();
// do stuffs with myAPI
}
}
}
Not sure why you need to lock down every access to your static member but consider using AtomicReference and it's getAndSet() method for better performance.
I work in a multi-threaded environment and the API can work once at a time, so I have to ensure that all the subclasses don't work on the API at the same time.
Depending on your environment, consider to use the ExecutorService.
For example: you could use a ThreadPoolExecutor with a fixed thread-pool size of 1 and submit your jobs to that executor.
That way you can ensure your API is only used within the call() method of the Callable you submitted.
Since you have only one thread working, you don't have to worry about concurrent access of the API.
Again, i don't know the environment you are working so maybe it is a bad idea or simple not possible to solve the problem with a ExecutorService.
I have a method in my static state machine that is only used once when my application is first fired up. The method needs to be public, but I still want it hidden. Is there a way to use an annotation or something that will hide the method from the rest of the project?
You cannot make a public method hidden (unless you can declare it private). You can however put in a subclass and only let the users of the object know the type of the superclass, that is:
class A {
//Externally visible members
}
class B extends A {
//Secret public members
}
Then you instantiate the class B, but only let the type A be known to others...
Once you declare public method it becomes part of your class's contract. You can't hide it because all class users will expect this method to be available.
You could use package level instead of public. That way it can only be called by your application.
If a method is public, it can't be hidden. What you may really be looking for is just a way to restrict access to calling a method. There are other ways to achieve a similar effect.
If there are some things that your state machine does that are "only used once when my application is first fired up" it sounds a lot like those are things that could happen in the constructor. Although it depends on how complex those tasks are, you may not want to do that at construction time.
Since you said your state machine is static, is it also a Singleton? You could maybe use the Singleton Pattern.
public class SimpleStateMachine {
private static SimpleStateMachine instance = new SimpleStateMachine();
private SimpleStateMachine() {
super();
System.out.println("Welcome to the machine"); // prints 1st
}
public static SimpleStateMachine getInstance() {
return instance;
}
public void doUsefulThings() {
System.out.println("Doing useful things"); // prints 3rd
}
}
Here's some code for a client of this Singleton:
public class MachineCaller {
static SimpleStateMachine machine = SimpleStateMachine.getInstance();
public static void main(String... args) {
System.out.println("Start at the very beginning"); // prints 2nd
machine.doUsefulThings();
}
}
Note that the SimpleStateMachine instance isn't built until the first time your class is accessed. Because it's declared as static in the MachineCaller client, that counts as a "first access" and creates the instance. Keep this tidbit in mind if you definitely want your state machine to perform some of those initialization tasks at the time your application starts up.
So, if you don't want to turn your state machine class into a true singleton... you can use a static initialization block do your one-time tasks the first time the class is accessed. That would look something like this:
public class SimpleStateMachine {
static {
System.out.println("First time tasks #1");
System.out.println("First time tasks #2");
}
public SimpleStateMachine() {
super();
System.out.println("Welcome to the machine");
}
public void doUsefulThings() {
System.out.println("Doing useful things");
}
}
While we're at it, since you mentioned that it's a state machine... the Head First Design Patterns book does a nice, easily understandable treatment of the State Pattern. I recommend reading it if you haven't already.
The idiomatic approach to doing this is to use interfaces to limit the visibility of your methods.
For example, say you have the following class:
public class MyClass {
public void method1() {
// ...
}
public void method2() {
// ...
}
}
If you want to limit some parts of the project to only see method1(), then what you do is describe it in an interface, and have the class implement that interface:
public interface Method1Interface {
public void method1();
}
...
public class MyClass implements Method1Interface {
public void method1() {
// ...
}
public void method2() {
// ...
}
}
Then, you can limit the visibility of the methods by choosing to pass the class around either as a MyClass reference, or as a Method1Interface reference:
public class OtherClass {
public void otherMethod1(MyClass obj) {
// can access both obj.method1() and obj.method2()
}
public void otherMethod2(Method1Interface obj) {
// can only access obj.method1(), obj.method2() is hidden.
}
}
A bonus of this approach is that it can also be easily extended. Say, for example, you now also want to independently control access to method2(). All you need do is create a new Method2Interface along the same lines as Method1Interface, and have MyClass implement it. Then, you can control access to method2() in exactly the same manner as method1().
This is a similar approach to that advocated in #MathiasSchwarz's answer, but is much more flexible:
The independent access control described in the preceding paragraph isn't possible with Mathias' technique, due to Java not supporting multiple inheritance.
Not requiring an inheritance relationship also allows more flexibility in designing the class hierarchy.
The only change required to the original class is to add implements Method1Interface, which means that it is a very low-impact refactor since existing users of MyClass don't have to be changed at all (at least, until the choice is made to change them to use Method1Interface).
An alternative solution: You can make it private and create a invokeHiddenMethod(String methodName, Object ... args) method using reflection.
You said that your public method is used only once when the application is started up.
Perhaps you could leave the method public, but make it do nothing after the first call?
There is a (non-)keyword level package level visibility. Instead of public, protected, or private, you use nothing.
This would make the method or class visible to the class and others in the package, but would give you a certain modicum of privacy. You may want to look at What is the use of package level protection in java?.
Hmm... You want a private method, but want to access it outside?
Try do this with reflection.
http://download.oracle.com/javase/tutorial/reflect/index.html
I have seen many Java programmers do something like this:
public static void main(String args[]) {
new MyClass();
}
So basically they create just one object of the class. If there is a method which should run only once, I guess this approach can achieve that. Your method will be called from inside the constructor. But since I don't know how your app works, what are the constraints, so it is just a thought.
/* Atleast is it needed in this case?*/
public class Service
{
private static List<String> subscribedFields;
private static List<String> unsubscribedFields;
//---------------------------------
// is this necessary?
//---------------------------------
public static void setFields(List<String> subscribedFields, List<String> unsubscribedFields)
{
Service.subscribedFields = subscribedFields;
Service.unsubscribedFields = unsubscribedFields;
}
public static List<String> getSubscribedFields()
{
return subscribedFields;
}
public static List<String> getUnsubscribedFields()
{
return unsubscribedFields;
}
}
// some other class
public class User{
// Is this not enough to change the lists? Isn't the setter redundant?
Change(Service.getSubscribedFields());
Change(Service.getUnsubscribedFields());
}
No, a public setter is not always needed for a private variable. The idea of providing public setters (and getters, for that matter) is based on - what external entities such as classes need access to the insides of the particular piece of code you are writing. Getters and setters provide that public interface for that to happen. However, you don't necessarily NEED to provide a public getter or setter to every private variable you create as that private variable may only exist for internal, private use to the class.
You'll have to decide if you specifically need to give access to your private variables based on the particular needs of your code.
Update Based on ada's Question in Comments
You could give the user access to your lists directly (yes - they can use the getter and then edit the list). This may work if you trust the users of your code. However, for various reasons, you may not want to give them direct access to your list like that (especially because it gives them free reign to do what they want to do, it can create problems if you have threading within your application, etc). In that case, you should provide interfaces into the underlying list. For example, in your class, instead of providing a getSubscribedFields(), you may want to provide methods like:
// Pseudocode
public String getSubscribedField(int i) {
return subscribedFields.Get(i);
}
public String addSubscribedField(String field) {
subscribedFields.Add(field);
}
Hopefully that helps clarify things a bit for you.
The more popular choice in this case is to use a Singleton which you initialize once with the fields. However, not even Singleton is really a good idea, but to do otherwise requires that we know a bit more about what you're trying to do. In most cases you can get around using static instances by making it a member of a class with a long lifetime. For example, if these fields were related to database fields, you'd associate it with a table class which holds information pertaining to a database table for instance.
Really it depends on what you're trying to accomplish.
No you shouldn't. And even more you should avoid static state.
Your class seems to be very prone to thread safety problems. I also question the relevance of your need to put your List as static variables.
Another thing, your setter isn't in line with JavaBeans setters & getters standards, you might have problem if you want to integrate with some common frameworks.
I suggest you a variation of your class. I refactored it in order to keep the responsibility of the class is to hold the subscriptions.
If you use a dependency injection framework like Spring or Guice, you could simply make a class like this one, and inject it to the classes that need this object.
public class SubscriptionServiceUsingDependencyInjection {
private final Set<String> subscribedFields = new CopyOnWriteArraySet<String>();
public boolean isSubscribed(String field_) {
return subscribedFields.contains(field_);
}
public void subscribe(String field_) {
subscribedFields.add(field_);
}
}
Otherwise If you really need a Singleton, you may use an enum to achieve the same goal :
public enum SubscriptionServiceUsingASingleton {
INSTANCE;
private final Set<String> subscribedFields = new CopyOnWriteArraySet<String>();
public boolean isSubscribed(String field) {
return subscribedFields.contains(field);
}
public void subscribe(String field) {
subscribedFields.add(field);
}
}
The CopyOnWriteArraySet will prevent concurrency problem if you are running this in a multithreaded environment.