Sharing Singleton logic between projects, with modifications for each project - java

I am developing two Android applications with similar -- but not identical -- logic, and I want to share code between them. Currently, I have a project for each application, and an additional project for shared classes. The shared-classes project is a library, and the application projects are linked to this library.
The problem I have is with a class that's responsible for getting data from the server and caching that data. The class is called DataSingleton. Fetching the data has some logic which is the same for both applications, and some which is different. My question is how to design the class to support this.
There are some limitations here:
The data Singleton should be a singleton, as implied by its name.
Some of the shared logic in the shared project uses the DataSingleton, so the DataSingleton must also be in the shared-classes project (otherwise I get a build error).
I don't want to put the application-specific logic in the shared project.
If this was C++, I would have 2 different classes name DataSingleton -- one in each application -- and then have the linker connect the correct class. Both classes could inherit from some common base class, to handle the code sharing for shared logic. Can I do something similar in Java?
If it helps, I can "initialize" the DataSingleton at the start of the application with some argument that will determine its behavior. I thought about passing a class to it, but then that class doesn't have access to the DataSingleton's private members.
What is the "right" way to do this?

Think about singleton. It is a class that does 3 thigs:
1. it has a business logic
2. it creates instance of itself
4. it holds this single instance and provides access to it.
You want to hold more than one implementations of your class. This means that you need interface and/or abstract base class and several concrete classes. But in this case the best solution is to separate #1 from #2 and #3: create hierarchy of DataFetchers (I am sorry, I changed your name DataSingleton because it does not describe the reality any more) and DataFetcherAccessor:
interface DataFetcher {}
class DataFetcher1 implements DataFetcher{}
class DataFetcher2 implements DataFetcher{}
class DataFetcherAccessor<A extends DataFetcher> {
private static A accessor;
public static void setImpl(Class<A> c) {
accessor = c.newInstance();
}
public static A getAccessor() [
return accessor;
}
}
There are obviously a lot of other solutions. For example you can use SPI to locate available implementation of your interface. You can also scan your classpath yourself and discover available implementation of interface DataFetcher or use Reflections for this.

Strip the DataSingleton in the shared project of the parts that will need to change in the different projects, define it as an abstract class and change its name to AbstractDataSingleton or something like that, then just create 2 separate classes in each product called DataSingleton or whatever and make them extend the AbstractDataSingleton in the shared project.

Related

How to achieve multiple inheritance in java

I am designing Traveller App. For which I need to design 'Traveller' class and with its instance I should be able to access properties of different types of Travel modes.
class Traveller {
// common properties.
}
class RoadTravel {
// properties specific to class
}
class WaterTravel {
// properties specific to class
}
class RailTravel {
// properties specific to class
}
from the above code , I just want to create instance of 'Traveller' class and should be able to access the properties of all other classes (RoadTravel,WaterTravel,RailTravel).
I dont want to create any dependency on my sub classes and also my instance variables should not be final.
Please suggest good way of implementation so that it should be easy to add any new type of Travel mode in future.
In Java you cannot have a class which extends (inherits) from multiple classes. (You might want to look into the Deadly Diamond of Death Problem.
In your case, what you could have would be a Travel interface which defines the behaviour each of your travel types need to expose, such as cost(int duration), getName(). etc/
Your logic would then use the Travel interface to do it's logic. The travel type dependent logic would be stored in the seperate classes which make use of the Travel interface. Your main logic would then delegate travel specific logic to these classes which are passed to it at run time.
You will need to take a look at the Strategy Design Pattern to see how you can implement this.
A way to implement multiple inheritance in java is the use of proxies.
Your requirements do not seem very clear and so I cannot suggest a complete solution.
If you provide an example of client code that will use these classes, I can suggest in more details how to implement it using proxies.

Is there a way to create Model here without duplicating the code?

I need to use two similar libraries one for one specific session of MVC. Means, they (their methods) won't be used simultaneously (I'll use If...Else around that specific session to choose methods of only one library at a time). The problem is:
For both libraries to work, its mandatory for my Entities (Model) to extend their classes (wished I was with C++).
They don't provide any Interface. So, I can't do multi-inheritance.
The only choice I have left: Create two different Models each for both libraries & use specific Model based on session (or being used libraries).
But, it'll duplicate the codes in Models. At this time there's no need to sync data between them due to use of persistent storage between MVC sessions. But still, duplicate code is a big headache to manage. Is there a way to avoid this?
You could create Adapters for each specific libraray. This would keep your own code clean from the other libraries.
Also you should consider using the Strategy Pattern for switching between both libraries. This becomes handy when the code becomes more complex and you can mock the libraries in tests.
You can't get around including both libraries if that's what you're asking. You could have a few options just depends on how you want things to work.
From what I understand, you could create two classes, each extending a different library, these classes implement an Interface, override any methods you need to.
Pseudo code:
private class Lib1Adapter extends Lib1 implements LibAdapter {
// wrapper methods call lib1 methods
}
private class Lib2Adapter extends Lib2 implements LibAdapter {
// wrapper methods call lib2 methods
}
public interface LibAdapter {
// method signatures for publicly accessible methods
}
public class YourModel {
public LibAdapter la = < boolean statement > ? new Lib1Adapter() : new Lib2Adapter();
}

