BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

ANN: My AOP for Delphi Frame - MeAOP V0.5

 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi Thirdparty Tools (General)
View previous topic :: View next topic  
Author Message
Riceball LEE
Guest





PostPosted: Sun May 14, 2006 1:14 pm    Post subject: ANN: My AOP for Delphi Frame - MeAOP V0.5 Reply with quote



= Delphi AOP(Aspect Oriented Programming) Frame - MeAOP Ver 0.5 =

=>writen by Riceball LEE>=

== Introduce AOP ==
Aspect Oriented Programming, IMO, the aspect is the general feature in
fact. It's a helper for object-oriented programming to
re-use the feature(function), such as the Login feature. Aspect
Oriented Programming attempts to aid programmers in the
separation of features, or the breaking down of a program into distinct
parts that overlap in functionality as little as possible.

1. distill/separate the general features from many classes;
2. many classes can share the feature, so it need not to modify many
classes if the feature've been changed.

I treat the Aspect Oriented Programming as Featrure Oriented
Programming.

IMO, the AOP core implementation is inject(patch) and intercept the
method of class.

=== Example ===

Let's introduce AOP with the help of an example. Imagine an application
that works concurrently on shared data. The shared data may be
encapsulated in a Data object (an instance of class Data). In this
application, there are multiple objects of different classes working on
a single Data object, whereas only one of these objects may have access
to the shared data at a time. To achieve the desired behaviour, some
kind of locking must be introduced. That means, that whenever one of
these objects wants to access the data, the Data object must be locked
(and unlocked after the object has finished using it). The traditional
approach is to introduce an (abstract) base class, from which all
"visiter" classes inherit. This class defines a method Lock() and a
method Unlock() which must be called before and after the actual work
is done (semaphores, basically).

<code>
TCustomVisiter = Class
protected
procedure Locked();virtual;abstract;
procedure Unlocked();virtual;abstract;
published
procedure AccessDataObject();virtual;
end;
}
</code>


This approach has the following drawbacks:

* Every method that works on the data has to take care of locking.
The code is cluttered with statements related to locking.
* In a single inheritance world, it is not always possible to let
all visiter classes inherit from a common base class,
because the one and only inheritance link may already be consumed
by another concept. This is especially true if the locking
features must be introduced into a class hierarchy after the
hierarchy has been designed, possibly by another programmer
(e.g. the developer of a class library).
* Reusability is compromised: The visiter classes may be reused in
another context where they don't need locking
(or where they have to use another locking scheme). By putting
the locking code into the visiter classes, the classes
are tied to the locking approach used in this specific
application.

The feature of locking in our example application can be described with
the following properties:

* It is not the primary job of the visiter classes
* The locking featrure is independent of the visiter's primary job
* locking featrure cross-cuts the system, i.e. many classes, and
probably many methods of these classes, are affected by locking.

So, a new program construct should be defined that takes care of
cross-cutting features of a system, eg, the locking feature of this
application.


In our example application, the aspect Lock would have the following
responsibilities:

* provide the neccessary features to lock and unlock objects to the
classes that have to be
locked/unlocked (in our example add lock() and unlock() to the
Data class)
* ensure that all methods that modify the Data object call lock()
before their work and unlock()
when they have finished (in our example the visiter classes).

the locking feature looks like this:

<code>
TLockingFeature = Class(TMeCustomFeature)
protected
procedure Locked();virtual;
procedure Unlocked();virtual;
function Islocked(): Boolean;virtual;
protected
function AllowExecute(Sender: TObject; MethodItem:
TMeInterceptedMethodItem): Boolean;override;
procedure AfterExecute(Sender: TObject; MethodItem:
TMeInterceptedMethodItem);override;
end;

function TLockingFeature.AllowExecute(Sender: TObject; MethodItem:
TMeInterceptedMethodItem): Boolean;
begin
Result := not IsLocked; //only not isLocked can be allow execute.
if Result then Locked;
end;

procedure TLockingFeature.AfterExecute(Sender: TObject; MethodItem:
TMeInterceptedMethodItem);
begin
Unlocked;
end;
</code>

Now, you need to add the locking feature to the methods of classes.
that' all.
<code>
//add the feature to the published method:
TCustomVisiter.AccessDataObject.
TLockingFeature.AddTo(TCustomVisiter, 'AccessDataObject');
</code>

