Feb 21

This post is the second of a set of post on the same topic starting here.

Where do I put business logic?

I’ve seen this question raised a lot of times by developers who are dealing with management applications using a persistence stack. This question is simple and legitimate but the answer is a little bit trickier.

First statement: there are different kinds of business logic which have to be in different layers. Business logic is itself fuzzy and quit large. To some extreme some could argue that the entities definition is part of the business logic, even the primary keys as a way to uniquely retrieve an entity. To the other end, a business process is considered as a kind of business logic. I personally think the business logic is wide but exclude the example I just mentioned.

Even if an entity has obviously some business inside its definition, its only data, so no logic at all. For the primary keys, I consider that a exposing primary keys is a mistake that prevent evolution and prevent implementation of high level technical services as archiving for example. The best is to expose 2 attributes per entity for retrieval: one which is human readable (as the ID of an employee) and another one which will be used for application integration. The idea is that these “IDs” are not varying from a system to another, or during the life cycle of the entities (except for exclusive business reasons), in the contrary of an internal primary key which could vary over time.

Bitwise, you can consider that the mandatoryness of an attribute (or validation) are part of the business logic. I agree some could argue it’s exclusively a data modelling concern. That’s not totally wrong but I think there is a mismatch between engine location and configuration. The engine location is of course in the data modelling layer but as this is part of the business logic (from my point of view) this should be configured in the same area as the other business logic: in the configuration. I will address the problematic of configuration later on. At the same level you have other business logics as: right management, partitioning and entity validity (broader than attributes validity).

Back to the initial question: where do I put my business logic? IMHO, the best is to define it in a set of configuration files and let the entities delegate to the appropriate engine. This provides a flexible approach (separation between the configuration and the engine) which is also generic (usage of an engine). This question is not totally addressed by this approach and hides the real problematic: scope of business logic.

The scope of the business logic is far more meaningful and key for a persistence stack. There are at least 3 different scopes:

  • entity attributes
  • entity
  • application
  • inter-applications

The entity attribute scope is for example the scope for validation/mandatoryness of the attribute PONumber in a purchase order for example. The entity scope is for example the global amount of a purchase order which is supposed to be the sum of the amount of the purchase order lines. The application scope is supposed to address the internal workflows to the application as the approval workflow of a user request for example. The inter application scope will address business logic between applications as between the requesting application/service and the catalogue application/service.
You will notice the “entity” word is ambiguous: does a purchase order line is an entity or not? IMHO, from a strict business perspective, I don’t think so, even if it’s convenient. I think a DAO can be considered as entity as soon as it has it’s own validity in the business: does not make sense to talk about a purchase order line outside of the scope of a purchase order. This distinction is sometimes used for value objects versus DAO. I personally prefer use entity and DAO and have both of them in separate layers: Data Access Layer (or data modelling layer) and Domain Layer.
   

 

Jan 31

This post is my 2 cents contribution to the debate on persistance stack architecture. I try to write short post (the shorter it is…the understanding greater is), but this time —with such a topic— I can only fail on this point. So this post will be followed by other posts :-).

I will not start from scratch explanation on the different approachs, the wording and so on…you will find some links in this post that I find usefull and I do not want to be redundant with them. I would like to enlarge the scope of the persistance stack to higly customizable environement and also the various features required by an Entreprise Management Application (taht I will name EMA) relying on a persistance layer.

What are the different layers (required or not)

You will find here an excellent article on the different layers of a typical persistence stack and further…to the UI. The UI is key but I will not address this question in this post. You will notice the author talk about a Persistence Layer which is different from an Persistence Stack. I use the word “Persistance Stack” to express all the layers that are requiered to build an application that use a database without the UI. These layers are usually (from the upper level to the RDBMS middleware):

  • Service Layer
  • Domain Layer
  • Data modeling
  • Persistance Layer
  • RDBMS middleware 

About the interest to respect layering

It’s just about commion sense : by layering correctly you will decouple your code and allow easier replacement of components as there are inricated. Most of the time, developers are doing naturally as it give an impression of over complicated the code. The important point they have to though about that an Entreprise Software relying on database will grow and evolve (faster at the begining) and you will write at the end touthands lines of code. If the rules and delimitations are clear from the begining, you will avoid a real mess of large classes.

Now let see in details the aim of each layers. I will go from down to top to express clearly the boundaries of each layer (starting from top tempt to mix the layer and put the code/requirement at a higher level than it should).