Exposing static methods through proxy classes

We have a Shared Utilities project, two independent SDK projects (each referring to the Utilities) and some plugin projects, each using only one of those SDKs. Shared Utilities contains some all-static classes, which need to be made visible to the plugins mentioned, but we'd like to hide the rest of its classes from them.
How we can go about resolving the issue? We'd like to keep the build process as simple as possible (we're using Ant for the build) with least possible dependencies.
Here's the options we've considered so far and why we've discarded each approach:
Second Shared Utilities project, which will be made available to the plugins - will make deployment harder.
Build 2 separate .jar-s from the Shared Utils project, one containing only the all-static utilities and the other - whatever needs to be hidden. This would make the build more complex, i.e. additional dependencies to the plugins' build scripts.
Proxy all-static classes in each of the SDKs - duplicate method definitions, but the implementation simply calls the corresponding static method from the Shared project - seems most painless, downside is we'd need to copy the Javadoc by hand. Is there a simple Javadoc tag, which would do this automatically upon generation?
Convert all-static classes to "normal" and simply create subclasses in each SDK - unnecessary (to my mind) performance overhead.
"Exposing static methods through proxy classes"
I've read your complete question and I'm not sure what is your issue exactly.
Exposing static (non-instance related) method through a proxy (instance).
What you wan't to hide from what exactly. What you want to expose to what exactly.
public class A {
private A(){} //prevent instanciation
public static void doSomething(){} //want to expose to some class, hide from other
}
To limit exposition of doSomething you can set the visibility: Controlling Access to Members of a Class.
You can also remove the static nature and use a static factory pattern to return the object like:
public class A {
private A(){}
public void doSomething(){} //want to expose to some class, hide from other
//the new A can also be set in a member variable and
//return always the same instance, if it is unmuttable it will be thread safe.
public static A getInstance(){ return new A();}
}
This can look like the "same thing" but you can now control the visibility of all method in A by controlling only the visibility of the getInstance(), the javadoc stay on A, now to control exactly how the getInstance can be access... I would have to understand exactly what you want to do.

Design Phase - Many references to same object

