Let's say I have a LibImplementationA that includes a LibInterfaces.
LibImplementationA contains the implementations of LibInterfaces's java interfaces .
My application uses the interfaces from LibInterfaces and the implementations from LibImplementationA.
I included LibImplementationA in my app, and I thought I could use the interfaces from LibInterfaces in my app's code. But I couldn't !
Why ?
To make my app work, I must include LibImplementationA and LibInterfaces.
So LibInterfaces is duplicated (in LibImplementationA and my app), and this seems really bad (in case of the update of LibInterfaces)
Last but not least, in my app I want to be able to switch from using LibImplementationA to LibImplementationB or LibImplementationX (that's why the app uses LibInterfaces).
My real problem is way more complex, but I need a clever idea to avoid duplications of this LibInterfaces, if possible!
I'm using Android Studio, with gradle.
Edit: for a better understanding, LibInterfaces contains communication interfaces (as simple as sendMessage(), messageReceived() methods) and LibImplementationX implements those methods using SIP, XMPP, WebSocket, Whatever.
The answer of "Why" - LibInterfaces could be protected/default scope interface & couldn't be implemented outside of that specific package.
Related
I'm looking for different ways to prevent internals leaking into an API. This is a huge problem because once these internals leak into the API; you can run either into unexpected incompatibility issues or into frozen internals.
One of the simplest ways to do so is just make use of different Maven modules; one module with API and one module with implementation. This way it is impossible to expose the implementation from the API.
Unfortunately not everyone agrees this is the best approach; But are there other alternatives? E.g using checkstyle or other 'architecture checking' tools?
PS: Java 9 for us is not usable, since we are about to upgrade to Java 8 and this will be the lowest supporting version for quite some time to come.
Following your checkstyle idea, it should be possible to set up rules which examine import statements in source files.
Checkstyle has built-in support for that, specifically the IllegalImport and ImportControl rules.
This of course works best if public and internal classes can be easily separated by package names.
The idea for IllegalImport would be that you configure a TreeWalker in checkstyle which only looks at your API-sources, and which excludes imports from internal packages.
With the ImportControl rule on the other hand you can define very detailed access rules for the whole application/module in a separate XML file.
It is standard in Java to define an API using interfaces and implement them using classes. That way you can change the "internals" however you want and nothing changes for the user(s) of the API.
One alternative is to have one module (Jar file) for API and implementation (but then again, is it an API or just any kind of library?). Inside one separates classes and interfaces by using packages, e.g. com.acme.stuff.api and com.acme.stuff.impl. It is important to make classes inside the latter package protected or just package-protected.
Not only does the package name show the consuming developer "hey, this is the implementation", it is also not possible to use anything inside (let's omit reflections at this point for the sake of simplicity).
But again: This is against the idea of an API, because usually the implementation can be changed. With this approach one cannot separate API from implementation, because both are inside the same module.
If it is only about hiding internals of a library, then this is one (not the one) feasible approach.
And just in case you meant a library instead of an API, which only exposes its "frontend" (by using interfaces or abstract classes and such), use different package names, e.g. com.acme.stuff and com.acme.stuff.internal. The same visibility rules apply of course.
Also: This way one does not need Checkstyle and other burdens.
Here is a good start : http://wiki.netbeans.org/API_Design
Key point : Do not expose more than you want Obviously the less of the implementation is expressed in the API, the more flexibility one can have in future. There are some tricks that one can use to hide the implementation, but still deliver the desired functionality
I think you don't need any checkstyle or anything like that, just a good old solid design and architecture should be enough. Polymorphism is all you need here.
One of the simplest ways to do so is just make use of different Maven
modules; one module with API and one module with implementation. This
way it is impossible to expose the implementation from the API.
Yes, I totally agree, hide as much as possible, separate your interface in a standalone project.
I'm trying to do something clever. I am creating a weather application in which we can replace the weather API with another weather API without affecting the code base. So I started with a Maven project with multiple modules.
I have a Base module that contains the Interface class and the Base class. The Interface class contains the calls to the APIs (all calls are similar, if not exact) and the Base class contains the properties to the APIs (again, all properties are similar, if not exact).
I have a module for each of the two weather APIs we are testing with plans to create more modules for new weather APIs as we grow the application.
Finally, I have created a Core module (includes main) to implement the specific module class for the weather API I want to test.
Now, I know the simplest way to do this would be to use a switch statement and enumeration. But I want to know if there is a more clever way to do this. Maybe using a Pattern? Any suggestions?
Here is a picture of the structure I have just described:
Here is the UML representation:
This is a learning process for me. I want to discover how a real Java Guru would implement the appropriate module and class based on a specified configuration.
Thank you for your suggestions.
I'm trying to do something clever. I am creating a weather application
in which we can replace the weather API with another weather API
without affecting the code base.
Without reading further down, this first statement makes me think about a plugin architecture design, but in the process of software design, decisions must not be rushed, the more you delay, the more information you have and a better informed decision can be made, for now is just an idea to keep in mind.
I have a Base module that contains the Interface class and the Base
class. The Interface class contains the calls to the APIs (all calls
are similar, if not exact) and the Base class contains the properties
to the APIs (again, all properties are similar, if not exact).
When different modules share behaviour/state, it is a good idea to refactor them and produce base abstract classes and interfaces, so you are on the right track, but, if there are differences, those shouldn't be refactored into the base module. The reason behind that is simple, maintainability. If you start adding if clauses or switches to deal with these differences, you just introduced coupling between modules, and you'll be always having to make changes in the base module, whenever you add/modify other modules, and this is not desirable at all.
This is reflected by the Open/Closed principle form the SOLID principles, which states that a class should be open for extension but closed for modifications.
So after you've refactored the common behaviour into the base modules, then each new API should extend the base module, as you did.
Finally, I have created a Core module (includes main) to implement the
specific module class for the weather API I want to test.
Now, I know the simplest way to do this would be to use a switch
statement and enumeration. But I want to know if there is a more
clever way to do this. Maybe using a Pattern? Any suggestions?
Indeed, making use of a switch, makes it work, but its not a clean design at all, for the same reason as before, when adding, modifying or removing modules, would require to modify this module aswell, and also this code can potentially break.
One possible solution, would be to delegate this responsability on a new component and make use of a creational design pattern like the Abstract Factory, which will provide a interface to instantiate components without specifying its classes.
As for the architecture, so far, the plugin architecture still makes sense, but what if the different modules extend the base contract adding more features? One option is to use the Facade pattern to adapt the module calls and provide an output that implements an interface that clients expect.
But then again, with the provided details, this is the solution I'd suggest, but the scenario should be studied carefully and in greater detail, in order to be able to assure that these are the right tools for the job, and commit to them.
In addition to Salvador Juan Martinez's answer...
To implement a plugin architecture Java's Jar File Specification provides support for service provider interfaces (SPI) and how they are looked up.
As of Java 1.6. you can use the ServiceLoader to lookup service providers. For Java 1.5. and less you must do it on your own or use a library. E.g. commons-discovery.
The usage is quiet simple. In your case put a META-INF/services/com.a2i.weatherbase.IWeather file in each plugin module.
In the Weather Forecast IO module the file should contain only one line
com.a2i.weatherforecastio.ForecastIO
The line must be the full quallified name of an IWeather implementation class.
Do the same for the other module and you can load the implementations via ServiceLoader.
ServiceLoader<IWeather> weatherServicesLoader = ServiceLoader.load(IWeather.class);
Iterator<IWeather> weatherServices = weatherServicesLoader.iterator();
Now it depends on your runtime classpath how many services will be found. Try to add and remove module jar archives from the classpath and run your application.
EDIT
I wrote a blog about a pluggable architecture with standard java. See http://www.link-intersystems.com/blog/2016/01/02/a-plug-in-architecture-implemented-with-java/
Source code is also available at https://github.com/link-intersystems/blog/tree/master/java-plugin-architecture
One solution is you have to define the common interface with all the identified common operations. The extensions/plugins need to implement that interface and have to provide the implementation to common operations.
You can use an abstract factory design pattern to hook up the exact implementation at runtime based on the input parameters.
Interfaces and abstract classes are always good in such scenarios, Thanks.
The question I'm asking is about a very frequent topic but I didn't find my exact question so I'm asking it explicitly.
I'm programming in java and I need to implement some classes, let's say A, B, C and D.
They are all part of an SDK and only D will be public (visible to the developer that will use my sdk).
A, B & C are classes dealing with different topics (let's say Bluetooth communciation, web services use & proprietary algorithms) although they need to communicate each other.
I'd like to divide classes in packages according to their "skill" (Public methods, Bluetooth, Web Services, Algorithms) but if I create different packages they won't be visible each other.
So, the only implementation I see here is a unique package and no modifier (so they will "see" each other and the user will only access to Class D).
Is there any way to create different packages in order to let me organize my sdk in a better way? (imagine a lot of classes, it could easily become a mess :) )
Thanks in advance for your help
Giorgio
If I understand what you're trying to do, I don't think the Java language gives you a way to do it.
My understanding of your question is "I am developing an API in which I want to expose only certain classes and/or methods; other classes and/or methods in the package need to be used by the exposed ones, but I do not want them to be marked public and therefore available to a programmer using the API".
You don't say why this is necessary, or desirable.
The language does not support visibility this way. You could possibly run the code you want to hide through an obfuscator, to (greatly) discourage anyone from understanding what those methods are and calling them, and of course not obfuscate the ones you want used, but that's as close as I can come up with.
I think the correct way to do this is to have a package which holds common interfaces and data (such as enums, simple classes such as Point etc...).
All other packages will refrence this common package,
where as their classes will implement the common interfaces.
This also gives you the benefit of true decoupling between the different packages.
You can use different packages for you classes, Just be sure they are public so they can be visible for other classes in other packages.
Converting an existing Android application to a library is incredibly simple: All I have to do is check the is Library checkbox in the project's properties.
However, once this easy step has been applied, a much more serious task lies ahead: How to retain the original application code unchanged (as a library!), while building different applications based on it.
That is, I don't really want to add another activity, but rather re-use the original activity (now in a library), where only a few methods (in the one-and-only activity) are different in each derived application.
Is the solution really is as simple as subclassing the library's activity in each application based on it?
What caveats should I watch for?
Is there a better approach?
You will mostly have to derive new classes from the ones included in the librairy or call their methods. If your librairy has classes such as activities, applications, you can extends them has you said.
Another solution could be to isolate the code you want to reuse and plugit into other activities by dependency injection. But this framework seems an overkill to me where you can just derive new classes.
A more android specific problem could be : how to call my new activities from within my new applications. The answer here relies in intent and to use different action names to call for the extended activities.
Regards,
Stéphane
Since the whole Android stuff is open source I was thinking about to do some minor modifications in a few internal classes from the com.android.internal.telephony package and of course then I would love if somehow my application could use the modified classes. I was thinking about replacing the classes with the original ones at runtime by using reflection or other kind of unknown java tricks :D ...maybe what I'm trying to do is impossible :( I don't know that's why I'm asking.
Note: The changes in the internal classes would not change their functionality in any way, its more about extending their functionality so even if other apps would use the modified versions it would not break them!
Why I want to do it? What I'm trying to achieve ?
Well i would like to modify the com.android.internal.telephony.gsm.CallTracker internal class so i could do proper call handling (call blocking etc..)
Maybe if you know about another way how to do what I want to I would like to hear about it :)
Note2: I know about the method when you handle the android.intent.action.PHONE_STATE, action , but its simply too late to react when this action is broadcasted. I'm really looking for a better solution even if that solution involve ugly hacks :)
As always thanks for all your replies...
You cannot do this :) I'll let you imagine what would happen if any application was allowed to freely replace core parts of the system. You can download the Android source code and you can modify it and you can upload the modifications to your phone (if your phone is rooted/unlocked) but you cannot apply such modifications with a simple app.
Changing a classes functionality (methods, byte code) after a class ha been loaded is impossible. Reflection/Invocation does not affect classes but static fields and instances only.
Your looking at a way to add additional methods or change existing methods of a running system, because the classes in question probably will be loaded already when your 'hacking' application is executed.
The only technical approach that I see is to change the classes in advance and deploy a modified system. I'm just ignoring possible licensing issues and security at the moment. But even with this way, your software would depend on a custom OS, a branch from some andorid version, disconnected from official updates, and you'd have to ask your customers to install a custom OS with, say, unknown features.
Sidenote - I'm very happy, that this is really impossible, otherwise my mobile would already be full of trojans, viruses, etc...
Romain is correct you can't and shouldn't try to change existing system classes.
That said, implementing call screening as you suggest should be possible by creating a replacement to the dialer application that handles phone calls.
Specifically the intent ACTION_ANSWER should be handled by your application, which could then either implement a dialer-like interface or open the dialer app (or any other call manager) explicitly.
There are actually ways to hack on Android framework classes, it just depends on which ones you want to hack.
You must extend the class you intent to hack on.
If you want to override package private methods and/or access package private variables you can put your class in the same package.
You can use reflection.
I've actually had to do this to work around bugs. Romain is correct, to an extent. It all depends on the structure of the code you are trying to hack on. You definitely can't hack on Android internals, but you can hack on other framework classes like Activity, View, etc.