Persistance layer

The persistance layer is juste about persistance…obvious but not always respected. Persisance is only about storing and retreiveing data, nothing else. You can use an ORM (Object Relational Mapping) framework as Hibernate or TopLink for example. It’s only bout storing, that means no validation, no business logic at all, and the objects should be limited to structures, no methods. There is no real interest to build it’s own persistance layer as most of the time your requirement are fulfilled by the most advanced frameworks. That does not means you should not take care in the choice of this framework as this layer is the key for the performances: having a poor framework (even a rich ones depending on how you will use them) will dramaticcaly impact performance by generating useless or not optimized RDBMS queries.

Most of the time these objects are named DAO objects or DAL objects (for Data Access Layer objects).

Tow extensions to EMA that may be include in this layer are rights and partitioning. Rights management is the ability to give read/write access to attributes of the DAL objects. The Partitioning is the ability to segregate the read/write access to DAL objects. These fucntionality have obviously a business aspect,e specially for the partitioning. But for performance reasons (espacially for partitioning which is usually implemented using a where statement), this might be implemented in this layer.

ORM..a myth or not? 

The different post, disucssions and articles I’ve read about persistance stack are highlighting the interest of doing OOP (Object Oriented Programing) especially in the domain layer. Most of the argument yield to the mandatoiness of using an ORM which is the key pivotal framework to step from a relational database to a obejct oriented coding space. This a myth to me and is only relevant for folks that love OOP and particularely love debate about the beauty of it.

ORM use have to be limited to what it is design for: just create DAO objects for upper layer. Some folks abuse of this because they are mixing it with the higher level layers which is strong mistake. I’ve looked at Hibernate and NHibernate (to simplify: NHibernate have the same capabilities than Hibernate v2, but in a .Net environment). As a framework it provides lots of different ways to operate with the RDBMS layer, but you usually use on 10% of them as you are doing some assements. IMHO, this is not a mistake to do so, if you take care that this assement will not have a strong impact on the other layers. You will never be able to take some decisions that have absolutely no impact, but you can mitigate this.

An example of assement is to chose the same type for keys: there is a real advantage to do it, but it will have an impact on the Domain Layer and the evolution of your application (if the type is long…evolve to GUID for example may be tricky if they are exposed and used in the other layers). On this specific point, a good practice is to never expose internal keys outside of the layer but to expose business keys in the Service and Domain layers. For each object, exposing 2 kind of business kay is useful: an international one, and a business one. The international one is a key that won’t varie from a language to another, that is usually a sequence of numbers, which is used by external programs to synchronize data for example. The business one is a key that is usually used by humans over business process as a social key for a employee for example, or a barcode for an asset.

Data Modeling

This layer is most of time mixed with the Domain Layer and Persistence layer, but it can be useful to detail its contract.

In my opinion, part of the contractrthis layer is the dual of the relationship aspect in RDBMS. I deed, you have to define the relationship between various objects in the persistance layer (as a purchase order have order lines for example), but you have to define some low level behaviour. Some of you could say that I start to introduce some business logic here…no, i don’t but you are right: we should not introduce business logic here yet. The behaviour I’m talking about are related to the impact on relationships and complex custom types during CRUD (Create Retrieve Update Delete) operations made by the persistance layer.

A complex custom type is a type that rely on more than one attribute of a DAO object. Here are 2 examples.

Currencies: Handling of currencies is not simple, you have to be able to do arithmetics operations on them, and convert them. Obviously a double type field is not enough, neither a string (when I say string, is a string having only one information, not a string containing an xml description of a currency object with multiple attributes). So in the data modeling you could declare that the currency attribute of the value object will be rely on a set of attributes (amount, currency symbol, reference value in $, date of reference convertion) of a DAL object.

Enumeration: Some enumerations fields may have these requirement. First: the user can add new values. Secondly: some values used by the business layers may not be removed. A typical example is the status of a purchase order. The aim is to present some choices to the end-users (all values already entered by other users for a status plus some predefined fixed values). For technical reasons you may store a predefined fixed value in an attribute and other values into another field, but you want your applciation not to be aware of this.

As you see these are low level behaviour. That the same for relationship: if an object of type A is linked to an (or a collection of) object B, B should be deleted if its parent (from a relationship perspective) A is deleted or B should be attached to another object of type A? Does it makes sense to have an object of type B without an association to an object of type A? All this behaviour have a business rational but this have to be implemented in this layer.