I am designing an application where a class named Rights is used. This class contains information about what the user can /can't do and also contains other classes like DocumentFilters.
The issue here is that I have a lot of different parts of the application getting an instance of that class through their constructor or get method, in order to be able to verify a user action before allowing it. It seems like this is bad practice (I might be wrong). Are there ways to improve this?
The way it works is having the main class of the application creating the Rights class and then creating different components and passing it to those. The components don't have instance of the main class ether.
Example code. This is repeated over several Modules.
public class ModuleA{
private Rights rights;
public ModuleA(Rights rights){
this.rights=rights;
}
private boolean verifyRights(ActionEvent e){
if(e.getSource("copyButton"){
if(rights.allowedToCopy){
return true;
}
return false;
}
}
That is a valid design and it is called Inversion of control and more specificly Dependency Injection. You can try to use an IoC container for java if you don't want to inject your dependencies manually.
It is also possible to separate the security code into aspects by using AOP. This is a more advanced option, but doing so you can separate the code that checks the security from the real business code.
If the method you showed is duplicated exactly in your Module classes, you should extract the method into a base class. This base class should then be used for all your Module classes.
public class ModuleBase
{
private Rights rights;
public ModuleA(Rights rights)
{
this.rights=rights;
}
public boolean verifyRights(ActionEvent e)
{
/// implementation
}
}
public class ModuleA : extends Bicycle
{
public ModuleA(Rights rights)
{
super(rights);
}
}
First of all I would suggest to isolate all the rights checking code into some special layer. Usually, the Facade patten is helpful here - it can check rights and then forward requests to the underlying business logic.
But this is not always possible. In this case you still have to provide classes with references to Rights instance. There are several patterns here:
Pass it to constructor/method (like you do) - still works.
Introduce Context which will store the Rights instance and make it available for necessary classes. But context is really helpful when it stores many reusable instances, not only one.
Use any dependency injection framework.
Hope this helps.

Java Classes versus C++ Classes

I just started learning to develop for the Android, and I come from a strictly C++ background. I found that Java does not support Multiple Inheritance, but do we really have to create a seperate .java file for every new Activity?
I have a TabActivity, with 3 more Activitys that make up the tabs. I want to create a List View on one of the tabs, but I am starting to get confused. Do I need to make another .java file that extends ListActivity? I can see even a relatively small application becoming extremely large if I am going to need to create a seperate .java file for every activity.
SIDE NOTE
If I want to add the ListView to one of my tabs, how would I do that? Nothing I have found thus far mentions how to add new activities to other Activities.
The other answers give good points about interfaces and that is probably more what you are looking for. However, for further information, no you don't have to create a new .java file for every new class, there are alternatives. However, keep in mind that more classes is not necessarily a bad thing. Your options are...
Nested Class:
public class A {
public/private class B {
}
}
Instances of B can access private variables of A but cannot be constructed without an instance of A (this is an approach often used for button handlers, etc.)
Nested Static Class:
public class A {
public/private static class B {
}
}
Instances of B cannot access private variables of A but they do not require an instance of A in order to be constructed. Instances of B can be instantiated anywhere if B is declared public, or only in A's methods if B is declared private.
Anonymous Class:
public class A {
private void setupLayout() {
...
button.addClickListener(new ActionListener() {
public void actionPerfored(ActionEvent e)
{
handleClick();
}
});
}
}
This strange syntax creates a class that has no name and functions the same as a nested class (e.g. can access private variables). It's an alternative form of writing nested classes that is sometimes shorter but leads to very strange syntax.
Java doesn't support multiple inheritance on abstract or normal classes but on interfaces only.
What you can do is create abstract classes that extends a particular Activity and keep creating abstract classes until you have a class that inherit all your activity features.
Alternatively, is have a class that inherits multiple interfaces.
If you use an IDE to do this, the overhead of creating lots of file is much smaller.
However there are a few ways to have many classes in the same file. This includes a) using inner/nested classes b) anonymous classes c) enums d) package local classes.
The only thing you cannot do is easily if spread the definition of a class across multiple files.
Java does not support Multiple Inheritance
Workaround is you use interfaces
but do we really have to create a seperate .java file for every new Activity
No, if your activity can be done in an existing class or can be sub classed in an existing class. Java is built around creating classes for each activity.
Java doesn't allow multiple inheritance. But it does allow implementing multiple interfaces. You don't need to create a seperate file for each class (though it's a good practice). You can encapsulate sub-classes in the main class of your file.
ListView can be simply extended and you can use the corresponding extended class in the xml etc.
Java does kind of support multiple inheritance, if you just make the base classes abstract and call them interface instead of class.
You can simply declare a ListView in XML and call it in the Activity, no need to have a separate ListActivity, just for ListView. It's when your whole Activity is a ListView.
And as per the concerns about more classes, it's not a bad thing. More classes means more object oriented, not strictly though (Everything has a limit).
Multiple Inheritence was considered not good due to problem of diamond of death. So the work-around was to use Pure Virtual Classes known as Interface in Java (Interface means a normal class in Objective-C though).
I suggest you to read HeadFirst Java second edition, for better grip on terminology and their use. It's a good book for beginners.

Categories