I have an interface, Resource, which is supposed to wrap something and expose a few operations on the wrapped object.
My first approach was to write the following, with the Strategy pattern in mind.
interface Resource<T> {
ResourceState read();
void write(ResourceState);
}
abstract class AbstractResource<T> implements Resource<T> {
// This is where the Strategy comes in.
protected AbstractResource(ResourceStrategy<T> strat) {
// ...
}
// Both the read and write implementations delegate to the strategy.
}
class ExclusiveResource<T> extends AbstractResource<T> { ... }
class ShareableResource<T> extends AbstractResource<T> { ... }
The two implementations above differ in the locking scheme used (regular locks, or read-write locks).
There is also a ResourceManager, an entity responsible for managing these things.
My idea of usage by the client, would be:
ResourceManager rm = ...
MyCustomObject o = ...
MyCustomReadWriteStrategy strat = ...
rm.newResourceFor(o, "id", strat);
This way, the client would know about resources, but wouldn't have to deal directly with resources (hence the package-private classes). Also, I could make my own implementation of some common resources, like sockets, and the client would only ask for them (ie, I would have to write a SocketStrategy implements ResourceStrategy<Socket>).
ResourceManager rm = ...
rm.newSocketResource("id", host, port);
To access resources, he would request an handler from the manager. This is due to each thread having some specific access privileges, and so the manager would create an handler with the appropriate access privileges.
// This is in the ResourceManager class.
public ResourceHandler getHandlerFor(String id) {
if (!canThreadUseThisResource(id)) throw ...;
if (isThreadReaderOnly()) {
return new ResourceReadHandler( ... );
} else {
return new ResourceWriteHandler( ... );
}
}
This is where the problem kicks in.
This approach seems clean and clear to me, it also seems to be intuitive for the user.
But, as hinted, the manager keeps a mapping from identifiers to resources. How would this be declared, and how would the manager retrieve the resources from the map?
Map<String, Resource<?>> map;
// Can I go around without any specific cast? Not sure yet.
Resource<?> r = map.get(id);
// This could have an enum ResourceType, to check if thread has privileges
// for the specific type.
Is this design acceptable, and/or following good practices?
Alternatively, I could wipe out the generics, and have ExclusiveResource and ShareableResource be abstract and public.
These classes would then be extended, both by me and the client, for every type of resource needed (FileResource extends ExclusiveResource, SocketResource extends ExclusiveResource, ...).
This would probably eliminate the need for the strategy pattern, but would expose more of my package to the user.
Which of these alternatives is the most correct, or widely accepted as good practice?
Edit: After some thought, I think I could be able to remove the generic from the Resource interface, since that's the one causing trouble, and leave it on AbstractResource and its subclasses. The latter could still grant me compile-time verification of the strategies used.
public <T> void newExclusiveResourceFor(
T obj, String id, ResourceStrategy<T> strat) {
ExclusiveResource<T> r = new ExclusiveResource<>(obj, strat);
map.put(id, r);
}
However, following the inheritance way seems to be more correct.
As suggested by dkaustubh and Paul Bellora, as it stands, there is no plausible justification for the generic in the Resource interface. This had gone completely unnoticed by me, at first, since I wanted the implementations to be generic, so I assumed the interface should also be generic. That's not the case.
I still have two options here.
Using Generics
I should remove the generic in the interface. Then, I would end up with the following.
interface Resource {
ResourceState read();
void write(ResourceState);
void dispose();
}
abstract class AbstractResource<T> implements Resource {
/* This is where the Strategy comes in.
* The generic ensures compile-time verification of the
* strategy's type. */
protected AbstractResource(ResourceStrategy<T> strat) {
// ...
}
// Both the read and write implementations delegate to the strategy.
}
class ExclusiveResource<T> extends AbstractResource<T> { ... }
class ShareableResource<T> extends AbstractResource<T> { ... }
// This is the behaviour the client implements, for custom resources.
public abstract class ResourceStrategy<T> {
public abstract ResourceState read(T obj);
public abstract void write(ResourceState state);
public abstract void dispose(T obj);
}
Only ResourceHandler, ResourceManager, ResourceState and ResourceStrategy need to be public, to the client.
Using Inheritance
Using inheritance, I can achieve the same results, with some trade-offs.
public interface Resource {
ResourceState read();
void write(ResourceState);
void dispose();
}
/* These implement only the locking schemes. */
abstract class ExclusiveResource implements Resource { ... }
abstract class ShareableResource implements Resource { ... }
/* The user extends these for custom content and behaviour. */
public abstract class CustomExclusiveResource
extends ExclusiveResource { ... }
public abstract class CustomShareableResource
extends ShareableResource { ... }
Resources are now public to the client.
Conclusions
There are ways to misuse resources with both approaches, bypassing the expected contracts and thread permissions. Both approaches are equal here.
With generics, the inner representation of resources need not be known by the client, since the manager creates the resources in the background. With inheritance, resource creation takes place on the client side, so the manager's API would change to accept provided resources.
Even though Resources are not public, using generics, the client needs to know about the strategies. With inheritance, these are gone, and the public status is assigned to resources instead.
With strategies, the behaviour can be changed in runtime, or there could be different behaviours for the same kind of resource. Without them, the client needs to dispose of a resource, and them re-create it using another subclass that implements different behaviour.
E.g.: small files can be completely read to memory, while large files may require an appropriately sized buffer.
Unless something else is missing, it may just be a matter of choice, and thinking about the desired API and use cases.
Related
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.
I've been learning a lot about Design Patterns lately, specifically Dependency Injection. I'm pretty sure that abstract factorys are a good way of instantiating objects that have dependencies. However I'm not sure how to tell lower level objects what factories they are supposed to use.
Consider following simplified example:
I have a class MainProgram (I just made this to represent that there is other code in my program..)
At some point during runtime I want to instantiate a IGeneticAlgorithm with an abstract factory:
public class MainProgram{
private AbstractGeneticAlgorithm geneticAlgorithm;
private IGeneticAlgorithmFactory geneticAlgorithmFactory;
public MainProgram(IGeneticAlgorithmFactory geneticAlgorithmFactory){
this.geneticAlgorithmFactory = geneticAlgorithmFactory;
}
private void makeGeneticAlgorithm(){
geneticAlgorithm = geneticAlgorithmFactory.getInstance();
}
public static void main(String[] args){
MainProgram mainProgramm = new MainProgram(new FastGeneticAlgorithmFactory());
//...
}
}
public interface IGeneticAlgorithmFactory{
public IGeneticAlgorithm getInstance();
}
public class FastGeneticAlgorithmFactory implements IGeneticAlgorithmFactory{
public IGeneticAlgorithm getInstance(){
return new FastGeneticAlgorithm();
}
}
public abstract class AbstractGeneticAlgorithm{
private IIndividual individual;
private IIndividualFactory individualFactory;
private void makeIndividual(){
individual = individualFactory.getInstance();
}
//...
}
At some point during runtime I want to instantiate an IIndividual in my GeneticAlgorithm. The IIndividual can't be instantiated at startup. The need to be able to instantiate the IIndividual during runtime comes from the way Genetic Algorithms work, where basically after each Step of Selection-Recombination-Mutation new Individuals have to be instantiated. (For more information see https://en.wikipedia.org/wiki/Genetic_algorithm). I chose to give the AbstractGeneticAlgorithm here only one IIndividual to keep this example simple.
public class FastGeneticAlgorithm implements AbstractGeneticAlgorithm{
private IIndividual individual;
private IIndividualFactory individualFactory;
}
public interface IIndividualFactory{
public IIndividual getInstance();
}
public class SmallIndividualFactory implements IIndividualFactory{
public IIndividual getInstance(){
return new SmallIndividual();
}
//...
}
public interface IIndividual{
//...
}
public class SmallIndividual implements IIndividual{
//...
}
Making the SmallIndividualFactory a static variable in the FastGeneticAlgorithm doesn't seem to me like good practice. And passing the SmallIndividualFactory to Main, so that Main can pass it down to FastGeneticAlgorithm also doesn't seem right.
My question is how to solve this? Thank you.
When it comes to using Dependency Injection, the Abstract Factory pattern is often over-used. This doesn't mean that it's a bad pattern per se, but in many cases there are more suitable alternatives for the Abstract Factory pattern. This is described in detail in Dependency Injection Principles, Practices, and Patterns (paragraph 6.2) where is described that:
Abstract Factories should not be used to create short-lived, stateful dependencies, since a consumer of a dependency should be oblivious to its lifetime; from perspective of the consumer, there should conceptually be only one instance of a service.
Abstract Factories are often Dependency Inversion Principle (DIP) violations, because their design often doesn't suit the consumer, while the DIP states: "the abstracts are owned by the upper/policy layers", meaning that consumer of the abstraction should dictate its shape and define the abstraction in a way that suits its needs the most. Letting the consumer depend on both a factory dependency and the dependency it produces complicates the consumer.
This means that:
Abstract Factories with a parameterless create method should be prevented, because it implies the dependency is short-lived and its lifetime is controlled by the consumer. Instead, Abstract Factories should be created for dependencies that conceptually require runtime data (provided by the consumer) to be created.
But even in case a factory method contains parameters, care must be taken to make sure that the Abstract Factory is really required. The Proxy pattern is often (but not always) better suited, because it allows the consumer to have a single dependency, instead of depending on both the factory and its product.
Dependency Injection promotes composition of classes in the start-up path of the application, a concept the book refers to as the Composition Root. The Composition Root is a location close to that application's entry point (your Main method) and it knows about every other module in the system.
Because the Composition Root takes a dependency on all other modules in the system, it typically makes little sense consume Abstract Factories within the Composition Root. For instance, in case you defined an IXFactory abstraction to produce IX dependencies, but the Composition Root is the sole consumer of the IXFactory abstraction, you are decoupling something that doesn't require decoupling: The Composition Root intrinsically knows about every other part of the system any way.
This seems to be the case with your IGeneticAlgorithmFactory abstraction. Its sole consumer seems to be your Composition Root. If this is true, this abstraction and its implementation can simply be removed and the code within its getInstance method can simply be moved into the MainProgram class (which functions as your Composition Root).
It's hard for me to understand whether or not your IIndividual implementations require a factory (it has been at least 14 years ago since I implemented a genetic algorithm at the University), but they seem more like runtime data rather than 'real' dependencies. So a factory might make sense here, although do verify whether their creation and implementation must be hidden behind an abstraction. I could imagine the application to be sufficiently loosely coupled when the FastGeneticAlgorithm creates SmallIndividual instances directly. This, however, is just a wild guess.
On top of that, best practice is to apply Constructor Injection. This prevents Temporal Coupling. Furthermore, refrain specifying the implementations dependencies in the defined abstractions, as your AbstractGeneticAlgorithm does. This makes the abstraction a Leaky Abstraction (which is a DIP violation). Instead, declare the dependencies by declaring them as constructor arguments on the implementation (FastGeneticAlgorithm in your case).
But even with the existence of the IIndividualFactory, your code can be simplified by following best practices as follows:
// Use interfaces rather than base classes. Prefer Composition over Inheritance.
public interface IGeneticAlgorithm { ... }
public interface IIndividual { ... }
public interface IIndividualFactory {
public IIndividual getInstance();
}
// Implementations
public class FastGeneticAlgorithm implements IGeneticAlgorithm {
private IIndividualFactory individualFactory;
// Use constructor injection to declare the implementation's dependencies
public FastGeneticAlgorithm(IIndividualFactory individualFactory) {
this.individualFactory = individualFactory;
}
}
public class SmallIndividual implements IIndividual { }
public class SmallIndividualFactory implements IIndividualFactory {
public IIndividual getInstance() {
return new SmallIndividual();
}
}
public static class Program {
public static void main(String[] args){
AbstractGeneticAlgorithm algoritm = CreateAlgorithm();
algoritm.makeIndividual();
}
private AbstractGeneticAlgorithm CreateAlgorithm() {
// Build complete object graph inside the Composition Root
return new FastGeneticAlgorithm(new SmallIndividualFactory());
}
}
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 am fairly new to Java and haven't yet needed to use an abstract class. I understand that:
Abstract classes can't be instantiated
Abstract classes often have abstract methods
Its purpose is only for other classes to extend
I also understand that abstract class can be used when you want to create new versions of your components. How does this work?
In what type of (specific) situation would it be beneficial to use abstract classes?
Also, I have read that you can use them to "partially implement your class." What exactly does this mean?
And my final question is, could extending a regular class achieve similar results?
In what type of (specific) situation would it be beneficial to use abstract classes?
You would want to use an abstract class when you want to provide some predefined methods in the base class without allowing the user to instantiate the base class as only more specific subclasses that define the rest of the behavior are good enough classes to stand alone and be used.
Also, I have read that you can use them to "partially implement your class." What exactly does this mean?
It means you can if you want only declare methods (label them abstract), in which subclasses have to define them, while also being able to define methods in the abstract class that all subclasses can also make use of.
And my final question is, could extending a regular class achieve similar results?
Only if the objects of the base class are useable by themselves.
You use an abstract class when a portion of your functionality is known, but a portion is variable.
public abstract class Channel {
private Response response;
public abstract void connect();
public abstract void sendMessage(Message message);
public abstract Response awaitResponse();
public abstract void disconnect();
public void send(Message message) {
connect();
sendMessage(message);
response = awaitResponse();
disconnect();
}
public Response getResponse() {
return response;
}
}
now you have a "communications channel" which you know you can send messages on, but have absolutely no idea of what the protocol is, how it connects, or how it handles the response.
To give an example of how far one might twist this idea. Let's explore "email" channels.
public class EmailChannel extends Channel {
public void connect() {
... open a SMTP socket to the email server ...
... open a HTTP socket for the response channel ...
}
public void sendMessage(Message message) {
... create a URL with encoding for the "response link" ...
... negotiate SMTP protocol ELHO, etc...
... send an email message with the "message" contents ...
... append the embedded HTTP "response link" ...
... close the SMTP socket ...
}
public Response awaitResponse() {
... wait till expected "GET" occurs on the HTTP socket ...
... return new Response(... details ...)
}
public void disconnect() {
... close the HTTP socket ...
}
}
There are of course many actual issues with the code above, but it is an example of the Template pattern, and a decent example of why one might want to write an abstract class.
Abstract classes become even more valuable when you have more implementations of them. To stretch our slapdash example just a bit further, imagine a system which offers a choice of protocols.
Contact "John Doe" by
1) email
2) SMS
3) chat
which would be backed by a
public Channel getChannelForInput(int value) {
switch (value) {
case 1: return new EmailChannel();
case 2: return new SMSChannel();
case 3: return new ChatChannel();
default: throw new IllegalArgumentException("value cannot be " + value);
}
}
and that backing would fit into something like
...
Channel channel = getChannelForInput(value);
channel.send(message);
displayResponse(channel.getResponse());
...
Hopefully now you can see how it might be useful to have a type that guarantees certain behaviors while leaving some of the details unspecified.
To add an example to #NESPowerGlove explaination.
Think of this scenario, you have a DAL(Data Access layer), Across all the DAO implementation classes you may be doing certain operation repeatedly, for e.g., opening connection, closing connection, logging specific task.
So these are the operation you can define in your abstract class(namely BaseDAO)
Now every DAOImpl which will extend BaseDAO just need to call methods define in your abstract class, for opening closing connection and logging too..
This is a very specific scenario, you'll find its usage at other places too
I think for reading about Abstract Classes, this link can help you
Since #NESPowerGlove has already answer some of your questions, so my answer will include only example, i will add details if you want.
Think of your self as an owner of pizza company (as well as keen programmer too :p). Now you have two branches in two different countries, say USA and Italy.
Since you know people of both countries have different tastes, so you are customizing the pizza making process as per country's people taste. That means. USA branch will serve pizza made as per USA style and Italian branch will serve pizza made in Italian style.
Since making of pizza is common in both processes, so you are defining an abstract class with an abstract method `makePizza()', method is marked abstract because you only know branches will make pizza, but how they will make pizza that is upto branch.
abstract class MyPizzaCompany{
public asbtract void makePizza();
}
Since, US branch serves pizza made in US style, so USBrach class will give its own implementation(here process of making pizza) for making pizza.
class USBranch extends MyPizzaCompany{
#Override
void makePizza() {
// make pizza in US style
}
}
Similarly, for Italian branch
class ItalianBranch extends MyPizzaCompany{
#Override
void makePizza() {
// make pizza in italian style
}
}
Imagine a scenario where you are writing a class. You write logic into methods that you know at that time and declare few methods abstract whose logic will be added by sub-classes.
We should create Abstract Class when we have following requirement
You want to have some common functionality for all sub classes
There must be some implementation required in each sub class as per different requirements
You want to deal between subtypes with abstract class object reference. (Polymorphism)
I'm developing an app with Jersey where I have many resources. Although main functionality of these resources varies, they share lots of common methods (like list, read, update and etc). The app runs on Google App Engine and uses Guice for dependency injection.
My first approach was to have a generic AbstactResource which contains all common logic, and it's respectively extended by all other resources which add their required custom methods.
public class AbstractResource<T> {
#GET
public ListPage<T> list(#QueryParam("limit") Integer limit,
#QueryParam("start") Integer start) {
// ... implementation
}
#GET
#Path("/{id}")
public T get(#PathParam("id") Long id) {
// ... implementation
}
And sample resource looks like:
public class TenantResource extends AbstractResource<Tenant> {
// custom resource related methods here
}
Everything works fine in this case. The problems appear when I add one more level of abstraction. Let's say if I want to store history and changelogs only for some of my resources. I've created one more abstract class extending AbstractResource called AudiatableResource which adds the required functionality.
public abstract class AuditableResource<T extends AuditableModel>
extends AbstractResource {
// here I override update and create methods to save changelogs
}
As you see the type parameter in this case has changed (now it extends AuditableModel).
New concrete resources will look like:
public class PropertyResource extends AuditableResource<Tenant> {
// custom resource related methods here
}
In this case everything still works, but this time I'm getting lots of warning messages on start-up:
WARNING: Return type T of method public T com.pkg.AbstractResource.get(java.lang.Long) is not resolvable to a concrete type
WARNING: Return type T of method public T com.pkg.AbstractResource.getNew() is not resolvable to a concrete type
WARNING: Return type com.pkg.data.ListPage<T> of method public com.pkg.ListPage<T> com.pkg.AbstractResource.list(java.lang.Integer,java.lang.Integer) is not resolvable to a concrete type
I really wonder if this approach is correct using Jersey and if I can just ignore this messages. It would be interesting to know how resources are organized in cases when there are large number of them.
One way to go is to separate the definition of the resources from the implementation.
Have very simple resource classes, defining the different services you want to offer. This way, the API you expose through rest is easily located and audited. The different methods are probably delegates to an implementation class
Implement the business logic of your resources in the implementations, where you might want to use inheritance to factor common behavior.
The reason you get those messages at runtime is that jersey uses runtime information about types in the resource. Generic type information being erased at compile time, it cannot get the actual return type of the generic class methods. If you provide a REST "facade" to your implementation, you can make this explicit.
public class Facade {
private final PropertyResource propertyResource;
public Facade() {
propertyResource = new PropertyResource();
}
#GET
#Path("somepath")
public Tenant something() {
return propertyResource.something();
}
}