5

This is a continuation of this Code Review question.

What was taken away from that post, and other aspect oriented design is it is hard to debug. To counter that, I implemented the ability to turn tracing of the design patterns on. Turning trace on works like:

//This can be added anywhere in the code
Run::setAdapterTrace(true);
Run::setFilterTrace(true);
Run::setObserverTrace(true);

//Execute the functon
echo Run::goForARun(8);

In the actual log with the trace turned on, it outputs like so:

    adapter 2012-02-12 21:46:19 {"type":"closure","object":"static","call_class":"\/public_html\/examples\/design\/ClosureDesigns.php","class":"Run","method":"goForARun","call_method":"goForARun","trace":"Run::goForARun","start_line":68,"end_line":70}

filter 2012-02-12 22:05:15 {"type":"closure","event":"return","object":"static","class":"run_filter","method":"\/home\/prodigyview\/public_html\/examples\/design\/ClosureDesigns.php","trace":"Run::goForARun","start_line":51,"end_line":58}

observer 2012-02-12 22:05:15 {"type":"closure","object":"static","class":"run_observer","method":"\/home\/prodigyview\/public_html\/public\/examples\/design\/ClosureDesigns.php","trace":"Run::goForARun","start_line":61,"end_line":63}

When the information is broken down, the data translates to:

  • Called by an adapter or filter or observer
  • The function called was a closure
  • The location of the closure
  • Class:method the adapter was implemented on
  • The Trace of where the method was called from
  • Start Line and End Line

The code has been proven to work in production environments and features various examples of to implement, so the proof of concept is there. It is not DI and accomplishes things that DI cannot. I wouldn't call the code boilerplate but I would call it bloated. In summary, the weaknesses are bloated code and a learning curve in exchange for aspect oriented functionality.

Beyond the normal fear of something new and different, what are other weakness in this implementation of aspect oriented design, if any?

PS: More examples of AOP here: https://github.com/ProdigyView/ProdigyView/tree/master/examples/design

2
  • Everywhere you do a static call or use a static property (wherever there's a :: in the code) you're creating a tight coupling between the caller and the callee. This is considered bad because it results in code that isn't organized into self-contained modules but where modules are tied to each other and can't be reused or tested in isolation.
    – GordonM
    Feb 18, 2012 at 10:36
  • Not quite. Yes there a lot of static method calls but its loosely coupled because the adapters within the methods. Calling PVSession::readCookie() will always call readCookie, but readCookie execution can be adapted elsewhere. Thats how dependencies of class are tested. Feb 18, 2012 at 16:17

1 Answer 1

2

It doesn't really seem like AOP, because you still have to copy that snippet of code everywhere. It's more encapsulated, sure, but it's still "infecting" your normal business logic. So if setAdapterTrace needs another parameter, or something else like that changes, you now have to change all the other classes using it. This is less of an issue with PHP than with, say, .NET or Java, because of its dynamic nature, but it still seems like something that clashes with the single responsibility principle (which I assume is your reason for going through all of this). At best, it's like a "poor man's AOP".

If you are intent on using AOP with PHP, have you looked at existing tools like php-aop? I haven't, so I'm interested in what you might find lacking in them that you would want to write your own AOP tool.

I should also note that web frameworks like CakePHP may possess some AOP-like functionality that you could use (e.g. beforeFilter in CakePHP). So if you're using a framework, you may already have the capabilities you need.

2
  • 1
    Great observations! What you mostly touched up is the intercepting filters design pattern, which can considered to 'encapsulate' the code. If setAdapterTrace needed another parameters, I would make it have a default value which you refered to as the dynamic nature of PHP. I should mention that the point of the trace is purely debugging and adds overhead to the application when turned on. Also the trace cannot be filtered or adapted then their purpose is to track these operations. One of the things I am considering is using DI for traces rather than strictly defining how the trace is performed. Feb 13, 2012 at 20:38
  • 1
    And yes, frameworks like cakePHP and even Wordpress have filters that can be considered AOP like. If I had to differentiate between them I would say these are more flexible in that they can be set to respond on specific events and allow filtering through anonymous functions, instances and static methods. And now debugging of filters. With adapters, there is only one other framework I know that uses adapters in a similar way for completely changing the execution of a class/method. Feb 13, 2012 at 20:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.