The Artima Developer Community
Sponsored Link

.NET Buzz Forum
I'll see you when you get there

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Udi Dahan

Posts: 882
Nickname: udidahan
Registered: Nov, 2003

Udi Dahan is The Software Simplist
I'll see you when you get there Posted: Jan 16, 2004 6:12 PM
Reply to this message Reply

This post originated from an RSS feed registered with .NET Buzz by Udi Dahan.
Original Post: I'll see you when you get there
Feed Title: Udi Dahan - The Software Simplist
Feed URL: http://feeds.feedburner.com/UdiDahan-TheSoftwareSimplist
Feed Description: I am a software simplist. I make this beast of architecting, analysing, designing, developing, testing, managing, deploying software systems simple. This blog is about how I do it.
Latest .NET Buzz Posts
Latest .NET Buzz Posts by Udi Dahan
Latest Posts From Udi Dahan - The Software Simplist

Advertisement

How to do SOA ?

That's a question that's been popping up a lot lately. I've been answering small facets of the question in comments all over the place, but I think that it's time to handle the big one.

First of all, I assume that the architecture that you're currently using is a layered architecture ( N-tier counts despite the "tier" misnomer, N=3 is also OK ). What I'm going to do is to do a step-by-step migration from a layered architecture (LA) to an SOA.

First some history. In your basic 3 tier LA, the layers are PL, BL, and DL. PL = presentation layer, BL = business layer, DL = data layer. Over time, people realized that layers were a nice abstraction and started changing the above layers to a system with more layers. For instance, tables in the database were the storage layer (SL), data access code to interact with the storage was often split into 2 layers - database Dal ( data access layer ) consisting primarily of stored procedure, and the app Dal which was code that exposed those sp's to the system in its own framework. ( Note that in many cases it is possible and even desirable to do away with the stored procedures and have the same sql code in the app Dal. ) The BL primarily was implemented by Fowler's Domain Model Pattern - rich objects holding both the data, behaviour, and "structure" of the system ( think Customer.Orders ). The PL use of the BL was by way of its objects. In other words, the PL was intimately aware of ( and dependant on ) the BL's inner workings.

So ... What's the problem ? Well there are quite a few, and I'll eventually make some exhaustive list of what the problems are, and why you should move to SOAs. For one, the BL may be a good API for working with it in process, but if you start to use them for remote invocation your performance will die. Why ? Because the BL is chatty, meaning everything is done in small bites - give me this, now give me that - when what is needed for remote clients ( or other systems ) is a chunky API - give me everything I need at once. Well, this problem can be fixed by putting in another layer, but I won't get into that ( unless you ask nicely =) ).

So, assuming that you know how to build a LA, how do you go about migrating to an SOA ? Here's how.

First you have to change your layers so that they behave like services. Then, if you want, you can wrap them up using webservices or some other plumbing choice. You'll need to have a standard way for passing data to your services ( SOA's schema ). How do you do that ?

Well, there's implicit knowledge scattered all around the system. Its the domain itself. The PL presents it. The BL performs logic on it. The DL stores it. Its data. It doesn't have behaviour. These are the "entities" of the system. What are the entities you ask ? They are the objects in your BL without the behaviour. Customer, Order, Product, etc, all these are entities that ALL parts of the system deal with. This is the stuff the will be passed between the services. If you wanted to integrate with other systems, you could easily serialize the entities to xml.

So, step 1 is to create a new layer, called Entities ( or something else if you prefer ) and copy all the classes of your BL that are part of the domain model to it. Next, remove all methods from those classes. There is some disagreement on whether or not the relationships should be left in or handled by a different service. ( I've tried using a separate service for handling relationships between entities with quite a lot of success, but can't generalize it enough to push for it as a part of the SOA proper. )

So, from now on, whenever you have to pass data between layers, use the corresponding entity.

So, you now know how to get data to your service, but its still a layer. So lets change the layer to a service. A service has a single point of entry, allowing only method calls. So ...

For each layer, make only one visible class, something like ($WhatYourServiceDoes)Service - like PersistenceService or AuthenticationService. I can see your getting mixed up.

When working in .Net, I have a project called PersistenceService, in it I have a class called PersistenceService. When somebody needs persistence services, they add a reference to the PersistenceService project, at the top of their client code file they write "using PersistenceService;" and then, in the code itself, when they write "PersistenceService.Update(u);" they are actually accessing the PersistenceService.PersistenceService class - it just makes it more readable like this.

All other classes inside a service are internal, nobody should be able to get at them. The public class has only public static methods - like "public static void Update(Entities.User u)" mentioned above ( you might want to return bool in your specific case, or maybe int ).

Now, the public class handles all security, logging, exception management, and other infrastructure code for each call, finally passing the call on to an internal class which holds the logic for actually doing the work.This class has almost the same structure as the public class and is the one in charge of actually getting the work done. There's no problem in instantiating other objects there to do the work.

In SOA, not everything is a service. /* cheap shot at the OO crowd */

>aside< This is getting rather long ... >/aside<

Its time for some examples ( I'll only be showing the SOA way ):

1. Login ( From your PL call this instead of what you did before )

Entities.User u = new Entities.User();
u.Username = txtUsername.Text;
u.Password = txtPassword.Text;

if (AuthenticationService.CanLogin(u))
// let the user continue
else
// show some error message (ask them to try again ?)

The AuthenticationService has a CanLogin method which takes the user's credentials from the entity, authenticates them somehow, and returns the result.

Why is this preferable to having a BL.User.Login() method ? Well, is it really the user's responsibility ( in the "real" world ) to authenticate themselves ? No. If you'd like to change the mechanism for authenticating users ( say moving to ADAM instead of a DB ), is there any reason to touch the User object ? No. There are more reasons, but let's not get into that.

What is needed is a separation of concerns. How you do something and where you do it (even at the interface level), should be separate from what you do it on.

So, to sum up, make layers into a services. And when you pass/get data to/from a service use entities. Next time, I'll go about implementing an entire service, something you doubtless have as a layer in ( at least one ) system, so that all this theory makes more sense.

BTW, if you have anything you'd like me to include in the next post specifically, let me know.

Read: I'll see you when you get there

Topic: Web Design References Previous Topic   Next Topic Topic: Database Cache Invalidation in ASP.NET

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use