My program gets information from an external source (can be a file, a database, or anything else I might decide upon in the future).
I want to define an interface with all my data needs, and classes that implement it (e.g. a class to get the data from a file, another for DB, etc...).
I want the rest of my project to not care where the data comes from, and not need to create any object to get the data, for example to call "DataSource.getSomething();"
For that I need DataSource to contain a variable of the type of the interface and initialize it with one of the concrete implementations, and expose all of its methods (that come from the interface) as static methods.
So, lets say the interface name is K, and the concrete implementations are A,B,C.
The way I do it today is:
public class DataSource {
private static K myVar = new B();
// For **every** method in K I do something like this:
public static String getSomething() {
return myVar.doSomething();
}
...
}
This is very bad since I need to copy all the methods of the interface and make them static just so I can delegate it to myVar, and many other obvious reasons.
What is the correct way to do it? (maybe there is a design pattern for it?)
**Note - since this will be the backbone of many many other projects and I will use these calls from thousands (if not tens of thousands) code lines, I insist on keeping it simple like "DataSource.getSomething();", I do not want anything like "DataSource.getInstance().getSomething();" **
Edit :
I was offered here to use DI framework like Guice, does this mean I will need to add the DI code in every entry point (i.e. "main" method) in all my projects, or there is a way to do it once for all projects?
The classes using your data source should access it via an interface, and the correct instance provided to the class at construction time.
So first of all make DataSource an interface:
public interface DataSource {
String getSomething();
}
Now a concrete implementation:
public class B implements DataSource {
public String getSomething() {
//read a file, call a database whatever..
}
}
And then your calling class looks like this:
public class MyThingThatNeedsData {
private DataSource ds;
public MyThingThatNeedsData(DataSource ds) {
this.ds = ds;
}
public doSomethingRequiringData() {
String something = ds.getSomething();
//do whatever with the data
}
}
Somewhere else in your code you can instantiate this class:
public class Program {
public static void main(String[] args) {
DataSource ds = new B(); //Here we've picked the concrete implementation
MyThingThatNeedsData thing = new MyThingThatNeedsData(ds); //And we pass it in
String result = thing.doSomethingThatRequiresData();
}
}
You can do the last step using a Dependency Injection framework like Spring or Guice if you want to get fancy.
Bonus points: In your unit tests you can provide a mock/stub implementation of DataSource instead and your client class will be none the wiser!
I want to focus in my answer one important aspect in your question; you wrote:
Note - I insist on keeping it simple like "DataSource.getSomething();", I do not want anything like "DataSource.getInstance().getSomething();"
Thing is: simplicity is not measured on number of characters. Simplicity comes out of good design; and good design comes out of following best practices.
In other words: if you think that DataSource.getSomething() is "easier" than something that uses (for example) dependency injection to "magically" provide you with an object that implements a certain interfaces; then: you are mistaken!
It is the other way round: those are separated concerns: one the one hand; you should declare such an interface that describes the functionality that need. On the other hand, you have client code that needs an object of that interface. That is all you should be focusing on. The step of "creating" that object; and making it available to your code might look more complicated than just calling a static method; but I guarantee you: following the answer from Paolo will make your product better.
It is sometimes easy to do the wrong thing!
EDIT: one pattern that I am using:
interface SomeFunc {
void foo();
}
class SomeFuncImpl implements SomeFunc {
...
}
enum SomeFuncProvider implements SomeFunc {
INSTANCE;
private final SomeFunc delegatee = new SomeFuncImpl();
#Override
void foo() { delegatee.foo(); }
This pattern allows you to write client code like
class Client {
private final SomeFunc func;
Client() { this(SomeFuncProvider.INSTANCE); }
Client(SomeFunc func) { this.func = func; }
Meaning:
There is a nice (singleton-correctway) of accessing an object giving you your functionality
The impl class is completely unit-testable
Client code uses dependency injection, and is therefore also fully unit-testable
My program gets information from an external source (can be a file, a database, or anything else I might decide upon in the future).
This is the thought behind patterns such as Data Access Object (short DAO) or the Repository pattern. The difference is blurry. Both are about abstracting away a data source behind a uniform interface. A common approach is having one DAO/Repository class per business- or database entity. It's up to you if you want them all to behave similarly (e.g. CRUD methods) or be specific with special queries and stuff. In Java EE the patterns are most often implemented using the Java Persistence API (short JPA).
For that I need DataSource to contain a variable of the type of the
interface and initialize it with one of the concrete implementations,
For this initialization you don't want to know or define the type in the using classes. This is where Inversion Of Control (short IOC) comes into play. A simple way to archieve this is putting all dependencies into constructor parameters, but this way you only move the problem one stage up. In Java context you'll often hear the term Context and Dependency Injection (short CDI) which is basically an implementation of the IOC idea. Specifically in Java EE there's the CDI package, which enables you to inject instances of classes based on their implemented interfaces. You basically do not call any constructors anymore when using CDI effectively. You only define your class' dependencies using annotations.
and expose all of its methods (that come from the interface)
This is a misconception. You do want it to expose the interface-defined method ONLY. All other public methods on the class are irrelevant and only meant for testing or in rare cases where you want to use specific behavior.
as static methods.
Having stateful classes with static method only is an antipattern. Since your data source classes must contain a reference to the underlying data source, they have a state. That said, the class needs a private field. This makes usage through static methods impossible. Additionally, static classes are very hard to test and do not behave nicely in multi-threaded environments.
Related
I've a question about DIP Principle. One of the guidelines says that we should not hold references to a concrete class (if it changes then I'll have to modify all clients that use it). So, what can I follow this guideline when I use POJOs ? For Example:
I have a Bean 'Foo' with some attributes (it could represent a Domain object)
class Foo {
private String one;
private String two;
//getters and setters
}
Multiple clients instantiate this object, for example, to persist it in the Database
class Client1 {
private FooDao dao;
Client1(FooDao dao){
this.dao = dao;
}
public void persist() {
//hard coding
Foo foo = new Foo();
foo.setOne("something...");
dao.save(foo); }
}
class Client2 {
private FooDao dao;
Client2(FooDao dao){
this.dao = dao;
}
public void persist() {
Foo foo = new Foo();
foo.setOne("something...");
foo.setTwo("something...")
dao.save(foo);
}
}
If I add or change any attribute to 'Foo' class every client would have to change, so follow this guideline how can I avoid that?
Thanks!
The comment from #chrylis is spot on. Robert Martin covers this in chapter 6 of Clean Code: Objects and Data Structures.
Objects hide their data behind abstractions and expose functions that operate on that data. Data structures expose their data and have no meaningful functions. (page 95)
The definition of OOP where everything is an object, and there are no data structures, is naive.
Mature programmers know that the idea that everything is an object is a myth. Sometimes you really do want simple data structures with procedures operating on them. (page 97)
So what about classes that expose both data and behavior?
Confusion sometimes leads to unfortunate hybrid structures that are half object and half data structure. They have functions that do significant things, and they also have either public variables or public accessors and mutators that, for all intents and purposes, make the private variables public, tempting other external functions to use those variables the way a procedural program would use a data structure.
Such hybrids make it hard to add new functions but also make it hard to add new data structures. They are the worst of both worlds. Avoid creating them. (page 99)
To the original question: the Dependency Inversion Principle applies to objects, not to data structures like Java Beans.
I think you're taking this a little too literally.
I had the pleasure of attending a talk given by Venkat Subramaniam, which talked about DIP.
You're right when you say that you should be relying on abstractions, not concretions, but in my notes from that talk, I have the footnote, "take this with a grain of salt."
In your case, you're going to want to take this with a grain of salt, since there's a fairly strong code smell here - you're exposing the use of this bean to all consumers who need it, which implicitly create a dependency on it. This violates the Single Responsibility Principle since this bean is being used in more places than it probably should be.
Since it seems like you're talking about a database abstraction, perhaps you would want to look into a DTO which would be exposed between services to carry information between them, and let your bean handle the internals.
To your point...
if it change[s] then I'll have to modify all clients that use it
...this is true if you remove functionality. If you add new functionality, you can let your downstream clients just ignore that functionality. If you want to change existing functionality, you have to allow the clients a path to migration.
You need to define the functionality of the method you would like to add.
interface Functionality {
public void persist();
}
Each class except the manager need to implement the interface:
class Client1 implements Functionality{
//Your code..
}
Add a high level class high level classes that not working directly with low level classes:
Class ManageClients{
Functionality func;
public void setClient(Functionality f) {
func= f;
}
public void manage() {
func.persist();
}
};
ManageClients class doesn't require changes when adding Clients.
Minimized risk to affect old functionality present in ManageClients class since we don't change it.
No need to redo the unit testing for ManageClients class.
This is a common design in the enterprise Java level (though, most of the time references get injected by some frameworks/libraries):
I have an interface
import java.util.*;
public interface ProductRepository {
public List <Product> getAllProducts();
}
And its implementation
public class ProductRepositoryImp implements ProductRepository {
private List<Product> products = new ArrayList<Product>();
public ProductRepositoryImp() {
products.add(new Product("Blackberry", 24000));
products.add(new Product("Nokia", 45000));
products.add(new Product("Samsung", 91000));
}
#Override
public List<Product> getAllProducts() {
return this.products;
}
public int localMethod(){
return 2;
}
}
In the main class (controller) I reference the interface (ProductRepository) instead of the implementation (ProductRepositoryImp)
public class ProductController {
static ProductRepository productRepository;
public static void main(String[] args) {
productRepository = new ProductRepositoryImp();
for (Product p : productRepository.getAllProducts()) {
System.out.println(p.getName());
System.out.println(p.getPrice());
System.out.println("");
} } }
Why?
Here is an explanation I read in a book:
It is not the best practice to connect two
layers (controller and persistence) with a direct reference. Instead, we can, in future, have an
interface reference in the controller so that we can easily switch to different implementations
of the repository without doing any code changes in the controller class.
What's the benefit of accessing .getAllProducts() from the ProductRepository instance instead of an instance of ProductRepositoryImp?
What's the point of "without doing any code changes" switching in the quote above? I know it's something related if we have
lets say "AnotherProductRepositoryImp"?.
What if I want to heavily access some .localMethod() instead which is inside the ProductRepositoryImp instance ?
What's the benefit of accessing .getAllProducts() from the
ProductRepository instance instead of an instance of
ProductRepositoryImp?
ProductRepository is your interface to your data layer. It is totally agnostic of the underlying database.
what's the point of "without doing any code changes" switching in the
quote above? I know it's something related if we have lets say
"AnotherProductRepositoryImp"?.
In this case it is not related to AnotherProductRepositoryImp, but lets say the underlying database changes. Each database has different query formats and the corresponding implementation of the query goes in ProductRepositoryImpl class. The changes would not be AnotherProductRepositoryImp but ProductMongoRepositoryImp, ProductMySqlRepositoryImp, ProductFileRepositoryImp etc
If you are coding to interfaces, then you will not have to make any changes to your controller. Just inject another implementation and you are done.
What if I want to heavly access some .localMethod() instead which is
inside the ProductRepositoryImp instance ?
If you are using any method which is not a part of interface and being used only internally in your implementation, then it is not a part of contract with the interface and need not be exposed to the outside world(i.e declare it private).
If it is to be exposed to the outside world, it means it is outside the contract with the interface. You would typically need to typecast to the correct instance type to access that value.
The benefit is that you can inject another implementation into your controller, such as a mock repository for testing, or a repository for a different SQL dialect.
Separating interfaces from implementations can also be used to make it explicit which methods are intended to be used by callers (cf. information hiding, encapsulation), though this can also be accomplished by access modifiers (such as private). The important thing is that the team agrees on which signaling mechanism they use to avoid misunderstandings.
While the use of interfaces was mandated by many early enterprise frameworks, most notably EJB until version 3.1, modern frameworks no longer enforce that.
Today, it is somewhat debated whether interfaces with only one implementation should exist. Some say yes for consistency, some say no for simplicity.
I'm new at programming and I'm learning Java.
I was just wondering why I should use an interface when there is only one implementation class?
You do this to prevent others from accessing your implementing type. For example, you could hide your implementing type inside a library, give the type package access, and return an instance of your interface to the users of your library:
// This is what the users of your library know about the class
// that does the work:
public interface SomeInterface {
void doSomethingUseful();
void doSomethingElse();
}
// This is the class itself, which is hidden from your clients
class MyImplementation implements SomeInterface {
private SomeDependency dependency = new SomeDependency();
public void doSomethingUseful() {
...
}
public void doSomethingElse() {
...
}
}
Your clients obtain objects like this:
public class MyFactory {
static SomeInterface make() {
// MyFactory can see MyImplementation
return new MyImplementation();
}
}
This trick becomes useful when the implementation uses lots of libraries. You efficiently decouple the interface of your library from its implementation, so that the user wouldn't have to know about the dependencies internal to your library.
One reason is to maintain the open/closed principle, which states that your code should be open for extension, but closed for modification. Although you only have one implementing class now, chance is that you will need another differing implementation class with the passing of time. If you extract the implementation into an interface beforehand, you just have to write another implementing class ie. You don't have to modify a perfectly working piece of code, eliminating the risks of introducing bugs.
You shoulnt do anything without thinking and reasoning.
There might be cases where you might want to add an interface even for a single implementation ... but IMO that's an OBSOLETE PRACTICE coming from old EJB times, that people use and enforce without the proper reasoning and reflection.
... and both Martin Fowler, Adan Bien, and others has been saying it for years.
https://martinfowler.com/bliki/InterfaceImplementationPair.html
https://www.adam-bien.com/roller/abien/entry/service_s_new_serviceimpl_why
To respect the Interface Segregation Principle.
The decision to create an interface should not be based on the number of implementing classes, but rather on the number of different ways that object is used. Each ways the object is used is represented by an interface, defined with the code that uses it. Say your object needs to be stored in memory, in collections that keep objects in order. That same object and also needs to be stored in some persistent storage.
Say you implement persistence first. What is needed by the storage system is a unique identifier for the persisted objects. You create an interface, say Storable, with a method getUniqueId. You then implement the storage.
Then, you implement the collection. You define what the collection needs from stored objects in an interface, like Comparable, with a method compareTo. You can then implement the collection with dependency on Comparable.
The class you want to define would implement both interfaces.
If the class you are defining implement a single interface, that interface would have to represent the needs of the collection and storage system. That would cause, for example:
unit tests for the collection would have to be written with objects that implement Storable, adding a level of complexity.
if the need arise later to display the object, you would have to add methods needed by the display code to the single interface, and modify the tests for collection and storage to also implement the methods needed for display.
I talk about impact on test code here. The problem is larger if other production level objects need storage and not display. The larger the project, the larger the issue created by not respecting the interface segregation principle will become.
It can give you the flexibility to add more implementations in the future without changing the client code which references the interface.
Another example of when it can be useful is to simulate multiple inheritance in Java when it is needed. For example, suppose you have an interface MyInterface and an implementation:
public interface MyInterface {
void aMethod1();
void aMethod2();
}
class MyInterfaceImpl implements MyInterface {
public void aMethod1() {...}
public void aMethod2() {...}
}
You also have an unrelated class with its own hierarchy:
public class SomeClass extends SomeOtherClass {
...
}
Now you want to make SomeClass be of type MyInterface but you also want to inherit all the code that is already existing in MyInterfaceImpl. Since you cannot extend both SomeOtherClass and MyInterfaceImpl, you can implement the interface and use delegation:
public class SomeClass extends SomeOtherClass implements MyInterface {
private MyInterface myInterface = new MyInterfaceImpl();
public void aMethod1() {
myInterface.aMethod1();
}
public void aMethod2() {
myInterface.aMethod2();
}
...
}
I see a lot of good points being made in this post. Also wanted to add my 2 cents to this collection of knowledge.
Interfaces Encourage parallel development in a team environment. There can be 2 classes A and B, with A calling B's API. There can be 2 developers simultaneously working on A and B. while B is not ready, A can totally go about it's own implementation by integrating with B's interfaces.
Interfaces serve as a good ground for establishing API Contracts between different layers of code.
It's good to have a separation of concerns with Interface handling implicit API documentation. it's super easy to refer to one and figure which APIs are accessible for the clients to call.
Lastly, it's better to practice using interfaces as a standard in a project than having to use it on a case by case bases (where you need multiple implementations). This ensures consistency in your project.
For the Art that Java Code is, interfaces make thmem even more beautiful :)
Interfaces can be implemented by multiple classes. There is no rule that only one class can implement these. Interfaces provide abstraction to the java.
http://www.tutorialspoint.com/java/java_interfaces.htm
You can get more information about interfaces from this link
I would like to start off by mentioning that my problem stems from the fact that interfaces in Java do not allow static methods. There have been discussions about the reason for this on SO (here , for example). So lets not dwell on that. I am looking for a way for my interface to create an instance of itself (rather, its implementation) and return that. In spite of playing around with Singleton pattern, Factory and AbstractFactory patterns, I still cannot achieve my goal.
To elaborate on what I'm trying - here's my interface:
public interface NoteDataStore {
public boolean deleteNote(long noteId);
public boolean addNote(Note note);
public List<Note> listNotes();
public boolean editNote(long noteId, Note note);
public List<Note> search(String searchString);
}
And here's my business logic layer:
public class BusinessLogicLayer {
public BusinessLogicLayer(){
/*
* GOAL: To get an instance of NoteDataStore here,
* without being aware of the implementation class.
*/
}
}
I tried to use a factory pattern like so:
public interface NoteDataStoreFactory {
public NoteDataStore getDataStoreInstance();
}
public class NoteDataStoreFactoryImpl implements NoteDataStoreFactory{
public NoteDataStore getDataStoreInstance(){
return NoteDataStoreImpl.getInstance();
/*
* Here, NoteDataStoreImpl is an implementation of NoteDataStore.
* This should be transparent to my business logic layer.
*/
}
}
However, this still requires the Business Logic layer to know the implementation class NoteDataStoreFactoryImpl thus:
NoteDataStore = new NoteDataStoreFactoryImpl().getDataStoreInstance();
How do I get around this? How do I keep my BusinessLogicLayer in the dark regarding the exact implementation class to use?
EDIT: More Detailed Background of my problem
A few of the answers suggest the use of frameworks like Spring. Alas, I cannot do so because this application targets various mobile platforms (Android, Blackberry, JavaME). I should have made this clear in my original question - apologies for not doing so.
My main intention is to have an app across platforms. The UI, database access, HTTP transport layers etc will have to be coded specifically for each platform. However, the business logic is simple enough to warrant a common layer across all platforms. I intend to distribute the business logic layer as a JAR library. So also, the parsing and framing layer (for JSON/XML).
There has already been a discussion about this at SO (on whether I should even be going down this path) - Logic Code reuse. However, assuming this is OK and that I proceed with the layered approach and the intention to have one layer common in code. Now, my situation is such that I have:
A common Business Logic Layer.
Platform-specific data layer (represented by the NoteDataStore interface)
Platform-specific Application core layer (Controller, if I may call it so).
Note that if I use the Factory pattern or other such, I can afford to have that layer specific to each platform. So, the factory method/class itself can know about the NoteDataStore implementation class. However, the Business Logic Layer must be unaware of any of the implementation classes.
A typical use of the various layers would be as follows:
public class NoteDataStoreAndroid implements NoteDataStore{
public boolean deleteNote(long noteId){
/*
* Android-specific database code
*/
}
/* ... similarly, other methods */
}
public class AndroidCoreApp{
public void doBusinessLogic(){
BusinessLogicLayer businessLogic = new BusinessLogicLayer();
businessLogic.startBusinessLogic();
}
}
Any inputs on how to handle this scenario?
Your class should accept factory instance from the outside. When you're creating instance yourself - you achieve nothing, you are correct here.
There are several techniques here. In general they belong to something very general called Inversion of Control or IoC for short. Also it is useful to know about 'Inversion of Control Containers' or IoCC. Java has Spring for example - read here. You should ask real Java guys about others :)
Also take a look at this article.
If you want to return an implementation you could do so with an anonymous inner class
NoteDataStore myImplementation = new NoteDataStore (){
//Implement methods here
};
Have you looked at IoC/Dependency Injection frameworks like Guice and Spring? They may be too heavyweight for what you are looking for, but they definitely solve the problem you describe. They allow all of your business layer code to be written against interfaces, and the actual implementations to be defined via the IoC framework. I'm personally a huge fan of Spring and have used it in nearly every Java app I've written in the past 6+ years.
I finally went for the suggestion provided by #Ray Tayek in a comment to the original question. I simply pass in an instance of the NoteDataStore at the time of creating the BusinessLogicLayer.
This simple solution suits my needs pretty well since I do not really require a Factory. My main objective was for the BL Layer to be unaware of the exact implementation classes of the interfaces it uses. Now, instead of a Factory, it is the core "Controller" layer that creates a concrete implementation of the interfaces and supplies them to the BL Layer. This is just perfect!
Here is the code snippet.
public class NoteDataStoreAndroid implements NoteDataStore{
public boolean deleteNote(long noteId){
/*
* Android-specific database code
*/
}
/* ... similarly, other methods */
}
public class AndroidCoreApp{
public void doBusinessLogic(){
BusinessLogicLayer businessLogic = new BusinessLogicLayer(new NoteDataStoreAndroid());
businessLogic.startBusinessLogic();
}
}
public class BusinessLogicLayer {
private NoteDataStore mDataStore;
public BusinessLogicLayer(NoteDataStore dataStore){
this.mDataStore = dataStore;
//Do something useful with mDataStore
}
public void startBusinessLogic(){
//Do something useful with mDataStore
}
}
Suggest you use ID frameworks, like Guice and others. Not simply use Factory Pattern.
I want to intercept all method invocations to some class MyClass to be able to react on some setter-invocations.
I tried to use dynamic proxies, but as far as I know, this only works for classes implementing some interface. But MyClass does not have such an interface.
Is there any other way, besides implementing a wrapper class, that delegates all invocations to a member, which is an instance of the MyClass or besided using AOP?
As you note, you cannot use JDK dynamic proxies (no interface), but using Spring and CGLIB (JAR included with Spring), you can do the following:
public class Foo
{
public void setBar()
{
throw new UnsupportedOperationException("should not go here");
}
public void redirected()
{
System.out.println("Yiha");
}
}
Foo foo = new Foo();
ProxyFactory pf = new ProxyFactory(foo);
pf.addAdvice(new MethodInterceptor()
{
public Object invoke(MethodInvocation mi) throws Throwable
{
if (mi.getMethod().getName().startsWith("set"))
{
Method redirect = mi.getThis().getClass().getMethod("redirected");
redirect.invoke(mi.getThis());
}
return null;
}
});
Foo proxy = (Foo) pf.getProxy();
proxy.setBar(); // prints "Yiha"
If you are prepared to do something really ugly, have a look at:
http://docs.oracle.com/javase/7/docs/technotes/guides/jpda/
Basically the debugger interface ought to allow you to attach like a debugger, and hence intercept calls. Bear in mind I think this is a really bad idea, but you asked if it was possible.
Java doesn't have any actual language features for method interception (not sure any static language does)
I kinda like Nick's idea of using the debugger interface, that's just mean.
I think the short answer you need is: No there isn't a way of intercepting a method call in Java without actually replacing the class using a proxy or wrapper.
Note: The AOP libraries just make this happen automatically.
Some of the Java gurus might frown upon this but I've had some good success with avoiding primitive types and setters altogether. My class looks like this:
class Employee extends SmartPojo {
public SmartString name;
public SmartInt age;
}
You'll notice two things: 1. everything is public. 2. No constructor.
The magic happens in SmartPojo which searches for any field which implements the "Smart" interface and initializes it. Since this is no primitive (and no final class), I can add set() and get() methods for all fields anywhere in my model in a single place. So no setter/getter wastes anymore, it's stunningly simple to add notification (also in a single place), etc.
True, this is no POJO anymore and it's not a Bean in most ways but I've found that these old ideas limit me more than they help. YMMV.
I just developed a small framework for this purpose.
You can check it out at: http://code.google.com/p/java-interceptor/ (use svn to check out).
There isn't a lot of magic in AspectJ. You can write your own agent. http://java.sun.com/javase/6/docs/api/java/lang/instrument/package-summary.html seems to be good starting point.
Why cannot your class implement an interface? You could just extract some interface from it containing all the methods that you want to intercept and use the dynamic proxies mechanism easily. It's also a good programming practice to code with interfaces and not classes.
You could use Spring framework with Spring AOP capabilities (which are using dynamic proxies inside) to do it. You will just have to define your class as a Spring bean in the configuration file and clients of your class will have to either get its instance from the Spring application context or as a dependency automatically (by defining the setMyClass(MyClass mc) method for instance). From there you can easily go to defining an aspect that intercepts all the method calls to this class.