Software design for adding aspects dynamically without AOP Framework - java

I have written a little example program to measure the time execution of java methods.
I want to design a solution which is low coupled and which can be added to other methods dynamically, which means that if I wrote other classes with other methods, I want to wrap my performance measuring module over my business logic module and measure the time execution of the methods while the business logic class has no dependencies to the performance measurement module.
My current solutions looks like this
I have an abstract class which defines some list operations.
I have sub-classes which defines the concrete list operations
I have a performance Measurement Class which extends the class which shall be measured
public abstract class ListOperations<T> {
private List<T> list;
public ListOperations() {
initList();
}
/**
* Initializes the list. Clients can decide which list type shall be used (e.g LinkedList, ArrayList etc.)
*/
public abstract void initList();
public abstract void addLast(final T element);
public List<? super T> getList() {
return list;
}
protected void setList(final List<T> list) {
this.list = list;
}
}
public class LinkedListOperations<T> extends ListOperations<T> {
public LinkedListOperations() {
super();
}
#Override
public void addLast(final T element) {
getList().addLast(element);
}
#Override
public void initList() {
setList(new LinkedList<T>());
}
#Override
public LinkedList<? super T> getList() {
return (LinkedList<? super T>) super.getList();
}
}
public class PerformanceMeassuredLinkedListOperations<T> extends LinkedListOperations<T> {
private static final String START_PERFORMANCE_MEASSURE_FOR_METHOD = "Start Performance Meassure for method: ";
private static final String STOP_PERFORMANCE_MEASSURE_FOR_METHOD = "Stop Performance Meassure for method: ";
private static final String TIME_EXECUTION_IN_MILLIS = "Time Execution in Millis: ";
/**
* Used to printout the name of the method from the stack. in depth 2 the real business logic method is located
*/
private static final int DEPTH_IN_STACKTRACE = 2;
// depth 0 = printStopMeassurement
// depth 1 = stopPerformanceMeassure
// depth 2 = method for which performance is measured (e.g addLast)
private long startCurrentTimeMillis;
#Override
public void initList() {
startPerformanceMeassure();
super.initList();
stopPerformanceMeassure();
}
public void meassureAddLast(final int numberOfElements, final T testElement) {
startPerformanceMeassure();
for (int i = 0; i < numberOfElements; i++) {
addLast(testElement);
}
stopPerformanceMeassure();
}
protected void startPerformanceMeassure() {
printStartMeassurement();
startCurrentTimeMillis = System.currentTimeMillis();
}
private void printStartMeassurement() {
System.out.println(START_PERFORMANCE_MEASSURE_FOR_METHOD + getNameOfCurrentExecutedMethod());
}
protected void stopPerformanceMeassure() {
System.out.println(TIME_EXECUTION_IN_MILLIS + (System.currentTimeMillis() - startCurrentTimeMillis));
printStopMeassurement();
}
private void printStopMeassurement() {
System.out.println(STOP_PERFORMANCE_MEASSURE_FOR_METHOD + getNameOfCurrentExecutedMethod());
}
private String getNameOfCurrentExecutedMethod() {
final StackTraceElement[] ste = Thread.currentThread().getStackTrace();
return ste[ste.length - DEPTH_IN_STACKTRACE].getMethodName();
}
}
public class Main {
public static void main(String[] args) {
PerformanceMeassuredLinkedListOperations<String> listOperations = new PerformanceMeassuredLinkedListOperations<String>();
listOperations.meassureAddLast(50000, "Hello");
}
}
With this solution I must extend every business logic module and add my time measurement code in a static way.
Now I want to design a performance measure module that can be added dynamically to any business logic module and measures the performance of the methods called. I don't want to use any AOP Framwork for that. I think such a dynamical aspect addition can be done with a mixture of some kind of decorator and interceptor pattern but I have no idea how.

