Nowadays we are on writing some core application that is all other application will be relying on. Without further due let me explain the logic with some codes,
We used to have a single java file that was 1000+ lines long and each application was having it as class inside, so when there was a change, each application had to edit the java file inside of it or simply fix one and copy to all. This is hard to implement as much as it is hard to maintain. Then we end-up with creating this as a separate application that is divided to smaller part, which is easy to maintain and also a core maybe a dependency to other application so we fix in one place and all other code applications are fixed too.
I've been thinking for a some great structure for this for a while want to use a builder patter for this as below
TheCore theCore = new TheCore().Builder()
.setSomething("params")
.setSomethingElse(true)
.build();
The problem arises now. Like so, I initialized the object but now I'm having access to that objects public class only. This application actually will have many small classes that has public functions that I don't want them to be static methods that can be called everytime. Instead I want those methods to be called only if TheCore class is initilized like;
// doSomething() will be from another class
theCore.doSomething()
There are some ideas I produced like
someOtherClass.doSomething(theCore)
which is injecting the main object as a parameter but still someOtherClass needs to be initialized or even a static method which doesn't make me feel comfortable and right way to that.
Actually I do not care if initializing TheCore would bring me a super object that includes all other classes inside initialized and ready to be accessed after I initialized TheCore. All I want in this structure to have a maintainable separate app and methods avaiable if only the main object which is TheCore is this circumstances is initialized.
What is to right way to achive it? I see that Java does not allow extending multiple classes even it if does, I'm not sure it that is right way...
Thanks.
After spending significant amount of time of thought I ended up that
// doSomething() will be from another class
theCore.doSomething()
is not suitable since many java classes could possibly have identical method names. So...
// doSomething() will be from another class
theCore.someOtherClass.doSomething()
would be a better approach.
To make it easier to understand I'll have to follow a complex path to explain it which is starting from the package classes first.
Think that I have a package named Tools and a class inside SomeFancyTool
main
└─java
└─com
└─<domainName>
├─Tools
| └─SomeFancyTool.java
└─TheCore.java
Now this SomeFancyTool.java must have a default access level which is actually package level access, because I don't want this classes to be accessed directly;
SomeFancyTool.java
package com.<domainName>.Tools
class SomeFancyTool{
public String someStringMethod(){
return "Some string!";
}
public int someIntMethod(){
return 123;
}
public boolean someBooleanMethod(){
return true;
}
}
So now we have the SomeFancyTool.java class but TheCore.java cannot access it since it is accesible through its Tools package only. At this point I think of an Initializer class that is gonna be in the same package, initialize these private classes and return them with a function when called. So initiliazer class would look like this;
ToolsInitializer.java
package com.<domainName>.Tools
public class ToolsInitializer{
private SomeFancyTool someFancyTool = new SomeFancyTool();
public SomeFancyTool getSomeFancyTool(){
return someFancyTool;
}
}
Since ToolsInitializer.java can initialize all functional private classes inside in Tools package and also can return them as objects to outside of the package scope, still we are not able to use these methods as we cannot import com.<domainName>.SomeFancyTool from TheCore.java because it is package wide accessible. I think here we can benefit from implementation of the java interface. A class that is not functional alone, so no problem even if it is accessed since it's methods will be nothing but declarations.
At this point I'll rename SomeFancyTool.java to SomeFancyToolImplementation.java which it will be implementing the interface and call SomeFancyTool.java to the interface itself.
SomeFancyTool.java (now as an interface)
package com.<domainName>.Tools
public interface SomeFancyTool{
public String someStringMethod();
public int someIntMethod();
public boolean someBooleanMethod();
}
and lets rename prior SomeFancyTool.java and implement the interface
SomeFancyToolImplementation.java (renamed)
package com.<domainName>.Tools
class SomeFancyToolImplementation implements SomeFancyTool{
#override
public String someStringMethod(){
return "Some string!";
}
#override
public int someIntMethod(){
return 123;
}
#override
public boolean someBooleanMethod(){
return true;
}
}
Now our structure has become like this with the final edits;
main
└─java
└─com
└─<domainName>
├─Tools
| ├─SomeFancyTool.java
| ├─SomeFancyToolImplementation.java
| └─ToolsInitializer.java
└─TheCore.java
Finally we can use our TheCore.java class to call all initializer classes with their methods to receive all these private classes inside as an object. This will allow external apps to call and initialize TheCore first to be able to access other methods.
TheCore.java
public class TheCore{
private SomeFancyToolImplementation someFancyTool;
public static class Builder{
private SomeFancyToolImplementation someFancyTool;
public Builder(){
ToolsInitializer toolsInitializer = new ToolsInitializer();
someFancyTool = toolsInitializer.getSomeFancyTool();
}
public Builder setSomeValues(){
//some values that is needed.
return this;
}
public Builder setSomeMoreValues(){
//some values that is needed.
return this;
}
public TheCore build(){
TheCore theCore = new TheCore();
theCore.someFancyTool = someFancyTool;
return theCore;
}
}
}
All Done and it is ready to use. Now the functional package classes and its methods that it relying on if TheCore is initialized or not, cannot be accessed with out TheCore. And simple usage of this Library from a 3rd Party app would simply be;
3rd Party App
TheCore theCore = new TheCore.Builder()
.setSomeValues("Some Values")
.setMoreSomeValues("Some More Values")
.build();
theCore.someFancyTool.someStringMethod();
Note: Note that a the ToolsInitializer.java is still accessible and could be used the get private method without first calling TheCore but we can always set a checker inside getSomeFancyTool() method to throw error if some prerequisites are not satisfied.
I do not still know if this is a functional structural pattern to use or its just some hard thoughts of mine. And don't know if some pattern is already exist that I just could not see yet but this is the solution I end up with.
Let's say I have 1 complete class with around 20 methods which provide different functionalities.
Now we have multiple clients using this class, but we want them to have restricted access.
For e.g. -
Client 1 - Gets access to method1/m3/m5/m7/m9/m11
Client 2 - Gets access to method2/m4/m6/m8/m10/m12
Is there any way I can restrict this access?
One solution which I thought:
Create 2 new classes extending Parent class and override methods which are not accessible and throw Exception from them.
But then if 3rd client with different requirement, we have to create new subclass for them.
Is there any other way to do this?
Create 2 new classes extending Parent class and override methods which
are not accessible and throw Exception from them. But then if 3rd
client with different requirement, we have to create new subclass for
them.
It is a bad solution because it violates Polymorphism and the Liskov Substitution Principle. This way will make your code less clear.
At first, you should think about your class, are you sure that it isn't overloaded by methods? Are you sure that all of those methods relate to one abstraction? Perhaps, there is a sense to separate methods to different abstractions and classes?
If there is a point in the existence of those methods in the class then you should use different interfaces to different clients. For example, you can make two interfaces for each client
interface InterfaceForClient1 {
public void m1();
public void m3();
public void m5();
public void m7();
public void m9();
public void m11();
}
interface InterfaceForClient2 {
public void m2();
public void m4();
public void m6();
public void m8();
public void m10();
public void m12();
}
And implement them in your class
class MyClass implements InterfaceForClient1, InterfaceForClient2 {
}
After it, clients must use those interfaces instead of the concrete implementation of the class to implement own logic.
You can create an Interface1 which defines methods only for Client1, and an Interface2 which defines methods only for Client2. Then, your class implements Interface1 and Interface2.
When you declare Client1 you can do something like: Interface1 client1.
With this approach, client1 can accesses only methods of this interface.
I hope this will help you.
The other answers already present the idiomatic approach. Another idea is a dynamic proxy decorating the API with an access check.
In essence, you generate a proxy API that has additional checks on method calls to implement a form of Access Control.
Example Implementation:
package com.example;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
#FunctionalInterface
public interface ACL<P, Q> {
boolean allowed(P accessor, Q target, Method method, Object[] args);
class ACLException extends RuntimeException {
ACLException(String message) {
super(message);
}
}
#SuppressWarnings("unchecked")
default Q protect(P accessor, Q delegate, Class<Q> dType) {
if (!dType.isInterface()) {
throw new IllegalArgumentException("Delegate type must be an Interface type");
}
final InvocationHandler handler = (proxy, method, args) -> {
if (allowed(accessor, delegate, method, args)) {
try {
return method.invoke(delegate, args);
} catch (InvocationTargetException e) {
throw e.getCause();
}
} else {
throw new ACLException("Access denies as per ACL");
}
};
return (Q) Proxy.newProxyInstance(dType.getClassLoader(), new Class[]{dType}, handler);
}
}
Example Usage:
package com.example;
import java.lang.reflect.Method;
public class Main {
interface API {
void doAlpha(int arg);
void doBeta(String arg);
void doGamma(Object arg);
}
static class MyAPI implements API {
#Override
public void doAlpha(int arg) {
System.out.println("Alpha");
}
#Override
public void doBeta(String arg) {
System.out.println("Beta");
}
#Override
public void doGamma(Object arg) {
System.out.println("Gamma");
}
}
static class AlphaClient {
void use(API api) {
api.doAlpha(100);
api.doBeta("100");
api.doGamma(this);
}
}
public static class MyACL implements ACL<AlphaClient, API> {
#Override
public boolean allowed(AlphaClient accessor, API target, Method method, Object[] args) {
final String callerName = accessor.getClass().getName().toLowerCase();
final String methodName = method.getName().toLowerCase().replace("do", "");
return callerName.contains(methodName);
}
}
public static void main(String[] args) {
final MyACL acl = new MyACL();
final API api = new MyAPI();
final AlphaClient client = new AlphaClient();
final API guardedAPI = acl.protect(client, api, API.class);
client.use(guardedAPI);
}
}
Notes:
The accessor does not have to be the client object itself, it can be a string key or token that helps ACL identify the client.
The ACL implementation here is rudimentary, more interesting ones could be One that reads ACL from some file or One that uses method and client annotations as rules.
If you don't want to define an interface for API class, consider a tool like javassist to directly proxy a class.
Consider other popular Aspect Oriented Programming solutions
You should create one super class with all the methods and then provide Client specific implementations in their corresponding sub classes extending from the super class defined earlier.
If there are methods which are common implementation for all clients, leave their implementations to the super class.
It seems like you are a bit confused about the purpose of Classes and Interfaces. As far as I know, an Interface is a contract defining which functionality a piece of software provides. This is from official java tutorial:
There are a number of situations in software engineering when it is
important for disparate groups of programmers to agree to a "contract"
that spells out how their software interacts. Each group should be
able to write their code without any knowledge of how the other
group's code is written. Generally speaking, interfaces are such
contracts.
Then you can write a Class which implements this Interface/contract, that is, provides the code that actually perform what was specified. The List interface and the ArrayList class are both an example of this.
Interfaces and Classes have access modifiers, but they aren't designed to specify permissions to specific clients. They specify what is visible for other piece of software depending the location where it is defined: Class, Package, Subclass, World. For example, a private method can be accessed only inside the class where it is defined.
From official Java tutorial again:
Access level modifiers determine whether other classes can use a
particular field or invoke a particular method. There are two levels
of access control:
At the top level—public, or package-private (no explicit modifier).
At the member level—public, private, protected, or package-private (no
explicit modifier).
Maybe you want something more powerful like Access Control List (ACL).
Your question is a little unclear, leading to different possible answers. I'll try to cover some of the possible areas:
Object encapsulation
If your goal is to provide interfaces to different clients that only provide certain functionality or a specific view there are several solutions. Which matches best depends on the purpose of your class:
Refactoring
The question somehow suggests that your class is responsible for different tasks. That might be an indicator, that you could tear it apart into distinct classes that provide the different interfaces.
Original
class AllInOne {
A m1() {}
B m2() {}
C m3() {}
}
client1.useClass(allInOneInstance);
client2.useClass(allInOneInstance);
client3.useClass(allInOneInstance);
Derived
class One {
A m1() {}
}
class Two {
B m2() {}
}
class Three {
C m3() {}
}
client1.useClass(oneInstance);
client2.useClass(twoInstance);
client3.useClass(threeInstance);
Interfaces
If you choose to keep the class together (there might be good reasons for it), you could have the class implement interfaces that model the view required by different clients. By passing instances of the appropriate interface to the clients they will not see the full class interface:
Example
class AllInOne implements I1, I2, I3 {
...
}
interface I1 {
A m1();
}
But be aware that clients will still be able to cast to the full class like ((AllInOne) i1Instance).m2().
Inheritance
This was already outline in other answers. I'll therefore skip this here. I don't think this is a good solution as it might easily break in a lot of scenarios.
Delegation
If casting is a risk to you, you can create classes that only offer the desired interface and delegate to the actual implementation:
Example
class Delegate1 {
private AllInOne allInOne;
public A m1() {
return allInOne.m1();
}
}
Implementing this can be done in various ways and depends on your environment like explicit classes, dynamic proxies , code generation, ...
Framework
If you are using an Application Framework like Spring you might be able to use functionality from this Framework.
Aspects
AOP allows you to intercept method calls and therefor apply some access control logic there.
Security
Please note that all of the above solutions will not give you actual security. Using casts, reflection or other techniques will still allow clients to obtain access to the full functionality.
If you require stronger access limitations there are techniques that I will just briefly outline as they might depend on your environment and are more complex.
Class Loader
Using different class loaders you can make sure that parts of your code have no access to class definitions outsider their scope (used e.g. in tomcat to isolate different deployments).
SecurityManager
Java offers possibilities to implement your own SecurityManager this offers ways to add some extra level of access checking.
Custom build Security
Of course you can add your own access checking logic. Yet I don't think this will be a viable solution for in JVM method access.
Suppose I have created a library and distribute all over the company and it use in every project.
Library is 1.0 and Suppose I have a interface Componentble.
public interface Componentble {
public String getComponentId();
}
I had done some modification and updated the jar for 1.1 and Componentble interface modified as follows.
public interface Componentble {
public String getComponentId();
public Componentble getParentComponent();
}
When this jar applied to existing project it will gives compile errors.
I want to do this modifications and update the jar. but case is it should not affect to existing projects.
What is the best way to do this.
Create ComponentbleV2 and in new project ask to use ComponentbleV2 not Componentble.
Or Create custom class loader and do what need.
The answer what i want is how we can do api modification and apply to existing project with out any compilation issue for existing projects.
One way to do this is by annotating the method(s) in your old interface with #Deprecated and explaining in the javadocs what to use instead.
For more documentation on that, see Oracle documentation on #Deprecated
For the sake of backwards compatibility, you're going to have to keep both interfaces for now. This might require a bit of customization in the implementation of the interfaces. In a while, after you've been through a couple more versions, you can remove the old interface.
Make sure to properly document your deprecated methods, so that the developers who use it know what to use instead and where to find it.
From Java 8 on you can provide default implementations for interface methods. They were invented exactly for your problem.
public interface Componentble {
public String getComponentId();
public default Componentble getParentComponent() {
return null;
}
}
Two interfaces
There is no need to deprecate the old one.
Create two interfaces where the new one extends the old one.
public interface Componentble {
public String getComponentId();
}
and
public interface ComponentbleWithStructure extends Componentble {
public Componentble getParentComponent();
}
Implementing a interface should imply that the implementer follows the contract of that interface.
This way you know that any class implementing both has been remade to fit the new contract and the ones implementing only the old still follows the old contract.
Example of use:
void doStuff(Componentble component){
if(component instanceof ComponentbleWithStructure){
Componentble parent=((ComponentbleWithStructure)component).getParentComponent();
....
}
....
}
Default implementation
The java8 way is only useful when it is possible to express the new functionality using the old interface. For example if you have a service that can look up parents you could write.
public interface Componentble {
public String getComponentId();
public default Componentble getParentComponent() {
return ParentLookUpService.getParent(getComponentId());
}
}
This way you will know that all instances using the new interface have a correct implementation.
I am working on GWT project with JDK7. It has two entryPoints (two clients) that are located in separate packages of the project. Clients share some code that is located in /common package, which is universal and accessible to both by having the following line in their respective xml-build files:
<source path='ui/common' />
Both clients have their own specific implementations of the Callback class which serves their running environments and performs various actions in case of failure or success. I have the following abstract class that implements AsyncCallback interface and then gets extended by its respective client.
public abstract class AbstractCallback<T> implements AsyncCallback<T> {
public void handleSuccess( T result ) {}
...
}
Here are the client's classes:
public class Client1Callback<T> extends AbstractCallback<T> {...}
and
public class Client2Callback<T> extends AbstractCallback<T> {...}
In the common package, that also contains these callback classes, I am working on implementing the service layer that serves both clients. Clients use the same back-end services, just handle the results differently. Based on the type of the client I want to build a corresponding instance of AbstractCallback child without duplicating anonymous class creation for each call. I am going to have many declarations that will look like the following:
AsyncCallback<MyVO> nextCallback = isClient1 ?
new Client1Callback<MyVO>("ABC") {
public void handleSuccess(MyVO result) {
doThatSameAction(result);
}
}
:
new Client2Callback<MyVO>("DEF") {
public void handleSuccess(MyVO result) {
doThatSameAction(result);
}
};
That will result in a very verbose code.
The intent (in pseudo-code) is to have the below instead:
AsyncCallback<MyVO> nextCallback = new CallbackTypeResolver.ACallback<MyVO>(clientType, "ABC"){
public void handleSuccess(MyVO result) {
doThatSameAction(result);
}
};
I was playing with the factory pattern to get the right child instance, but quickly realized that I am not able to override handleSuccess() method after the instance is created.
I think the solution may come from one of the two sources:
Different GWT way of dealing with custom Callback implementations, lets call it alternative existent solution.
Java generics/types juggling magic
I can miss something obvious, and would appreciate any advice.
I've read some articles here and on Oracle about types erasure for generics, so I understand that my question may have no direct answer.
Refactor out the handleSuccess behavior into its own class.
The handleSuccess behavior is a separate concern from what else is going on in the AsyncCallback classes; therefore, separate it out into a more useful form. See Why should I prefer composition over inheritance?
Essentially, by doing this refactoring, you are transforming an overridden method into injected behavior that you have more control over. Specifically, you would have instead:
public interface SuccessHandler<T> {
public void handleSuccess(T result);
}
Your callback would look something like this:
public abstract class AbstractCallback<T> implements AsyncCallback<T> {
private final SuccessHandler<T> handler; // Inject this in the constructor
// etc.
// not abstract anymore
public void handleSuccess( T result ) {
handler.handleSuccess(result);
}
}
Then your pseudocode callback creation statement would be something like:
AsyncCallback<MyVO> nextCallback = new CallbackTypeResolver.ACallback<MyVO>(
clientType,
"ABC",
new SuccessHandler<MyVO>() {
public void handleSuccess(MyVO result) {
doThatSameMethod(result);
}
});
The implementations of SuccessHandler don't have to be anonymous, they can be top level classes or even inner classes based on your needs. There's a lot more power you can do once you're using this injection based framework, including creating these handlers with automatically injected dependencies using Gin and Guice Providers. (Gin is a project that integrates Guice, a dependency injection framework, with GWT).
I'm learning Java and want to implement method chaining to build a set of execution instructions. I've heard about some design patterns like builder or command pattern (I don't know what those patterns are btw, just heard their names floating around in my learning journey). But not sure if I would be complicating things if I chose to go with a OOP design pattern.
So this is what I want to build:
Hypothetically speaking, lets say I have a class in my program called DatabaseOperator.
In terms of design, I would I go about designing the class so that the client that uses DatabaseOperator could use it like shown below:
public static void main(String args[]){
DatabaseOperator do = new DatabaseOperator();
DatabaseOperator.getConfigurations("fileName").getAuthenticationDetails("somefile").
joinCluster("clusterName").launchMode("TEST").initiateConnection();
}
How should I design my DatabaseOperator class? Any particular design pattern I can use or is it not needed?
Thank you in advance.
You could design your DatabaseOperator class to support chained invocations, by returning the this object in the different methods. Each of these methods will update the state of the DatabaseOperator in order to facilitate proper execution of other methods (such as initiateConnection()) down the line.
As Jordao pointed out, this looks more like a Fluent Interface (that uses a Builder pattern under the hood). One possible implementation could be:
public class DatabaseOperator {
private Configuration configuration = Configuration.DEFAULT;
private AuthDetails authDetails = AuthDetails.DEFAULT;
public DatabaseOperator withConfigurationsFrom(String fileName) {
//Get the configurations from the file, and initialize the 'Configuration' object
configuration = initializeFrom(fileName);
return this;
}
public DatabaseOperator withAuthenticationDetailsFrom(String fileName) {
// Get authentication details from the file, and initialize AuthenticationDetails
authDetails = initializeAuthDetailsFrom(fileName);
return this;
}
//.. and so on
public void initiateConnection() {
//Uses configuration and authDetails
}
}