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.
Related
Recently, when I ask how to make methods thread-safe in singleton pattern, someone told me that using an enum version singleton pattern is a good option. and by multiple threads. If the method has side effects (changes the state of some variable) then you need to think about protecting it (make it synchronized) or parts thereof. So I write code like this:
public enum ReStation {
INSTANCE;
private List<Email> emailList;
private ReStation() {
emailList = new ArrayList<>();
}
public synchronized void recycleEmail(Email email) {
System.out.println("Recycle station recycleing the email: "
+ email.getContent());
emailList.add(email);
}
public synchronized void deleteEmail(Email email) {
emailList.remove(email);
}
public synchronized void clear() {
emailList.clear();
}
}
however, when I read the book named "Design Pattern-Elements of Reusable Object-Oriented Software", I come across such a paragraph as below :
Applicability
Use the Singleton pattern when
• there must be exactly one instance of a class, and it must be accessible to
clients from a well-known access point.
• when the sole instance should be extensible by subclassing, and clients
should be able to use an extended instance without modifying their code.
Given an enum can't be extended, I am really confused about How could I use an extended instance without modifying their code while using an enum version singleton pattern? is modifying singleton class codes the only way to extend the functionality of the singleton?
When the quote says the "sole instance should be extensible by subclassing", they are talking about situations where:
You need a single distinguished instance of a base class or interface, with a well-known access point, like the process Logger;
You need to choose the concrete implementation at runtime, for example based on configuration or other runtime information. Your process Logger, for example, could be implemented by FileLogger or ConsoleLogger. Usually, it should be possible to use any Logger subclass to implement the system logger.
You can't do this with the "enum version singleton pattern".
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.
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.
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'm reading J. Bloch's effective Java and he said the following:
Once an interface is released and widely implemented, it is almost
impossible to change.
So, now consider the simple interface for DAO-pattern:
public interface UserDao{
public User getById(int id);
public Collection<User> getAll();
public boolean delete(int userId);
public boolean update(User u);
}
This is how my Dao interface looked when it was released firstly. By the time, I had to add some functionality to users in order to aggregate all users by its registration_date or something similar. So, I needed to add corresponding method declarations to the DAO-interface and implement it.
Moreover for now I can't imagine how DAO-interfaces may be more or less stable at all, because adding some new DAO-operations happens very often.
Maybe it's my DAO design disaster, or interfaces are hardly suitable for DAOs?
I think that sentence of J. Bloch is meant to public interfaces, and not for your DAO case.
Think of you creating a public API to let any programmer use your platform. If you are changing that interface, your are requiring programmers to adapt his code, so this will be frustrating.
But if you are creating an interface for the purpose of your internal app, you are not assuming that risk, and it is worth to evolve your interface as you need.
Obviously you have to consider how many classes implements your interface and assume the cost of the modification.