What you're describing is a cross cutting concern
Your needs fall squarely into the realm of an aspect. You want to be able to log latency across various cut-points in your code.
Consider:
Method 1
You will need to intercept all calls to said business modules.
You can define an BussinessModule interface. Create a delegate class that intercepts this common call and then wraps an abstract method and logs latency (or whatever).
It's limited but, with some effort can work and it's the easiest implementation.
Method 2
Develop some sort of expressive language to say which methods you want to intercept on what classes
Figure out a way to intercept those method calls (Without using AspectJ, or writing your own class-loader, I can't imagine how) and execute them
Method 1 is not at all dynamic. You must have iron control of implementation across your whole system. Any class that doesn't get included in your delegate/proxy scheme won't get this behavior. Someone has to make sure that every class implemented has this wrapper on it.
Method 2 is super dynamic. By having an expressive language/syntax you can describe code to get wrapper and then, even if it's not your code or you're working with lazy people, it still gets wrapped. The downside is that it would be insanely difficult and time consuming to implement. Good new though! Spring AOP and AspectJ already do this!
So, your question was
how do I do this without Spring AOP or AspectJ
I believe I have given an answer. But to be totally clear: Lots-and-lots of delegation would be the easiest route.
That said: There is no good explainable reason to roll your own. I literally have an Aspect and the bean config for Spring to do exactly this. If it's a question of time I can simply paste it in and you can rip it off and run with it.

You do not want to use a proven and tested framework because you alone can do better and exchange one framework for another - your own one. Be it as it may, you will be ending up using a framework. Does that make sense?
Good luck for re-inventing the wheel.
Update: Some more background about why I think you will be ending up implementing your own AOP framework: AOP is kind of orthogonal to OOP's inheritance concept. An OOP language without any semantic extensions like AspectJ or frameworks like Spring AOP just does not offer the means to express aspects, otherwise AOP languages/frameworks would be redundant. I doubt you will be able to solve the problem by a mere combination of two or so OOP design patterns.
Update 2: If you fail with design patterns and byte code generation is too complex for you, you might want to use the same approach as Spring AOP: Java dynamic proxies (works for interfaces) and/or CGLIB dynamic proxies (for non-interface types).

Related

Does it makes sense to use state pattern with virtual proxies?

class HeavyweightObjcet
{
public void operate() {
System.out.println("Operating...");
}
}
class LazyInitializer
{
HeavyweightObjcet objcet;
public void operate()
{
if (objcet == null)
objcet = new HeavyweightObjcet();
objcet.operate();
}
}
Here I'm making a virtual proxy for a heavyweight object. Each time before calling HeavyweightObject::operate, the program checks first whether the object is null or not. This part is checked once and only once through the entire lifetime of the object.
A possible improvement maybe using the state pattern like this:
class HeavyweightObjcet
{
public void operate() {
System.out.println("Operating...");
}
}
class LazyInitializer
{
HeavyweightObjcet objcet;
State state = new UninitializedState(this);
public void operate()
{
state.operate();
}
}
abstract class State
{
LazyInitializer initializer;
public State(LazyInitializer initializer)
{
this.initializer = initializer;
}
abstract void operate();
}
class UninitializedState extends State
{
public UninitializedState(LazyInitializer initializer) {
super(initializer);
}
#Override
public void operate() {
initializer.objcet = new HeavyweightObjcet();
initializer.state = new InitializedState(initializer);
initializer.operate();
}
}
class InitializedState extends State
{
public InitializedState(LazyInitializer initializer) {
super(initializer);
}
#Override
public void operate() {
initializer.objcet.operate();
}
}
Does this solution make sense?
Is there any possible improvement to the code?
Are there any examples to something like this that's done before?
Is it an unnecessary complication or does it worth it or does it depend on the situation?
Does it make the code faster? I mean, the extra function calls may be slower than just a simple conditional.
Is it an unnecessary complication or does it worth it or does it
depend on the situation?
While it is completely fine to have only 2 states when using the State Pattern, it is most definitely an overkill in this particular case for the following reasons :
There will only ever be one state transition from
UninitializedState -> InitailizedState. Once HeavyWeightObjcet
has been initialized, you are most definitely not going to
alternate between transitioning from InitializedState -> UninitializedState or
vice-versa
There is a reason why we have design principles such as YAGNI (You aren't gonna need it) and KISS (Keep it simple, stupid). Don't introduce complexities in the first iteration of the code. Let the design evolve as a part of continuous refactoring.
While the above example looks good on paper, the real world is a different ballgame altogether. There are more important problems to address in the code in the real world. (For example, is the operate method thread-safe?)
Does it make the code faster? I mean, the extra function calls may be
slower than just a simple conditional.
This is too small an area to be worrying about when it comes to performance Read : micro-optimization
Last but not the least, the State Pattern allows us to adhere to the Open-Closed principle.. As the example stands, there is no convincing reason for the operate method to change as far as initialization of the HeavyWeightObject is concerned. Moreover, the initialization code should be in the constructor rather than the operate method in the first place.

How to implement a method for multiple strategies having completely different logic?

I find it hard to give this question a concret title, as I'm not really aware of how to name my type of problem. Any suggestions welcome.
I have a service to run logic that literally performs the same action (eg save a thumbnail), but contains completely different logic for different providers:
#Service
public class ThumbnailService {
public void saveForProvider1(Prov1 url) {
}
public void saveForProvider2(Prov2 url) {
//completely different logic than Provider1; also a different parameter Object "Prov2"
}
}
Problem 1: for any new provider I have to create an additional method in that ThumbnailService.
Now at a specific point, I want to run those methods async:
//basically just an async wrapper service
#Service
#Async
public class ThumbnailServiceAsync {
#Autowired
private ThumbnailService delegator;
public class asyncSaveForProvider1(Prov1 url) {
delegator.saveForProvider1(url);
}
public class asyncSaveForProvider2(Prov2 url) {
delegator.saveForProvider2(url);
}
}
Switching by anInteger variable where I know which number stands for which provider:
int provider;
switch (provider) {
case 1: thumbServiceAsync.asyncSaveForProvider1(url); break;
case 2: thumbServiceAsync.asyncSaveForProvider2(url); break;
default: throw NotSupportedException();
}
Problem 2: as you see I'm writing lots of code just for the sake of delegation to the specific provider routine. And I also have to touch at least those 3 classes mentioned when introduction any additional provider.
Question: how could I optimize this process? Especially regarding that by time more providers may be implemented. And also not only a thumbnail routine, but furhter methods that have to be implemented for every provider, but are different from their logic. Like "create a user for providerX", or "run some cleanup routine for providerX".
interface Provider {
void specificProviderCode();
}
public class Provider1 implements Provider {
public void specificProviderCode(){
}
}
public class ProviderFactory{
public static Provider createProvider(ProviderType providerType){
if(providerType.equals(ProviderType.TYPE_1){
return new Provider1();
}
}
}
#Service
public class ThumbnailService {
public void saveForProvider(Provider provider){
provider.specificProviderCode();
}
}
#Service
#Async
public class ThumbnailServiceAsync {
#Autowired
private ThumbnailService delegator;
public class asyncSaveForProvider(ProviderType providerType) {
Provider url = ProviderFactory.createprovider(providerType);
delegator.saveForProvider(url);
}
}
Now when you are adding new provider only there you need to make changes(to create new one with specific logic), both services will not be changed, which also means all callers to services do not need to change their code.
The Command Pattern is a great fit here.
Think of the save methods as instances of Runnable or Callable (the basic Command interfaces in Java). If ThumbnailService would wrap each unique save method along with its unique parameter into one of these Command interfaces, then ThumbnailServiceAsync could become a simple Executor with no knowledge of Providers. The switch statement goes away, because the Executor treats every Command the same: by invoking run() or call().
This leaves the question of closing ThumbnailService to modification. We'd like to eliminate knowledge of concrete Providers from that class as well. The obvious OOP approach would be to break the different logic up into separate classes, potentially into the Providers themselves. If you must wrap a common interface around the Providers, you may need to resort to serializing the different parameters e.g. as Strings, casting, or perhaps using reflection.

Dynamically Casting class and calling appropriate methods

I am writing a utility which uses some classes defined in a 3rd party library which i do not control.
I would like the to know what would be a good way to handle situations like the one described below :
3rd party library has a base abstract class 'Food' which is extended by 'Appetizer','Entree',"Beverage' and 'Dessert'. (all part of 3rd Party Library)
I am writing a 'WaiterUtility' which has methods to serve each type of food.
I want to avoid an endless chain of instanceof checks .
`
Class WaiterUtility{
public serveItems(Food[] items)
{
for(Food aFood : items){
//how do i call the sub-class specific methods i wrote below?
}
}
private void serve(Appetizer aFood){//somecode}
private void serve(Entree aFood){//somecode}
private void serve(Beverage aFood){//somecode}
private void serve(Dessert aFood){//somecode}
}
`
If at all possible, I would implore you NOT to use reflection as TBotV63 does in his answer (he even says to avoid it). From the Oracle documentation:
If it is possible to perform an operation without using reflection, then it is preferable to avoid using it.
So, obviously we're inclined to say that all Foods can be served, and that any Waiter can serve any kind of Food. Ideally a good API would therefore expose methods that would be sufficient for a serve(Food) method to do the job without knowledge of what kind of food it is. It seems like your question implies that this is not the case, and therefore something more needs to be done.
If the 3rd party library accepts community input then you should try to open an issue or a pull request to add the functionality.
Obviously that's not always possible, so the next best thing to do would be to create an interface (something like Serveable) which defines the methods you would need, and then subclass the different types of food while implementing that interface. Then you would have Waiter.serve(Serveable).
This is more work than reflection or many uses of instanceof, but it is better OO design.
Why reflection is bad
The documentation for reflection points out 3 drawbacks of reflection
exposure of internals
performance
security
While you might not care about 2 or 3, 1 is especially bad.
... use of reflection can ... render code dysfunctional and may destroy portability. Reflective code breaks abstractions and therefore may change behavior with upgrades of the platform.
Why instanceof is bad (in this case)
serveItems(Food[]) implies to the caller that if you pass it several Food items, it will serve each of them. However this is not really the case. We can only serve certain sub-classes of Food, and we will have run-time errors if we try anything else. Java is a nice typesafe language, we like compile-time errors much more than run-time errors.
Another downside is that additional code needs to be added to Waiter every time a new sub-class of Food is added or changed. This becomes a cross-cutting concern and makes the code unscalable from a development perspective.
These are by no means the only downsides/issues, just a couple examples.
You can try following code:
Class WaiterUtility{
private Map<Class<? extends Food>, Waiter> waiters = new HashMap<>();
WaiterUtility() {
waiters.put(Appetizer.class, new AppetizerWaiter());
waiters.put(Entree.class, new EntreeWaiter());
waiters.put(Beverage.class, new BeverageWaiter());
waiters.put(Dessert.class, new DessertWaiter());
}
public serveItems(Food[] items)
{
for(Food aFood : items){
waiter.get(aFood.getClass()).serve(aFood);
}
}
private static abstract interface Waiter {
private void serve(Food aFood);
}
private static class AppetizerWaiter implements Waiter {
private void serve(Food aFood){
Appetizer appetizer = (Appetizer) aFood;
//somecode
}
}
private static class EntreeWaiter implements Waiter {
private void serve(Food aFood){//somecode}
}
private static class BeverageWaiter implements Waiter {
private void serve(Food aFood){//somecode}
}
private static class DessertWaiter implements Waiter {
private void serve(Food aFood){//somecode}
}
}
Try something similar to the following:
public serveItems(Food[] items)
{
for(Food aFood : items){
Class<?> foodClass = aFood.getClass(); // Get the food's class
Method serve = WaiterUtility.class.getMethod("serve", foodClass); // Get the method by name and argument types
try {
serve.invoke(this, aFood);
} catch (IllegalArgumentException e) { // Should never occur, we're matching it up.
} catch (IllegalAccessException e) { // Shouldn't occur, we're in the same class.
} catch (InvocationTargetException e) {
// Handle errors possibly thrown by the serve method.
}
}
Haven't tested this tho.
Note that you should however avoid this, it's terrible design.

How can a java method be versioned?

I have a need to revision methods of business rules while keeping all previous versions accessible. The class they are contained in will be the same, but the content in each method will be different. I would prefer they have the same method signature. The caller will know the version it would like the execute. I would also prefer not to have _vX in the method name (like the example below). Is there a better way to do this? Something like an annotation on each method would be nice but in brief test that didn't seem possible to make the method unique enough.
public class SomeSpecificRule {
public Response processRule_v1() {
}
public Response processRule_v2() {
}
}
Edit : The reason for different methods is that the logic contained within the methods will likely be effective at different times (primary scenario), but we need to be able to run any version at any given time (secondary). method_v1 used for Dates x1-x2, and method_v2 from Dates x2-x3 will be common. However, the "which version should we use" given dates and other criteria logic I want keep separate though, to make the create of these classes and additional methods easy for other developers.
Without any other specifications, it sounds like you want to use an interface:
interface Rules {
Response processRule();
}
class Rules_v1 implements Rules {
public Response processRule() { ... }
}
class Rules_v2 implements Rules {
public Response processRule() { ... }
}
It's not possible to version a method. A single signature can only appear once. You could have different classes that have the same method, and retrieve them via a factory, or some other method, but you can't do what you're asking.
You may use separate classloaders for loading different versions of the same class... but be warned that working with classloaders is a real pain.
I think that a simple OOP approach (as suggested in other answers) could be more convenient.
Or you could do versioning internally:
processRule(..., int Version = 0)
{
switch (Version)
//etc
}
If you default Version == 0 as "current version", this might be relatively practical?
My argument is that what you call "business logic versions" is actually business logic itself, because you are explicitly using multiple versions because your business demands it.
Ideally you would never have to do this, but if you do have to maintain methods that map to elements in some versioned wire interface, then represent versions as values in the language, and use a trampoline method to keep your API simple.
enum Version {
V1,
V2,
V3,
;
}
public class ClassWithVersionedMethod {
// Protected to allow overriding while preventing clients from calling
// versioned methods explicitly, and to minimize clutter in the javadoc and
// IDE-autocomplete menus.
protected T methodV1(...) { ... }
protected T methodV2(...) { ... }
protected T methodV3(...) { ... }
// Final to prevent overriding of unversioned method by accident.
public final T method(Version v, ...) {
switch (v) {
case V1: return methodV1(...);
case V2: return methodV2(...);
case V3: return methodV3(...);
}
// Throw outside switch so that we get a compiler warning when
// someone adds a member to Version.
throw new AssertionError("Unsupported version " + v);
}
}
This is a tribute to Kajetan Abt's answers but upgarded.
public void processRule(int version)
{
switch (Version){
case 1:
executeRule1();
break;
case 2:
executeRule2();
break;
}
}
//executeRule1(), executeRule2() functions declarations here
I think this is better than creating new classes because you are trying to keep all previous versions of methods.
Basically what said in other answer : Use an Interface.
public interface Car {
public void start();
public void drive();
}
How to apply: to totally keep version mess away from code, create a separate implementation of that Interface, per version.
public class CarV1 implements Car{
public void drive(){}
public void start(){}
}
public class CarV2 extends CarV1{
#Override
public void drive(){//--extra--}
}
public class CarNewV3 implements Car{
public void drive(){//--new--}
public void start(){//--new--}
}
You may create full implementation classes from scratch, or extend previous versions to add/override some functionality.
Finally, to wire it all together, that is, to serve appropriate versions, you can use:
Factory classes, they can provide implementations for a specific version. This class can check some parameters and choose to use a specific version.
public class CarFactory(){
public static Car newCar(){
if(year >= 2013){
return new CarNewV3();
}else if (year >= 2000){
return new CarV2();
}else{
retrun new CarV1();
}
}
}
Or, Use some DI framework, this way, you write a little extra set-up class (module) where you figure out the best implementations to use at run time.

Java design pattern: event system, multiple actions for a given actor

I have a system that manages events that happen to multiple actors using a simple queue-based system. Event is a simple class that has time and an abstract method fire(). Actor is a simple interface that implements two methods - think() and act(). Each actor has 2 basic events, that are implemented like that:
public class ActorThinkEvent extends Event {
private Actor actor;
public ActorThinkEvent(Actor actor, long time) {
super(time);
this.actor = actor;
}
public void fire() {
Main.game.queue.add(actor.think());
}
}
public abstract class ActorActEvent extends Event {
protected Actor actor;
protected ActorActEvent(Actor actor, long time) {
super(time);
this.actor = actor;
}
public void fire() {
long spent = act();
Main.game.queue.add(new ActorThinkEvent(actor, time + spent));
}
public abstract long act();
}
This way, "thinking" invocation is fixed, it is supposed to generate an ActorActEvent that would be added to the global queue, while "acting" invocation is done using a custom ActorActEvent-based class that implements the action, just returning the time spent, and new "think" event would be added to the queue automatically.
The problem I see here is that implementation of ActorActEvent-based classes comes down to simple delegation from ActorActEvent.act() to some method of Actor class with pre-stored arguments, i.e. all my ActEvent classes look very similar:
public class ActorMoveEvent extends ActorActEvent {
private Coords delta;
public ActorMoveEvent(Actor actor, long time, Coords delta) {
super(actor, time);
this.delta = delta;
}
public long act() {
return actor.moveBy(delta);
}
}
public class ActorReloadEvent extends ActorActEvent {
public ActorReloadEvent(Actor actor, long time) {
super(actor, time);
}
public long act() {
return actor.reload();
}
}
public class ActorPickupEvent extends ActorActEvent {
private ItemStash wantedItems;
public ActorPickupEvent(Actor actor, long time, ItemStash wantedItems) {
super(actor, time);
this.wantedItems = wantedItems;
}
public long act() {
return actor.pickupItems(wantedItems);
}
}
I might up end with several dozens of such classes. If I understand correctly, it's classic implementation of Command pattern. However, I don't feel good about all these delegation classes and especially about writing them all manually.
I thought of using Java's reflection and stuff like Method.invoke(), while passing Method instance and pre-stored arguments to it in generic ActorActEvent class, however, it would be fairly slow. I thought of writing up a generator for all these classes, but it looks like a fairly clumsy solution to me.
If it would be some modern scripting/functional language, I'd end up using block/closure-like structure, preparing it first and invoking it when the time comes. Alas, I don't know how to make it efficiently in Java.
Are there any bright ideas on what can I do to improve the situation?
My advice is to go down the reflection path. Worrying that "it would be fairly slow" is premature in this case. The performance of reflection has been pretty decent for the past decade now, and you will be able to cache your Method objects to save the time spent reparsing names (which is probably the biggest performance hit). This approach is flexible and quick to implement.
If you really like your closures though, you can experiment with anonymous inner classes for your events. There are a few restrictions - you will still have to declare your methods so it is a little more verbose, and you'll need to declare your variables as final in order to access them from within the inner class. This approach will give you all the performance and safety of static types but you'll still have to have a class for each event.
Historically, events have exhibited a 'worst of both worlds' behaviour and passed around Objects, relying on the target to know how to cast and deal with them.

Categories