Saturday, January 23, 2010

Code Design Decision - Protecting Delegate Access?

Ran into this design desicion on one my engagements. Consider an abstract class implementation  that references a reference to another (delegate) object. Convenience methods are in the primary class class that are callled by concrete classes. This pattern can also exist in a concrete that delegates to another implementation.

public class AbstractClass{

private Delegate delegate;

void methodCallA() { delegate.methodCallA());
void methodCallB(String arg) { delegate.methodCallB());

}


This is a common idiom applied to the service/dao pattern, where a DAO delegate would never be exposed to consumers using a service instance. However, in my situation I was implementing a framework solution outside of data access, and was mulling over how far to go with hiding accesss to the delegate instance.

The idea is to provide access to the referenced object only from abstract class methods. However, as this design evolved, sometimes it seemed cumbersome to have to define an additional method in the abstract class, so I asked myself should I always hide delegate accessf from consumer, as shown below?

.....
public void concreteMethod() {
...
delegate.methodCallA();
...
}

I answered this question by asking myself there was a chance that the associated object implementation would ever have to be replaced, or some kind of pre or post conditioning may be required? If there's a chance, then protecting access to the delegate with access methods is worth the extra method definitions in the based class. However, this assumes only the delegate is only providing a few methods for the base class, if more than 7ish methods, then it would be cleaner to eliminate the base class access methods, and let concrete classes access the delegete directly.

If the conditions are met above, then allowing public access to the delegate can shorten the number method implementations, and new methods defined in a delegate are immediatly available for consumption.



Monday, November 3, 2008

Making JEE Software Development Agile

Agility is the verb that has been assigned as the solution for IT's slushiness in developing custom software. While, applying an agile process helps, if the software development mechanism is not agile, then it will be for not. Listed below are things that should be put into place in order to support an agile software construction environment.

Consistent Application Architecture
Consistency promotes predictability, scalability, and re-usability in software development. Impacts of applying new frameworks and patterns can be predicted. Consistent application structure and application of frameworks allows developers to functionally decompose there work efforts in a consistent manner for level of effort and resource planning. Additionally, consistency promotes reuse, as generalized components can rely upon an expected consuming application structure.

Convention over Configuration
Whenever possible, introduce generalized mechanisms that allow developers to start writing code out of the box. Eliminate having to set up or visit configuration files, hunting down libraries. The developer should always produce code that is verifiable and directly solving a problem space. As opposed to having perform setup or initialization activities.

Continuous Integration Environment
Establish an automated mechanism that "continuously" and frequently compiles/builds/deploys/tests code committed by the team to the repository. This environment helps ensures quality, and eliminates the inefficiencies developers can have when dealing with code resulting from merging activities. Less time is spent setting up demo and prototype environments for verification, allowing developers to keep there stream of consciousness in providing a solution.

Reference Application
Define and maintain a basic application that represents your application architecture. This can then be used a medium to describe how applications are constructed with your architecture, and communicate and prove new frameworks or technologies. Scaling agile development can also be enforced, by documenting steps required to build this application. New resources can then go through this exercise which will expedite there learning curve on there own, whithout taking away from existing resources.

Low Ceremony
Provide an envrionment in which the development team can easily install supporting software such as application servers or database instances. This of course, is limited to just the construction phase of the project, but by providing this "low ceremony" ability, agility is achieved by by passing the normal IT administration protocol during construction. Things can happen quicker, and after an agile spring/iteration verificaiton the team will have a better understanding of the "to be" production environment. At the same time quickly deliver early working deliverablse and versions of the software.

Knowledge Access
Take advantage of WIKI software, which will providce a way to communicate your application architecture and development environment. The WIKI brings agility to documentation, as it can be edited in-line allowing developers to collectivley contribute to it, thereby helping to keep documentation fresh and relevent.

Thursday, October 16, 2008

Aspect Oriented Programming - Is it black magic?

When first exposed to AOP a rush of potential application occurs, the possibilities where intoxicating. A myriad of possibly utilities come to mind with the ability to transparently apply logic (advice in AOP terminology) to instance creation, method calls, variable initialization (joint points in AOP).

Frameworks and approaches have been around for a while that allows instrumentation of Java bytecodes usually used for peformance profiling or applying the "proxy" design patterns implementations. AOP does this with a formal declartive programming language, making its application less technical allowing it to be applied safely, easily, and transparently.




AOP was developed around the mid-ninties to help with modularization. OO based languages were promising reuse and lego building block type productivity, but functionality that cut across modular boundaries such as logging, transaction and security was standing in the way of reuse. With OO you can deliver a generalized abstract solution for a problem space. Users of this solution can apply it an access it's various methods in arbitrary fashion providing much utility. Consider a generalized purchase order PDF component/framework specific for a purchasing sytem. Users can apply this framework by extending from classes or implementing interfaces and calling public API methods. This framework can then be reused and embedded in applications with other frameworks, components, and custom code to form an end user solution. However, we want to just reuse the PDF purchasing component and may not have source, nor the desire to change component source code. This is where AOP technology comes into play. With AOP allows interception of method calls, instance creation, or variable assignment and the ability to apply advice (logic) to these interceptions (join points).
that generali but a problem arises when this solution is put into use. requires different transaction demarcation boundaries or security privleges. Each use of the solution requires different access paths that are determined by how the solution is used.

Why AOP?