Regarding this last sentence, it really make sense to gather together as much as possible the configuration of almost all layers inside one location. In a metadata driven environement, this is absolutely not an issue to mix configuration of different layer inside a unique location (a file or a a folder)…more over, I would recommend it.

Where do I put business logic?

To continue here

Other interesting links
Segregation/Distinction between Service Layer and Domain Layer

Jan 20

I’ve come across a bug or strage behaviour of the asp .Net control ImageButton the other day.
If you don’t specify a value for the attribute “ImageUrl”, the server will do an access to your default page. To highlight this I’ve created a small project sample that you can find here.
This project contains a default.aspx page, and 2 pages: one with an ImageButton control with attribute “ImageUrl” set (page1.aspx), the other one without the attribute (page2.aspx).

If you lanch the web application: you will see in the output:

Goes through _Default.Page_Load with IsPostBack:False

Go to the page1.aspx page by clicking on button “Page 1″, you will see in the output:

Goes through _Default.Page_Load with IsPostBack:True
Goes through Page1.Page_Load with IsPostBack:False

Now click on the back button of your explorer, and go to page2.aspx by clicking on button “Page 2″, you will see in the output:

Goes through _Default.Page_Load with IsPostBack:True
Goes through Page2.Page_Load with IsPostBack:False
Goes through _Default.Page_Load with IsPostBack:False

You can notice the access to default page. To avoid useless access to the default page, even if you want to setup the ImageUrl property of the control programatically, set a value in the page.

Jan 17

 I’m exploring creation of Package in Visual Studio 2005 and I was not able to build a dummy project. After different tries, the problem was due to the empty key.snk file. I then tried to create on using the command line:

C:\>sn -k key.sn
Unfortunately I get the following error:

Microsoft (R) .NET Framework Strong Name Utility Version 2.0.50727.42
Copyright (c) Microsoft Corporation. All rights reserved.

Failed to generate a strong name key pair — Access is denied.

Finaly ‘google’ helped me : solution is there. Thanks to Aaron for this useful tip. More over, I confirm that now if I create a new dummy project …visual no more create an empty key.snk file.

Jan 08

Here is really great post on principals to write maintenable code. More over this can be extended to improve supportability of the products.

Most of the developers are doing development only! It does not sound like a problem for you…I thing we are at the exact barrier between real development and hobby work. I’m not that fan of Agil development as it does not work well if not apply correctly and with a minimum of knowledge, experience and willing to do it. Nevertheless, Agil methodology as the real advantage to melt the concerns and responsability of QA, dev, CM over the entire team. From what I’ve seen, usually, development task are only 20 to 40% of to whole process to implement new features (and I don’t take into account the maintenance, support and bug fixe after release). Do not use the fake argument that it depends on the environment (Language, Framework, QA automation rate…etc), it’s just wrong. I prefer by far having a developper that knows less about a language or a framework but concerned by CM, QA, comprehensiveness and maintenability of features/code than a rely strong developer that will force to use the last framework release that he knows and break build process…even if his coding skills are higher. To make it shorter: don’t care about improving efficiency about 10% on 20-40% of the process, but I care if it’s on 60%-80% of the process plus maintenance, evolution…etc.

A sentence from the article that are fiond terribly true: “there is an inflection point where a coder mindlessly spewing out code transforms into a thoughtful software craftsman capable of creating maintainable code. That inflection point happens the day a coder first stops, lifts his/her nose out of the coding window, and says to him/herself “where should this code go?”.
I’ve seen this many times and is named “Seperation of concerns”. That does not mean using Spring is mandatory do code correctly :-), but as soon as a developer start to think this way, he will improve maintenability, componentization, and avoid spagetty development with useless interdepedencies. We see new languages as Ruby, Python that are marketed as “less code to implement the same feature” than with other languges as Java and C#. I agree that simplicity is fondamental and less code also, but this should not lead to weird code that can’t be maintained: if seperation of concerns leads to 3 additional lines of code to do a back-and-forth between 2 layers…that’s good.

Jan 06

This is the first tip of the year :-) To debug newly written code in the global.asax file, the easiest way is to force a save of web.config file. Each time the config.file is saved, the application is stopped and started.

Dec 24

