Good software tries to model and implement the various needs of a system or application apart from each other. This is called "separation of concerns". A concern can be many things, but in general, it is a concept. In AOP, Aspect Oriented Programming, there is an ability to actually code a concern that crosscuts many locations in an application as a single entity.
This capability allows a developer to write code that does not have duplication (DRY, don't repeat yourself). It is likely that requirements for your system are written by a business analyst, not a computer scientist. This means the person may likely know many things from software development such as terminology from security. The gravity of an agile world encourages us to "keep it simple". This means a requirement will be written in an allegedly simple way, incorporating security features into a business operating feature. This attempt at simplifying things by uniting security concepts with application concepts, leads to "domain pollution". That is the domain of the business is all that the SME (Subject Matter Expert) writes. Well, this leads to domains that are abominations. Animals aren't just created by declaring this dear needs to have wings because it may run out of food sources, so we need it to be able to get to this other area for food.
You, the developer will have to untangle the real security concern from the business concern. If the requirements can be expressed in a way that utilizes terminology form different specific domains, then this blending can be stopped. And we will reduce the needless smashing and untangling of concepts all because it was thought to be simpler.
Showing posts with label AOP. Show all posts
Showing posts with label AOP. Show all posts
Wednesday, April 18, 2012
Tuesday, October 06, 2009
Enhance Exceptions with Context
Don't you wish sometimes that Java had the feature for exceptions to automatically capture the values of the variables in the context that were present when an exception occurs? Well I guess we just have to do it manually. Let's see what it would look like:
Ok, now whenever someone calls someMethod("noa-b-c"); they will get a friendly message in the exception telling them what the value of x was during the invocation. That wasn't too bad, but what if the method had 3 parameters? What if you didn't have the try block around the whole body and it still threw an exception?
There must be a better way? I don't want to always tell the computer how to do things, how come I can't just say what I want? I want to tell Java that when an exception happens in my method, it should capture the context and chain the original exception. I will just use an annotation to tell Java to do this for me.
There, that is better! Um, wait, how is that going to work? Now I am going to have to make something that will process that annotation and put the try catch there and include the parameter values. I could run my code in some sort of container that I can proxy the object of SomeClass and in the proxy I can add this new feature, then I need to make sure that all my clients to this method go through the proxy, then oops, I need to use CGLIB because I didn't use an interface, man, that is goign to all be easy.
There must be a better way! AspectJ is still Java, let's see if that wil work. We can create a pointcut for methods that have the @ThrowsContext annotation, and after the method throws an exception, we will chain it with our exception with a message of the context and chain teh original exception.
That is pretty to the point, it says what I want to do which makes programming more productive and fun. Maybe you don't want the context to leak out of your components, but you need this information to support debugging durign development, you can use LTW Load Time Weaving supported by AspectJ to only add this aspect behavior during deployments that you decide should have it.
Next time we will enhance the context and provide options to which context to include.
And here is the annotation:
public class SomeClass {
public void someMethod(String x) {
try {
int pos = x.indexOf("abc");
String y = x.susstring(pos);
} catch (RuntimeException e) {
throw new RuntimeException(
"there was a problem here, with param x="
+ x, e);
}
}
}
Ok, now whenever someone calls someMethod("noa-b-c"); they will get a friendly message in the exception telling them what the value of x was during the invocation. That wasn't too bad, but what if the method had 3 parameters? What if you didn't have the try block around the whole body and it still threw an exception?
There must be a better way? I don't want to always tell the computer how to do things, how come I can't just say what I want? I want to tell Java that when an exception happens in my method, it should capture the context and chain the original exception. I will just use an annotation to tell Java to do this for me.
public class SomeClass {
@ThrowsContext
public void someMethod(String x) {
int pos = x.indexOf("abc");
String y = x.substring(pos);
}
}
There, that is better! Um, wait, how is that going to work? Now I am going to have to make something that will process that annotation and put the try catch there and include the parameter values. I could run my code in some sort of container that I can proxy the object of SomeClass and in the proxy I can add this new feature, then I need to make sure that all my clients to this method go through the proxy, then oops, I need to use CGLIB because I didn't use an interface, man, that is goign to all be easy.
There must be a better way! AspectJ is still Java, let's see if that wil work. We can create a pointcut for methods that have the @ThrowsContext annotation, and after the method throws an exception, we will chain it with our exception with a message of the context and chain teh original exception.
public aspect ExceptionContext {
pointcut ctx(ThrowsContext t, Object th) :
execution(@ThrowsContext * *..*(..)) &&
@annotation(t) &&
this(th);
after(ThrowsContext t, Object th)
throwing(RuntimeException e) : ctx(t, th) {
Object[] args = thisJoinPoint.getArgs();
throw new RuntimeException("parameters: " +
Arrays.toString(args) + "\nthis=" +th, e);
}
}
That is pretty to the point, it says what I want to do which makes programming more productive and fun. Maybe you don't want the context to leak out of your components, but you need this information to support debugging durign development, you can use LTW Load Time Weaving supported by AspectJ to only add this aspect behavior during deployments that you decide should have it.
Next time we will enhance the context and provide options to which context to include.
And here is the annotation:
@Retention(value=RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ThrowsContext {
}
Monday, March 09, 2009
Introduce JAXB to your POJOs
Suppose you want to keep your POJO really a POJO? If you use JPA annotations on a class, is it still really a POJO? A POJO should be usable as a domain object independent of whether it came from a database, or from a remote service. So If I see @Entity on your POJO, I know it is really a database object, and I start thinking all about it's dependencies, do I need a transaction, do I need a JDBC connection, what JAR has the JPA annotation, maybe it isn't in my JRE, no more a "plain" Java object.
Ok, but I want to store my POJO in a database, what do I do? Ok, that will be my next article... Today, what if I want to use JAXB to serialize the POJO as XML? Then I need to use @javax.xml.bind.annotation.XmlRootElement to annotate the class. That just ruined my POJO. AspectJ can add fields, methods, annotations, and parents to classes. Why not just introduce the JAXB annotations necessary to marshal the object at runtime just for the situation that I need?
Here is my POJO:
Now, here is the POJO with the JAXB annotation:
Isn't marshaling an object to XML a totally different concern from if an Order needs the customer's email address? So, let's separate those two concerns:
This aspect introduces the XmlRootElement annotation to the Order class, keeping Orders, Orders.
Next time I'll show how to run this example.
Ok, but I want to store my POJO in a database, what do I do? Ok, that will be my next article... Today, what if I want to use JAXB to serialize the POJO as XML? Then I need to use @javax.xml.bind.annotation.XmlRootElement to annotate the class. That just ruined my POJO. AspectJ can add fields, methods, annotations, and parents to classes. Why not just introduce the JAXB annotations necessary to marshal the object at runtime just for the situation that I need?
Here is my POJO:
public class Order {
private String number;
private String product;
private String customerEmail;
private String customerName;
}
Now, here is the POJO with the JAXB annotation:
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Order {
private String number;
private String product;
private String customerEmail;
private String customerName;
}
Isn't marshaling an object to XML a totally different concern from if an Order needs the customer's email address? So, let's separate those two concerns:
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public aspect Jaxbify {
declare @type : Order : @XmlRootElement;
}
This aspect introduces the XmlRootElement annotation to the Order class, keeping Orders, Orders.
Next time I'll show how to run this example.
Wednesday, December 05, 2007
How Important is Symmetry in JPA?
When you are designing a domain model using JPA or hibernate or another declarative approach to ORM, you must decide the cascade rules for creating and deletign objects that are related to each other. When you have a one-to-many relationship between two objects, when an object is persisted, you need to decide if the related object should be automatically persisted as well, or should you have to persist each object?
To me it seems that this must be made symmetrical, that is if you cascade create, then you should cascade delete as well. Any other rule than this makes your system more complicated. Intuition should be available to one trying to understand your domain model, and symmetry is a part of nature, so it will be intuitive to expect a consistent behavior. If you are using JPA, the cascade rules will be in the code so you will see the rule with the code so it will be evident of your choice. In the case that you are using Hibernate from an XML configuration file that is not visible at the same time as the source code, then you will have to remember the cascade rules, minimizing the burden of memorizing too many things can help in comprehending your model, a consistent rule of always cascade create with delete will eliminate this from your efforts.
In a more encapsulated direct approach, I recommend that a new annotation of @Aggregation be created that has this behavior as it's meaning, it is simple and precise as to the intent. AspectJ can be used to create this annotation, and with JPA annotations as the ORM approach, the needed annotations can be injected behind the scenes. This seems like a nice clean use of AOP to help in using of JPA.
To me it seems that this must be made symmetrical, that is if you cascade create, then you should cascade delete as well. Any other rule than this makes your system more complicated. Intuition should be available to one trying to understand your domain model, and symmetry is a part of nature, so it will be intuitive to expect a consistent behavior. If you are using JPA, the cascade rules will be in the code so you will see the rule with the code so it will be evident of your choice. In the case that you are using Hibernate from an XML configuration file that is not visible at the same time as the source code, then you will have to remember the cascade rules, minimizing the burden of memorizing too many things can help in comprehending your model, a consistent rule of always cascade create with delete will eliminate this from your efforts.
In a more encapsulated direct approach, I recommend that a new annotation of @Aggregation be created that has this behavior as it's meaning, it is simple and precise as to the intent. AspectJ can be used to create this annotation, and with JPA annotations as the ORM approach, the needed annotations can be injected behind the scenes. This seems like a nice clean use of AOP to help in using of JPA.
Sunday, August 05, 2007
Is-a vs. has-a
When you model your system in object oriented methodologies, you have to choose whether a class "is-a" a certain type or if it "has-a" a certain type. Is this confusing? The best way to think of this is to ask what is a customer? If you have a class "Person" in your model, then you might think that a "Customer" is-a "Person". But that starts to get complicated. A customer is someone who has bought a certain product. So, can you scale the is-a version of customer to purchasing of multiple products? Maybe you can model a customer as an order that has been fulfilled, and a person can have a collection of orders, thus a person "has-a" collection of orders. But many situations involving two different products do not occur at the same time usually, so you would preferr to just treat the person as a customer while in the situation involving a certain product.
Then you could have the best of both worlds. But what system or languatge can handle this? You would always have to have some sort of layering and pretend that the other stuff doesn't matter while on the boundaries of the layer. What if there was a DBMS that could let you define both simple versions of person and customer, and the DBMS would integrate the various views as real objects?
An AODBMS would be able to define various dimensions of the same entity and provide a way for the simplified dimensional slice to integrate the various views into a single database entity.
Then you could have the best of both worlds. But what system or languatge can handle this? You would always have to have some sort of layering and pretend that the other stuff doesn't matter while on the boundaries of the layer. What if there was a DBMS that could let you define both simple versions of person and customer, and the DBMS would integrate the various views as real objects?
An AODBMS would be able to define various dimensions of the same entity and provide a way for the simplified dimensional slice to integrate the various views into a single database entity.
Wednesday, February 28, 2007
Persistent Data Aspects
If a database has persistent data that comes from an aspect, what would it be? Examples of this would be design patterns implemented as an aspect, metadata about an object, or other data that is introduced by the aspect. Also, a data "feature" will change the way data is stored in the database. The feature of a "revision history" is implemented as an aspect of the persistent data. The feature changes the persistence of a regular object to contain the modification time, and the prior instances.
In order to access the revision history of an object that has the feature of versioning, an aspect query syntax is needed to provide access to the custom information. an example of a query that returns the sequence of instances that represent the change history of an object could be:
select aspect(Version) from Customer where customerId = "12345"
This would match against the customer extent finding the instance that has a customerId of 12345, and returns the result defined by the "Version" aspect. This could be an envelope containing the instance at the time of a modification, and the time modified as a collection.
The result of accessing an object redefined by a "Version" aspect will depend on it's context. The normal usage would be just like any other object access. But what if you want to access the view of the object at a prior point in time? The context time of the query can be modified and the same query that provides a normal object could return the value of the object at the context time. The query can be reusable accross different contexts with different meanings.
A RDBMS typically supports triggers that are procedures that are executed at certain events within the database. This is a very normal aspect oriented flow. So, an aspect oriented database would not run a trigger, but just advice at the certain event defined by the DBMS. Also, the design pattern of an observer can be implemented as an aspect that would introduce a relationship between the subject and observer. The modification of the subject sends events to the observer(s). This is the same pattern as a trigger, but in an AODBMS the paradigm of thought is advice and design patterns as reusable aspects.
In order to access the revision history of an object that has the feature of versioning, an aspect query syntax is needed to provide access to the custom information. an example of a query that returns the sequence of instances that represent the change history of an object could be:
select aspect(Version) from Customer where customerId = "12345"
This would match against the customer extent finding the instance that has a customerId of 12345, and returns the result defined by the "Version" aspect. This could be an envelope containing the instance at the time of a modification, and the time modified as a collection.
The result of accessing an object redefined by a "Version" aspect will depend on it's context. The normal usage would be just like any other object access. But what if you want to access the view of the object at a prior point in time? The context time of the query can be modified and the same query that provides a normal object could return the value of the object at the context time. The query can be reusable accross different contexts with different meanings.
A RDBMS typically supports triggers that are procedures that are executed at certain events within the database. This is a very normal aspect oriented flow. So, an aspect oriented database would not run a trigger, but just advice at the certain event defined by the DBMS. Also, the design pattern of an observer can be implemented as an aspect that would introduce a relationship between the subject and observer. The modification of the subject sends events to the observer(s). This is the same pattern as a trigger, but in an AODBMS the paradigm of thought is advice and design patterns as reusable aspects.
Aspect Query Language
An aspect oriented database should support an aspect oriented query language. What would the aspect paradigm do to influence other query languages? There is SQL, JDOQL, EJBQL, OQL, and others. AQL or "Aspect Query Language" would be a query language that supports queries against an aspect oriented database. There are persistent aspects, and persistent data that has been annotated by aspect introduced metadata. An aspect oriented database is a regular database that contains metadata or out of band data integrated with objects. Sure anydatabase can create metadata tables and join it to another table. So what is special about the aspect metadata? In part is a matter of representation, that is there will be keywords distinguishing the aspect data from the object data. The other side of the power of aspect data management is the implicit introduction of information based on contexts of the usage of objects in relationships.
Subscribe to:
Posts (Atom)
Labels
- agile (2)
- annotation (2)
- AOP (7)
- Aspect (1)
- AspectJ (4)
- concern (1)
- Context (1)
- database (2)
- DBMS (2)
- Design Patterns (1)
- Domain (1)
- domain model (1)
- DRY (1)
- DSL (1)
- Exceptions (1)
- grow (1)
- hibernate (1)
- Java (3)
- JAXB (1)
- JPA (2)
- OO (2)
- ORM (1)
- requirements (1)
- SME (1)
- software development (1)