I was studying some tutorials concerning the Java language. I was wondering if I should abstract every time that I code something, and on any type of standard and stack?
I have seen that with every Spring Services for example, we could even abstract controllers, using interfaces with EJBs on JavaEE stack etc.
I was wondering what is the aim of that? Should I do the same thing while developing with the Android SDK?
Should I abstract every class that I code?
It is always a good idea to make modular, reusable components. When an app is built from the ground up with this in mind, it becomes more and more scalable, more and more self-extensible. The same components in an app get re-used as newer features are added, saving time and effort. And it becomes easier to make changes later on or identify sources of errors. Refactoring should never be afterwards, but from the beginning.
Having said that, it is not a great idea to have more and more abstractions in mobile apps just for the sake of "abstraction". The reason, of course, is that smart phones are not as powerful as servers or even desktop computers. There is a performance penalty associated with literally every class and virtual method in an Android app. There needs to be a greater balance between "abstraction" and efficiency, and the performance trade-offs become more visible on the medium and low-end devices.
From the official docs:
1. Be careful with code abstractions
2. Avoid dependency injection frameworks
3. Avoid Creating Unnecessary Objects
4. Prefer Static Over Virtual
5. Avoid Internal Getters/Setters
EDIT:
After having recently tried out Dagger, I have to admit that point 2 may be a bit outdated by now. What can I say ... I came to the Dagger party quite late.
You need abstraction whenever you have a class that you do not want to implement all of its methods. Those classes inheriting it will be forced to implement all those methods otherwise you would need to declare the subclasses as abstract as well.
In addition to that you should be aware of interface, methods of interface must not have body and the good thing is that your class can implement as much as interface as you want. Whereas, you can only inherit one abstract class. Interfaces are like contracts. Whichever class implement them need to provide body for all of their methods.
Whether you need abstract or interface or both is really depend on your design and what you want to implement. Although it is a good practice to force those classes that have common methods to implement the same interface ( if you do not know anything about body of each of the methods) or abstract ( if you know what the body of some, all or none of the methods)
Another example would be when you have abstraction or interface if you add something to them all the subclasses or classes that are implementing them need to follow those modifications, it means the could would be more easier to get modified.
Have a look at this, this and this and open/close principle as well.
This can be interpreted in many different ways. In my point of view, abstraction is used in coding as a design principle, in cases where you need an extension or many types of implementations. For eg, in Spring, a controller may have defined as an abstract class (A) and have several other types of controllers (B,C,D..) extending A. As a user of Spring framework, If you are not satisfy with the available controller implementations, still you can develop your own controller extending A. Also Spring developers too can extend / add new controllers in future releases with ease.
Reusability. Hands down!
If your class has a
Repetitive code
Non Repetitive codes for different scenarios.
Then it is a good idea to declare the class Abstract.
Put the repetitive code in the abstract class and create abstract methods for the code which is going to be different.
Here is an example.
Register and Unregister any BroadcastReceiver
Abstract class
public abstract class BaseReceiverActivity extends AppCompatActivity{
private BroadCastReceiver receiver;
private IntentFilter filter;
public abstract BroadCastReceiver getReceiver();
public abstract IntentFilter getFilter();
#Override
public void onStart(){
super.onStart();
configureReceiver()
registerReceiver(receiver, filter);
}
#Override
public void onStop(){
super.onPause();
unregisterReceiver(receiver);
}
private void registerMyReceiver(){
registerReceiver(receiver, filter);
}
private void configureReceiver(){
receiver = getReceiver();
filter = getFilter();
}
}
Implementation class:
public class WifiScanner extends BaseReceiverActivity{
#Override
public void onCreate(Bundle sis){
super.onCreate(sis);
setContentView(R.layout.yourLayout);
}
#Override
public BroadCastReceiver getReceiver(){
return new YourReceiver();
}
#Override
public IntentFilter getFilter(){
return IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
}
}
Related
I am programming in java for a while not much used interface. I just wondering what are the benefits of using interface. I read a article about loose coupling it states that
Tight coupling makes it much harder to add new functionality. With loose coupling, you can swap out components easily. This also makes your system more scalable as your system grows. Using loose coupling, you can safely write additional code when adding new features to your system without breaking the existing functionality.
After reading this i understood that the key take away is classes/components can be swapped easily and it helps to achieve code extensibility without breaking the existing functionality. code swapping makes sense but code extensibility without breaking changes doesn't makes sense to me.
I tried creating a interface called Player at first.
public interface Player {
void play();
}
After creating this interface i had implemented the contracts of this interface
public class BlackPlayer implements Player{
#Override
public void play() {
System.out.println("playing videos from black player");
}
}
Finally i had created a VideoPlayer class and the constructor takes Player implemented classes.
public class VideoPlayer {
private Player videoplayer;
VideoPlayer(Player videoplayer){
this.videoplayer = videoplayer;
}
void playVideo(){
videoplayer.play();
}
}
In the main method i am creating the Videoplayer instance and using its functionality
class Main{
public static void main(String[] args) {
VideoPlayer player = new VideoPlayer(new BlackPlayer());
player.playVideo();
}
}
Java Interface helps to achieve code extensibility without breaking changes, easy implementation swapping and easy unit testing(exclude about testing for now).
In future i planned to add different player i can easily swap its implementation by other class which implement the contracts of Player lets call it as Redplayer. Now i can easily swap the implementation by this line of code
Before - VideoPlayer player = new VideoPlayer(new BlackPlayer());
After- VideoPlayer player = new VideoPlayer(new RedPlayer());
Correct me if i told anything wrong about implementation swapping.
Now the second thing which confused me alot.
Interface help to achieve extensible code without breaking its functionality.
Again in future all my app users are requesting a pause feature which is already in production. Now i am trying to add the additional contracts to the already created interface.
public interface Player {
void play();
void pause();
}
After adding this pause contract all the class which implements Player showing error that override missing for pause. By introducing the pause contract broken my existing class.
Then how can i achieve code extensibility without breaking existing functionality. How can i scale the application with new features?
Adding a new method to an interface will break compilation for all the existing implementations of that interface. This is why for many years Java did not add any functionality to its core library classes like Collections. In Java 8 they added the ability to add a default implementation of an interface method so they could then add new methods to Collections interfaces without breaking compilation for everyone upgrading.
So to answer your question, you can always add a new method to an interface and give it a default implementation and you would not be breaking any of your existing code. The second way you can do this is to create a new interface called PausablePlayer which has the pause method. In Java you can implement multiple interfaces, so any implementations which support pause could implement that new interface in addition to the existing one. This approach works best when you want to add functionality which only applies to certain implementations but not all.
I have an interface like so
public interface Manager {
public void manage();
}
Now, all Managers will need to load work to manage, however, I have mixed feelings about adding public void loadWork() to the interface...
On one hand, all Managers will do this, but on the other hand, users of a Manager class will not need to know about loadWork().
Question: Is it bad practice to add "helper" or "setup" type methods to an interface?
It's not always a bad idea to add "setup" methods in an interface. For example, Java EE has an interface called ServletContextListener that is purely meant to make setup and shut down.
It's even sometimes acceptable to make interfaces with methods you should actually never directly call such as the Runnable or the Callable interface.
Being said that, it seems is that you want to force your developers to implement a loadWork() method in Manager but you also want to hide it from the class' users.
As you say, one option is adding the method in the interface but this way the method will be accessible (which you don't want). If you don't want the method to have visibility I see two options:
Make the class Manager an abstract class and add a loadWork() protected method.
Create an interface called LoadWorker with a method loadWork(). Then create an abstract class AbstractManager that implements Manager and has as a private/protected LoadWorker field. This way, even though loadWork() is public, it's not accessible from AbstractManager's users as it is called through a protected/private field (LoadWorker).
At the end it comes to a balance between overengineering and good design. It's up to you to take the decision following the specific needs. Nevertheless, there is no 'perfect solution'.
I need to proxy methods on various view classes in the Android UI Framework such as TextView. Particularly TextView#setText(int resId). This method is not part of an interface. Therefore, Java Proxy will not work since it only works for interfaces. I need to use bytecode manipulation.
I found a library called dexmaker that seemed promising. I am assuming that I need to do runtime byte code manipulation since the Android View classes are only actually available on the device. Dexmaker can proxy public methods on concrete classes. Then I noticed that TextView#setText(int resId) is inexplicably final. The TextView class itself is non-final.
I think I could fork dexmaker to support final methods in non-final classes. Is this possible? I don't want to start this project if it isn't. It would be a huge win for my library though because developers would not need to have subclasses, interfaces, or manual static method calls for their views. My library needs to know when text is set on particular View. A proxy is the perfect design pattern for this.
As far as I know, this is not possible on Android.
Dexmaker creates dex files that contain new classes. These classes are then added to an application by using dex class loaders. Such dex files can however not be used to replace classes, only to add new subclasses that serve as a proxy.
In this sense, dexmaker is rather like cglib than javassist.
Note that Android does neither provide similar instrumentation capabilities as a regular Jvm where you can instrument final classes and methods by class redefinition via an agent. This is not provided by Android: http://developer.android.com/reference/android/app/Instrumentation.html
The intent of "final" is that the method cannot be overridden. That effectively puts a halt to proxying by extension. However, you can still proxy by wrapping, the way Spring handles it.
That is one reason why it is a best practice to separate the interface from the implementation.
In more concrete terms ...
// This snip is not supposed to be functional, only to demonstrate a concept
interface TextViewInterface {
void setText (int resId);
}
class TextView implements TextViewInterface {
public final void setText (int resId) {
... snip ...
}
}
class Proxy$TextView implements TextViewInterface
extends View { // Added this for Android hierarchy
private TextView textView;
public void setText (int resId) {
textView.setText(resId);
}
}
Does this help?
I am trying to create a simple game that can work in different platforms as a proof of concept. For now I am happy to have it working for both J2SE (using AWT or Swing) and Android. I decided to use Java for the logic of the game as both platforms expects Java code. The idea is creating a set of interfaces to abstract the OS and have a clean straight-forward game logic using these interfaces. And having 2 implementations of these interfaces, one per platform.
Some code to describe what I mean:
public class MyGameLogic implements GameLogic {
private GameSprite _sprite;
#Override
public void init(GamePlatform platform) {
_sprite = platform.loadSprite("arena");
}
#Override
public void draw(GameCanvas canvas) {
canvas.drawSprite(_sprite, 100, 200);
}
}
Here GamePlatform, GameSprite and GameCanvas would be interfaces. These interfaces will be implemented in a different way for the different platforms depending on the platform capabilities and APIs. In a similar way, GameLogic is an interface that is implemented by the game logic and not the platform. The platform will use the GameLogic interface to initialise the logic and redrawing every time is required, but more method are expected to be added in the future.
Even if I think this option is great, I see 2 flows in this design:
* the game logic can create its own implementation of GameSprite and call drawSprite() with it, which is not expected by the platform implementation.
* the implementation of the platforms must cast back all the interfaces in order they can access the real data inside the GameSprite. So if the GameSprite returned in loadSprite for J2SE is in reality a J2SESprite class, which implements GameSprite, when calling draw() I should cast the GameSprite back to J2SESprite.
In order to solve the problem I thought in adding generics, but it will make the code really ugly, here is the same code with generics.
public class MyGameLogic<
Sprite extends GameSprite,
Platform extends GamePlatform,
Canvas extends GameCanvas>
implements GameLogic<Platform, Canvas> {
private Sprite _sprite;
#Override
public void init(Platform platform) {
_sprite = platform.loadSprite("arena");
}
#Override
public void draw(Canvas canvas) {
canvas.drawSprite(_sprite, 100, 200);
}
}
This way, the game logic will not be able to call new Sprite(), as it is a generic type nor extending it, which solves the first problem, and we do not need to cast it back as the generics will provide the proper type. The problem is that I have to add the generics in all my game logic classes, and there is a generic parameter for each interface, and can be a lot at the end.
Is there any better solution? Any design pattern I am not aware of that I can use for this purpose?
Thanks!
You have one game that might have two or more user interfaces ( Swing, Android). For business applications it is common to separate the user interface from the business logic. The business logic is placed in a service layer, which is an internal API used just by the user interface code. The service layer manipulates and provides domain objects that represent what the program is about. The user interface code is placed in a separate presentation layer. It translates user inputs into calls to the service layer and translates domain objects returned from theservice layer into user interface changes.
You could use a similar design. You would have different implementations of the presentation layer (for Swing and Android) but the same service layer.
Introduction
I am trying to make a rather complex structure in Java with interfaces, abstract classes and generics. Having no experience with generics and only average experience with creating good OOP designs, this is beginning to prove quite a challenge.
I have some feeling that what I'm trying to do cannot actually be done, but that I could come close enough to it. I'll try to explain it as brief as I can. I'm just going to tell straight away that this structure will represent my DAO and service layers to access the database. Making this question more abstract would only make it more difficult.
My DAO layer is completely fine as it is. There is a generic DAO interface and for each entity, there is a DAO interface that extends the generic one and fills in the generic types. Then there's an abstract class that is extended by each DAO implementation, which in turn implement the corresponding interface. Confusing read for most probably, so here's the diagram showing the DAO for Products as an example:
Now for the service classes, I had a similar construction in mind. Most of the methods in a service class map to the DAO methods anyway. If you replace every "DAO" in the diagram above with "Service", you get the basis for my service layer. But there is one thing that I want to do, based on the following idea I have:
Every service class for an entity will at least access one DAO object, namely the DAO of the entity that it is designed for.
Which is...
The question/problem
If I could make a proper OO design to make each service class have one instance variable for the DAO object of their respective entity my service layer would be perfect, in my view. Advice on this is welcome, in case my design is not so good as it seemed.
I have implemented it like this:
Class AbstractService
public abstract class AbstractService<EntityDAO> {
EntityDAO entityDAO;
public AbstractService() {
entityDAO = makeEntityDAO(); //compiler/IDE warning: overridable method call in constructor
}
abstract EntityDAO makeEntityDAO();
}
Class ProductServiceImpl
public class ProductServiceImpl extends AbstractService<ProductDAOImpl> {
public ProductServiceImpl() {
super();
}
#Override
ProductDAOImpl makeEntityDAO() {
return new ProductDAOImpl();
}
}
The problem with this design is a compiler warning I don't like: it has an overridable method call in the constructor (see the comment). Now it is designed to be overridable, in fact I enforce it to make sure that each service class has a reference to the corresponding DAO. Is this the best thing I can do?
I have done my absolute best to include everything you might need and only what you need for this question. All I have to say now is, comments are welcome and extensive answers even more, thanks for taking your time to read.
Additional resources on StackOverflow
Understanding Service and DAO layers
DAO and Service layers (JPA/Hibernate + Spring)
Just a little note first: usually in an application organized in layers like Presentation / Service / DAO for example, you have the following rules:
Each layer knows only the layer immediately below.
It knows it only by it's interfaces, and not by it's implementation class.
This will provide easier testing, a better code encapsulation, and a sharper definition of the different layers (through interfaces that are easily identified as public API)
That said, there is a very common way to handle that kind of situation in a way that allow the most flexibility: dependency injection. And Spring is the industry standard implementation of dependency injection (and of a lot of other things)
The idea (in short) is that your service will know that it needs a IEntityDAO, and that someone will inject in it and implementation of the interface before actually using the service. That someone is called an IOC container (Inversion of Control container). It can be Spring, and what it does is usually described by an application configuration file and will be done at application startup.
Important Note: The concept is brilliant and powerful but dead simple stupid. You can also use the Inversion of Control architectural pattern without a framework with a very simple implementation consisting in a large static method "assembling" your application parts. But in an industrial context it's better to have a framework which will allow to inject other things like database connection, web service stub clients, JMS queues, etc...
Benefits:
Your have an easy time mocking and testing, as the only thing a class depends on is interfaces
You have a single file of a small set of XML files that describe the whole structure of your application, which is really handy when your application grows.
It's a very widely adopted standard and well - known by many java developers.
Sample java code:
public abstract class AbstractService<IEntityDAO> {
private IEntityDAO entityDAO; // you don't know the concrete implementation, maybe it's a mock for testing purpose
public AbstractService() {
}
protected EntityDAO getEntityDAO() { // only subclasses need this method
}
public void setEntityDAO(IEntityDAO dao) { // IOC container will call this method
this.entityDAO = dao;
}
}
And in spring configuration file, you will have something like that:
<bean id="ProductDAO" class="com.company.dao.ProductDAO" />
[...]
<bean id="ProductService" class="com.company.service.ProductService">
<property name="entityDAO" ref="ProductDAO"/>
</bean>