Dans un précédent billet j’ai parlé des vertues du typage et quand sans lui, il fallait avoir un bon nombre de tests pour éviter les regressions. Cette batterie de tests n’est —selon moi— pas suffisante, voires impossible a mettre en place suivant les situations. Dans le cas ou vous écrivez un framework par exemple, vous ne pouvez imposer des tests aux utilisateurs de votre framework afin de compenser tout changement d’API.

Les langages dynamiques sont par définition des languages avec un typage faible…voire inexistant. J’ai lu dans un billet sur RubyCLR, que l’intéret de tout typage tombait de par l’usage de Test Driven Development. C’est tout simplement faux et que c’est l’utilsation de TTD et langugae dynamique donnent cette impression.

Une grande partie des nouvelles technologies suivent le même schéma d’adoption. Dans un premier temps, la nouvelle technologie est adoptée par énormément d’utilisateur et une certaine euphorie accompagne cette adoption. A ce stade, les sociétés commence à se pencher dessus sans l’adopter vraiment ou alors de manière expérimentale. On voir alors tout un tas de détracteurs apparaitres qui par la meme occasion mettent en exèrgue certains défauts (faux mythe) et la technologie est alors quelque peu délaissée. Si elle ne disparait pas, elle va survivre et progressivement etre adoptée par plus en plus de personnes … y compris les sociétés.

La survie de la technologie dépend uniquement de sa vraie valeur intrinsèque. Je pense que les languages dynamiques sont au premier stade: beaucoup d’”early adopters” avec peu de vrai applications/framework l’utilsations ou alors en tant qu’outil. Ou voit alors quelquesfan annoncer l’inutilité du typage. C’est abhérent car le typage n’est pas uniquement un artéfact due à la faible abstaraction des premiers langagues: le typage défini un modèle, et le modèle est au centre de tout a partir du moment ou il faut développer un système/application complexe qui est appeller à évoluer. C’est à ce point fondamental que certaines méthodologies commencent par le modèle avant le développement lui même (MDA).

Je pense donc que pour l’instant les languages dynamiques offrent une rapidité de dévelopment inégalée bien utile aucx development d’outils internes, de test ou de prototypage…mais n’enlève rien au besoin fondamental de typage/contrat des entitées utilisées dans une application ou un système complexe afin qu’il puisse évoluer.

Dec 17

Voici un article très intéressant sur les anti-pattern en SOA.

Dec 12

Si on demande aux aficionados des langages sois-disant nobles comme le C# ou Java, ils diront que oui. Je partage en partie cet avis, mais il est tout a fait possible d’avoir les inconvénients du Javascript en Java ou C# voire AOP. Je ne tiens pas a lancer le vaste débat sur quel langage de programmation est le meilleur, car cela finit toujours par des discussions assez stériles, mais je tiens a parler d’un point en particulier: le typage. 

Il est vrai que le javascript n’est pas typé ce qui ne permet pas une détection des problème compile-time mais run-time…ce qui me pose tout de même un sérieux problème. Ce qui est étonnant, c’est de voir à quel point les nouveaux développements en langages typés tendent a essayer d’aller dans la même voie que le javascript. En effet, avec l’arrivée des AOP comme spring et les développements autour des WebServices avec des invocations dynamiques ou les WebServices qui sont eux même non typés…on arrive aux mêmes problèmes. Au final on obtient du code très fragile et difficiles a faire évolués sans une batterie de tests impressionnante.

Dec 06

Le but de cet exemple est de montrer comment séparer la logique métier de l’interface utilisateur. Pour cela j’utilise un control qui publie un évènement spécifique (logique métier) et utilise un template (interface utilisateur) pour le rendu. Le template implément alors la convertion vers l’évènement du control. Vous pouvez étendre cet exemple avec l’utilisation d’un template différent suivant le thème choisi par l’utilisateur…cela fera peut-être l’objet d’un autre article.

Vous pouvez trouver le code source ici.

Pour implétenter cet example il faut:

  • implémenter le control qui charge le template
  • ajouter l’évènement spécific
  • remonter les évènement a partir du template
  • implémenter le template

Control chargeant un template