Note: the locking feature only affects the current injected method of
the class, not affects the derived class if the derived class override
the method.

There are two solvers if you wanna add the feature to the derived class:

solver 1: the derived class have to call the inherited method the
parent class
<code>
TMyVisiter = Class
protected
procedure AccessDataObject();override;
end;

procedure TMyVisiter.AccessDataObject();
begin
inherited AccessDataObject();
.....
end;

</code>

Solver 2: add the feature to derived class if need.
<code>
TLockingFeature.AddTo(TMyVisiter, @TMyVisiter.AccessDataObject,
'AccessDataObject');
TLockingFeature.AddTo(TOtherVisiter, @TOtherVisiter.AccessDataObject,
'AccessDataObject');
</code>

=== AOP Concepts ===
the general features for AOP:

|| * Authentication ||
|| * Caching ||
|| * Context passing ||
|| * Error handling ||
|| * Lazy loading ||
|| * Debugging ||
|| * logging, tracing ||
|| * profiling ||
|| * monitoring ||
|| * Performance optimization ||
|| * Persistence ||
|| * Resource pooling ||
|| * Synchronization ||
|| * Transactions ||
|| * Remote Method Calling ||

== MeAOP: My AOP For Delphi Frame ==
my AOP For Delphi Frame is base on the code injection. heavy hack to
delphi, patch the binary codes to implement the interception of the
method.
I do not like the implementation of the dynamic proxy. It's performance
is very low, inject the code directly is the fastest and the best
solver.
I wish my AOP is simple, effective and easy to use enough. BTW, I call
my AOP For Delphi Frame as MeAOP.

You do not care the bewildering concepts: joint, advise, cross-cut etc
in the MeAOP. you just need to know the concept: feature.
the core of MeAOP distill the custom feature class, and your work is
design your feature class and add it to the specified method of class.
You just call the AddTo class function of the TMeCustomFeature to add
your feature to the specified method of class. eg,
<code>
TMyFeature.AddTo(aClass, @aClass.aMethod, 'aMethod').
</code>

BTW, you even can add your to a procedure.
<code>
TMyFeature.AddTo(@aProcedure, 'aProcedure').
</code>


then how to design your feature class? very simple.
just override the BeforeExecute, AfterExecute etc method in your
TMyFeature class. That's all.
of cause your all features should be derived from the TMeCustomFeature.

Note: [Ver0.5] Currently supports procedure(method) with no parameters
only. No function can be allowed.

<code>
TMyFeature = class(TMeCustomFeature)
protected
{: run the methodItem only return True }
{ If you do not override it always return true.}
function AllowExecute(Sender: TObject; MethodItem:
TMeInterceptedMethodItem): Boolean;override;
{: trigger on before the MethodItem is executed and after
AllowExecute return true.}
procedure BeforeExecute(Sender: TObject; MethodItem:
TMeInterceptedMethodItem);override;
{: trigger on after the MethodItem is executed even though the
MethodItem's raised exception . }
procedure AfterExecute(Sender: TObject; MethodItem:
TMeInterceptedMethodItem);override;
{: trigger on after the MethodItem's raised exception . }
procedure AfterException(Sender: TObject; MethodItem:
TMeInterceptedMethodItem; E: Exception);override;
end;
</code>

=== MeAOP Structure ===
Three Levels:
1.the lowest level core : the TMeInjector object for the method and
procedure
provide the simplest and the lightest injector(one injector only
take 36 bytes memory)
2.the middle level core: the TMeInterceptor class for the method and
procedure
2.1. TMeCustomInterceptor : supports the method or procedure with
no paramaters
2.2. TMeInterceptor: supports the method or procedure with
paramaters
3.the top core: the TMeCustomFeature
provide the feature oriented programming class library. You can easy
add the new feature class to the specified method of the class .

=== MeAOP Download ===
Current Version: 0.5.0.0
+ Supports the procedure and method with no parameters(do not support
the function

* MeAOPv05.rar (no src, D7 D10)

http://dev.cq118.com/UploadFiles/attachments/Delphi/AOP/Readme/MeAOPv05-
1.rar

Just for test.


--
Happy coding with pascal
Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi Thirdparty Tools (General) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.