AOP is a product of early researchers to solve the modularity problem of object oriented software development. OO languages have most of the constructs available such as inheritence, polymorphism, and information hiding that allows for resuable components to be defined that can be configured and exercises in a black box type of way to solve a problem. However, objects making up a framework of component boundary will invariable have to integrate other reusable components/frameworks (ala Log4J), or apply some kind of logic (security/transactions) that cannot be predicted across implementation along with creating usage and framework dependencies. AOP allows things like logging and security to be applied to solutions from outside the code, allowing developers to write source code purley for a specific domain solution. AOP proramming is applied in the context of how your component(s) need to be used, therefore promoting more reuse, removing depedencies, and providing cleaner code.


Quick Primer


There'a a lot to AOP, but here's a quick primer that will hopefully help with general understanding. An Aspect is the programming element you want to apply. For instance a Logging aspect will apply logging. The example below is a logging aspect defined for the Spring AOP framework. The annotations and special method signature makes this an Aspect. There are other AOP frameworks AspectJ, AspectWerkst to name a couple. AspectJ can be used as a stand alone solution and it provides much broader ability to apply AOP. With Spring AOP you can only apply aspects to methods visible to the application context. AspectJ AOP allows aspects to be applied to any method, property, instance creation, or thrown exception.



Where an annotation is applied is determined by a Pointcut which is an AOP way to specify where an annotation should be applied. In the case of Spring AOP aspects can be applied to a classes method execution point during runtime, which can be, before, during, or after. This is defined using general or specific method signature patterns that can be wildcarded so that an aspect can be targeted towards specific method(s). An example Spring AOP pointcut definition is shown below that apply and Aspect to all instance methods to classes defined in the service package. The example shown below is a Spring annotation based Aspect that will log all method calls to anything matching the controller class package specified by the @Before pointcut annotation.



@Aspect
public class Logger {


@Before("execution(* com.*.controller.*.*(..))")
public Object logController(JoinPoint call) throws Throwable {


Log log = LogFactory.getLog(call.getTarget().getClass());
log.info("WM-CONTROLLER EXECUTION:" + call.getTarget().getClass() + "." + call.getSignature().getName());
return null;


}

}



How to Adopt

You can become familiar safley apply AOP by using to to support debugging and performance tuning tasks. For example create a logging example that reports method execution timings, yuo can easily apply logic that senses for methods where most time is spent. Once you become mreo comfortable you can defined aspects that will support production implementations. These could include aspects apply object caching, or apply security and transactions behaivor. Don't use AOP to apply or control business logic, as tempting as it may be this kind of misues may seem state of the art, but instead coul lead to hard to maintain and fragile source code.

Tuesday, August 5, 2008

Annotations and Agility

Frameworks are commonly configured through external properties either in the form of textual XML files or property *.ini files. While this allows applications to be configured without having to change code, maintaining these files in a team environment can inhibit agility. Attribute Oriented Programming moves configuration information out of centralized property files and puts this meta information closer to relevent source code elments. This information can then be picked up at design and/or runtime and used by a framework.

The XDoclet framework poineered the ability to define useful attribute libraries that support many frameworks. XDoclet was so succefull, that Annotations, another name for attribute, were introduced as a real language construct in the Java 5 SDK.

Quick Java Annotation Primer

Annotations are defined just like a Java class, interface element, they are defined in a package definition and can be targeted towards Class, Variables, or Methods. Additionally, they can be defined with a retention policy, keeping them in compiled class binary files for runtime processing or stripping them out when source is compiled.

Lets create an annotation and put it to use. Consider a @Info annotation that is targeted towards class definition. It simply annotates a class with an owner data and wether a class has been code reviewed. This annotation is defined in java annotation declaration shown below.



@Target({ElementType.TYPE})

public @interface Info


{
String owner() default
"NO-OWNER";
String notes() default "";

String reviewed default “NOT-REVIEWED";


}





You can see the @Info annotation applied to a class definition below.





@Info(owner="dpitt")


public class MyClass {
String attribute = null;
}





The usefullness of this annotation is twofold. First, using the supplied annotation processor source can be scanned and a report generated indicating whether a class has been reviewed. Second, an exception handler can be defined that will sense for the @Info annotation in a stack trace and report who's reposinble for the exception. Source for this exception handler is shown below.




public class ExceptionHandler {
public static void handle(Throwable e)
{
// determine where exception occurred, ignoring sy stem
classes StackTraceElement[] st = e.getStackTrace();
f or (StackTraceElement ele : st) {
String className =
ele.getClassName();
Class cls = null;
try {
cls = (Class) Class.f orName(className);
} catch (ClassNotFoundException e1) {
System.out.println(e1); }

// sense for @Info annotation

if (cls.isAnnotationPresent(Inf o.class)) {
Inf o inf o = (Inf o)
cls.getAnnotation(Inf o.class);
System.out.println("=== Owner of this Exception is: " + info.owner() + " ====");
System.out.println("Error Occurred :" + className);
System.out.print(e);
}
} } }



Agility

Popular frameworks such as Hibernate and Spring have introduced annotations as an option for configuration instead of using XML files. With Hibernate annotations or javax.persistent Annotations can be used to define mapping attributes. An example mapping a class to a table is shown below.



@Entity
@Table(name = "EMPLOYEE")
public class Employee
{



@Column(name = "FIRST_NAME")

public String getFirst()
{...


@Id
@GeneratedValue
@Column(name = "ID")
public Long getId()
{...




Annotations provide agility in development teams by not eliminating the need for developers to reconcile and define framework meta data in property file mechanisms. Eliminating these files may not seem like a big deal, but with a team of 10 developers all having to add and synchronize configuration files. Allowing configuration info to live close to source elements, lets developers spend more time writing software for a given problem, and not chasing down configuration issues.