L’érreur la plus classique est d’oublié de dériver de INamingContainer qui permet de faire remonter les évènements venant du template.
[csharp]namespace BubbleEvent
{
[System.Web.UI.ToolboxData(”<{0}:TemplateControl runat=server />“)]
public class TemplateControl : System.Web.UI.WebControls.WebControl, System.Web.UI.INamingContainer
{
protected override void CreateChildControls()
{
Controls.Clear();
System.Web.UI.ITemplate template = Page.LoadTemplate(”mytemplate.ascx”);
template.InstantiateIn(this);
}
}
}[/csharp]
Ajout de l’évènement métier

Afin de simplifier, on pourrait utiliser System.Web.UI.WebControls.CommandEventArgs et System.Web.UI.WebControls.CommandEventHandler, mais je voulais montrer un exemple complet.
[csharp]namespace BubbleEvent
{

public class TemplateControl : System.Web.UI.WebControls.WebControl, System.Web.UI.INamingContainer
{

public event TemplateControlTextSelectedEventHandler TextSelected;

public delegate void TemplateControlTextSelectedEventHandler(object source, TemplateControlTextSelectedEventArgs e);

public class TemplateControlTextSelectedEventArgs : System.EventArgs
{
private System.String fText;
public System.String Text { get { return fText; } }
public TemplateControlTextSelectedEventArgs(System.String text)
{
fText = text;
}
}
}
}[/csharp]
Remonter l’évènement avec OnBubbleEvent

A noter: l’appel à base.OnBubbleEvent(sender, args). C’est utile dans le cas ou le control dériverai d’un autre custom control.
[csharp]namespace BubbleEvent
{

public class TemplateControl : System.Web.UI.WebControls.WebControl, System.Web.UI.INamingContainer
{
… protected override bool OnBubbleEvent(System.Object sender, System.EventArgs args)
{
if (base.OnBubbleEvent(sender, args))
return true;
if (args is TemplateControlTextSelectedEventArgs)
{
TemplateControlTextSelectedEventArgs textArgs = args as TemplateControlTextSelectedEventArgs;
if (TextSelected != null)
TextSelected(this, textArgs);
return true;
}
return false;
} …
}
}[/csharp]
Implémenter le template

Afin de montrer clairement la convertion entre un évènement lié à l’interface graphique (le template) et l’évènement métier, j’ai utilisé des évènements basé sur des boutons…ce qui est très différent par rapport a faire remonter du text. Le bouton fButtonHello doit fait remonter la chaine ‘Hello !’, alors que le bouton fButtonHelloAndName va faire remonter la chaine ‘Hello ‘avec le nom tapé dans le TextBox fName. Voici le template.

[asp]
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="mytemplate.ascx.cs" Inherits="mytemplate" %>
Name :


[/asp]

Il reste donc a implémenter la convertion.

[csharp]public partial class mytemplate : System.Web.UI.UserControl
{
void ButtonHelloClicked(object sender, System.EventArgs e)
{
RaiseBubbleEvent(this, new BubbleEvent.TemplateControl.TemplateControlTextSelectedEventArgs(”hello !”));
}
void ButtonHelloAndNameClicked(object sender, System.EventArgs e)
{
RaiseBubbleEvent(this, new BubbleEvent.TemplateControl.TemplateControlTextSelectedEventArgs(”hello ” + fName.Text + ” !”));
}
protected void Page_Load(object sender, System.EventArgs e)
{
fButtonHello.Click += new System.EventHandler(ButtonHelloClicked);
fButtonHelloAndName.Click += new System.EventHandler(ButtonHelloAndNameClicked);
}
}[/csharp]

Voila, l’essentiel est fait, il ne reste plus qu’a utiliser ce control dans une page.
[asp]
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<%@ Register TagPrefix="custom" Namespace="BubbleEvent" %>




Result:



[/asp]
Et le code associé:
[csharp]public partial class _Default : System.Web.UI.Page
{
private void TextSelected(object sender, BubbleEvent.TemplateControl.TemplateControlTextSelectedEventArgs args)
{
fResult.Text = args.Text;
}

protected void Page_Load(object sender, System.EventArgs e)
{
fTemplate.TextSelected += new BubbleEvent.TemplateControl.TemplateControlTextSelectedEventHandler(TextSelected);
}
}
[/csharp]

Conclusion

On peut donc séparer la logique métier de l’interface utilisateur en utilsant un template pout l’interface et une classe métier implémentant des évènements métier. Cette technique est très bien adaptée pour faire une intégration AJAX: le template ait les appels AJAX qui relèbent de l’interface et ne remonent que les évènements métier pertinents.