Archive

Posts Tagged ‘DDD’

Random thoughts

May 18th, 2010 stiiifff 3 comments

I’ve been fairly busy lately, working on interesting things at work, getting ready for an imminent birth, preparing some sessions as well … and also, thinking about a dozen of blog posts I wouldn’t have time to write. So anyway, here’s a quick & dirty cheap list of ramblings, not sure if it’s gonna be of any use, but it’ll hopefully free up some memory slots in my brain :-)

  • Complex Data Model != Domain Model : don’t get the “Let’s do DDD because it’s trendy. And, woohoo, that CQRS thingie would look nice on my CV as well” tendency too quickly. Knowing when not to apply DDD is almost as important as knowing how to apply it properly.
  • WCF RIA Services : I played a bit with it at work … and I like it. It was designed to address 80% (more ?) of the needs of developers writing n-tiers Data-Driven applications (also known, in the .Net world, as ‘Business applications’), and it does … just that. And that’s good. Sure, it can be misused and it’s bad because it doesn’t use Pattern ‘Blah’ and it violates Rule ‘MoreBlah’, but you’re smart right, so you’ll know when to use it, and when not to. I’m just a bit annoyed that the attributes, I mean, data annotations, are scattered in 25 different namespaces. “Bah, just press ‘Alt-Enter’ dude, API design is so overrated these days”.
  • Agatha : Using it, works well, like it. I’m a fan, it’s WCF for mere mortals. Keep up the good work Davy.
  • RavenDB : This will deserve a post of its own to describe just how cool I think this NoSQL-for-.Net-written-by-guess-who is. Not only it makes domain-modeling and application prototyping dirt cheap (no more mapping & OR impedance mismatch bro !), it will also give a run for their money to the existing NoSQL databases out there (I mean, how can you compete with 25 blog posts & 12 releases per week ;) lol). Oh, and if you’re into it, DDD will be most welcome as well (“But Ma, there’s no lazy-loading ! How can I do DDD without lazy-loading & bi-directional navigation properties ?” … “Kiddo, lazy-loading sucks. Big time”).
  • Frameworkitis : It’s a nasty disease, I had it in the past, went through a long detox and now (I think) I’m clean. Unfortunately, I still have a lot of peers that are addicts. Wish they could see the light.
  • “KISS-Mantra” : Repeat 5 times per day “I’m a complexaholic, I will not generify, I will simplicate”. Anybody has a nice wallpaper with a giant yellow Bath duck ? :-)

Ah, I feel lighter now.

Categories: DDD, DotNetHub, ORM, WCF Tags: , ,

Value Object in .Net 4.0 – Take Two

April 5th, 2010 stiiifff 5 comments

I’ve refined a bit my base class for Value Objects in .Net 4.0. Instead of using Tuples, I’ve used anonymous types which have had structural equality since .Net/C# 3.0 (I didn’t know that :-) ).

I’ve also renamed methods to make the intent more clear. Here is what it now looks like (fancy stuff removed for simplicity) :

public abstract class ValueObject<T> : IEquatable<T>
    where T : ValueObject<T>
{
    public delegate object ValueObjectStructuralViewBuilder<TValueObject>(TValueObject valueObject) where TValueObject : T;

    private static readonly IDictionary<Type, ValueObjectStructuralViewBuilder<T>> structuralViewBuilders = new ConcurrentDictionary<Type, ValueObjectStructuralViewBuilder<T>>();

    private static object BuildStructuralView(T valueObject)
    {
        Debug.Assert(valueObject != null);
        Debug.Assert(structuralViewBuilders.ContainsKey(valueObject.GetType()));
        return structuralViewBuilders[valueObject.GetType()](valueObject);
    }

    protected static void DefineStructuralView<TOrDerived>(ValueObjectStructuralViewBuilder<TOrDerived> structuralViewBuilder)
        where TOrDerived : T
    {
        if (structuralViewBuilder == null) throw new ArgumentNullException("structuralViewBuilder");
        var valueObjectType = typeof(TOrDerived);
        structuralViewBuilders[valueObjectType] = va => structuralViewBuilder(va as TOrDerived);
    }

    protected ValueObject()
    {
        var valueObjectType = GetType();
        if (!structuralViewBuilders.ContainsKey(valueObjectType)) throw new InvalidOperationException(string.Format(
            "StructuralViewBuilder not defined for type '{0}'.", valueObjectType.FullName));
    }

    // Method overloads omitted for brevity purpose ...

Creating a Value Object type now reads like this :

public class Leg : ValueObject<Leg>
{
    static Leg()
    {
        DefineStructuralView<Leg>(l => new { l.Location });
    }  

    public Leg(string location)
    {
         Contract.Requires(location != null);
         Location = location;
    }  

    public string Location { get; private set; }
}

Inheritance of Value Object types is now supported, and the added overhead of the base class is a ConcurrentDictionary per Value Object type hierarchy (remember that static members in generic types defines 1 instance per closed generic type).

As always, feedback (good or bad) is more than welcome !

Categories: DDD Tags: ,

Value Object with .Net 4.0

March 22nd, 2010 stiiifff No comments

There’s already been a lot of implementation of generic Value Object base class … but I’ve never been really satisfied with what I’ve seen so far. Most of them uses reflection, or assume that all public properties should be used, or add significant overhead to every instance of the value object type, or just contain too much obscure code for something that should not be so complicated.

So I figured out that I would give it a try :-) Here is my attempt at building a simple to understand, efficient and correct implementation of the generic Value Object base class in C# 4.0:

public delegate IStructuralEquatable StructuralObjectBuilder(T source);

public abstract class ValueObject : IEquatable, IStructuralEquatable
    where TValueObject : ValueObject
{
    private static StructuralObjectBuilder _structuralIdentityBuilder;

    protected static void DefineStructuralIdentity(StructuralObjectBuilder structuralIdentityBuilder)
    {
        Contract.Requires(structuralIdentityBuilder != null);
        _structuralIdentityBuilder = structuralIdentityBuilder;
    }

    protected ValueObject()
    {
        Contract.Requires(_structuralIdentityBuilder != null, string.Format(
            "StructuralIdentityBuilder for type '{0}' was not set in static constructor.",
            GetType().FullName));
    }

    private IStructuralEquatable BuildStructuralIdentity(TValueObject valueObject)
    {
        Contract.Requires(valueObject != null);
        var structuralIdentity = _structuralIdentityBuilder(valueObject);
        Debug.Assert(structuralIdentity != null);
        return structuralIdentity;
    }

    public bool Equals(TValueObject other)
    {
        if (ReferenceEquals(null, other)) return false;
        if (ReferenceEquals(this, other)) return true;
        return BuildStructuralIdentity(this as TValueObject)
            .Equals(BuildStructuralIdentity(other));
    }

    public override bool Equals(object obj)
    {
        return Equals(obj as TValueObject);
    }

    public override int GetHashCode()
    {
        return BuildStructuralIdentity(this as TValueObject).GetHashCode();
    }

    public override string ToString()
    {
        return BuildStructuralIdentity(this as TValueObject).ToString();
    }

    public static bool operator ==(ValueObject left, TValueObject right)
    {
        if (ReferenceEquals(null, left)) return ReferenceEquals(null, right);
        return left.Equals(right);
    }

    public static bool operator !=(ValueObject left, TValueObject right)
    {
        return !(left == right);
    }

    public bool Equals(object other, IEqualityComparer comparer)
    {
        return BuildStructuralIdentity(this as TValueObject).Equals(other, comparer);
    }

    public int GetHashCode(IEqualityComparer comparer)
    {
        return BuildStructuralIdentity(this as TValueObject).GetHashCode(comparer);
    }
}

I’m leveraging the new IStructuralEquatable of .Net 4.0 that gives us the semantic of structural equality when comparing 2 objects. One of the types that implements this interface by default is the new Tuple generic type, so I’m borrowing it’s equality, GetHashCode & ToString implementations :-)

Eventually, to create a Value Object type, you just have to define its structural identity builder in the static constructor:

public class Leg : ValueObject
{
    static Leg()
    {
        DefineStructuralIdentity(l => new Tuple(l.Location));
    }

    public Leg(string location)
    {
        Contract.Requires(location != null);
        Location = location;
    }

    public string Location { get; private set; }
}

Obviously, if you want to have a somewhat “immutable” value object, you shouldn’t define any publicly accessible setter for your public properties.

Remark: I haven’t implemented support for inheritance of value objects yet. I’ve tried, came up with different solutions but didn’t find any that was satisfactory so … stay tuned. Or, send a patch if you found a good one ;-)

This is a first drop … please send me your comments & suggestions on how to improve it.

Categories: DDD Tags: ,

DDD Immersion Course review

March 8th, 2010 stiiifff No comments

I recently had the chance to follow a 4-day Domain-Driven Design Hands-on immersion course in Paris, with Eric Evans.

It was very inspirational, probably the most interesting course I’ve followed to date. The amount of knowledge contained in the DDD book can be daunting to master, and the course succeeds in clarifying the most complex aspects of DDD as well as delivering the latest evolutions of the approach.

If you are interested in this course, Paul Rayner has written an amazing series of posts about it:

  • Part One – Introduction. What is DDD? Ubiquituous language? a Model?
  • Part Two – Building-Block patterns (eg. Aggregate. Domain Event. Creative Collaboration etc)
  • Part Three – Strategic design – Bounded Context and context mapping.
  • Part Four – Strategic design (continued) – Core Domain
  • Part Five – More on supple design (Specification pattern). Implementation concerns. Discussion.
  • Part Six – Design and agile.
  • Part Seven – Final. Course takeaways and other thoughts.

Happy modeling !

Categories: DDD Tags:

Looking back at 2009, and forward to 2010

December 24th, 2009 stiiifff 4 comments

There will probably be thousands of posts like this one but anyway, here I go with my own … I wanna take a little time looking back at 2009 and then set my personal expectations for 2010.

Overall, 2009 was a great year :-)

  • I finally created my own company ! This gives me a certain degree of freedom in choosing the types of project I want to work on, the knowledge I want to acquire and even more opportunities to meet a lot of very talented people.
  • I learned a lot … especially on how to have a more business-centered focus on software development. Thinking about business value, weighting different solutions benefits vs costs, and also, listening & talking more to the business guys.
  • I read a lot, although I still haven’t finished all the books I started. Functional & concurrent programming, domain-specific languages, Scrum, Business/IT Alignment are in my continuous learning bag.
  • I followed a great course with Udi Dahan and it helped me gain some new perspectives on how to rethink about software design in general. Messaging, SOA & DDD are fascinating topics I want to further learn from.
  • Articles & presentations of Eric Evans on DDD and Udi on CQRS had a tremendous impact on my view of software building. We, software developers tend to focus too much on creating cool frameworks or libraries, and solving complex technical problems, while forgetting about our main goal : providing business value. Sometimes, solving a problem from a business point of view is far easier than at a technical level. Also, we tend to be maniac about every line of code we write … but as E. Evans is saying “Precision design are fragile” & “Not all of a system will be well designed“. Focus your efforts on writing good code in parts of the system that provide most of the business value. It is perfectly fine to write not so good code elsewhere (the duck-tape programmer has its role to play!), just make sure you make everything explicit.
  • Finally, with some friends, I created a new community about the .Net platform & the Agile methodologies, DotNetHub. It’s a very exciting project :-)

So, 2009 was so amazing that I’m eagerly awaiting 2010 !

  • I already booked a DDD immersion workshop with E. Evans in Paris, mid-February, and I’m sure it’s gonna be a great course. Maybe others will follow as I find myself learning a lot during those intensive courses.
  • DotNetHub will keep me busy, organizing great conferences with, well-known and well-known-to-be speakers.
  • I absolutely have to finish all the books I started before I buy any new one !
  • I will restart working on my app based on Northwind and demonstrating DDD coupled with NServiceBus. I have to admit, I got a bit side-tracked by DotNetHub and another major personal event (read further lol).
  • Probably learn some new technical stuff like C# 4.0, VS2010/TFS2010, Dublin & some more F# but honestly, that’s less important and most probably easier than the previous stuff (although F# is quite funky). Using your brain and training your critical sense to filter marketing / wrong piece of information / silver bullets is actually the hardest part of our job.

So, that’s about it folks ! This is the list of my expectations for 2010 … but that’s actually all secondary compared to the main challenge I will have to face : becoming a father end of May 2010 ! ;-) Indeed, my wife is pregnant of my first child. I’m really excited about it … now, on top of my to-do list : read the baby books or get killed :-) lol

Merry Christmas & Happy New Year to all !

Getting a better view from the roof of the Bus

November 3rd, 2009 stiiifff No comments

Last time, I had a first spike with NServiceBus in combination with Castle Windsor, NHibernate & FluentNHibernate, and highlighted the fact that it was quite easy to get those guys up and running together in a clean way, and from there, to process your first messages.

This time, I would like to take a step back, off the Bus, to lay down the foundations of a more concrete & complete example. To do so, I will use the well-known used & abused database sample from Microsoft : Northwind !

I can already hear you all “Northwind, WTF ?!” … except that this time, it’s gonna be different, trust me !

Let’s start by having a look at our veteran database diagram …

NorthwindDiagram

As we can see, Northwind is a traditional sales company, with an online business, which is:

  • Receiving Orders from Customers, classified in different Demographic segments, and shipping those orders via third-party Shippers.
  • Provisioning adequate Stock quantities of Products, arranged in Categories, by buying from several Suppliers, to deliver ordered quantities.
  • Managing Salesmen organized in Territories & Regions.

(yeah, I can get all that from a simple database diagram … impressive imagination huh ? ;-) )

In an SOA world, we wil tend to breakdown the different facets of the company into several independent but cooperating Services.

A naive but all too common way to split our problem domain would probably be as follows:

  • Employee service: manage employees, territories & regions.
  • Customer service: manage customer & demographic segments.
  • Order service: manages customer orders & shippers.
  • Supplier service: manages suppliers & stock.
  • Product service: manages products & categories.

Unfortunately, this simplistic way of defining service boundaries around groups of related concepts most often leads to services that are not autonomous (e.g. call each others, use same database), which violates one of the 4 tenets of SOA (“Services are autonomous“). Plus the fact that it just smells too much like a CRUD API.

A better starting point for modeling services is to analyze the Business Capabilities of the company, that is to say, the distinctive aspects of the company that are contributing to achieve its main goals. Another possibility can also be to model your Services around Bounded Contexts that you would have previously identified, if you are a DDD practitioner. I’m still not yet entirely sure which solution you should prefer and in which conditions … good topic for another discussion.

But in any case, your Services will be better aligned with the Business rather than just being technical CRUD-services.

Here is an attempt at defining the Business Capabilities (BC) and their respective goals in our beloved fictive Northwind company:

  • Marketing BC: maintains a catalog of products, define pricing & promotional operations to maximize sales.
  • Sales BC: accepts customer orders and improves customer relationship.
  • Inventory BC: optimizes the provisioning of product stocks via suppliers to support sales.
  • Shipping BC: optimizes delivery times & costs through shippers.
  • HR BC: manages salesmen to cover sales territories & markets.

They might change as the company’s goals evolve, some being dropped, new ones being added but let’s focus on these ones for now. One service will be defined for each business capability.

Each of those services will eventually use it’s own independent datastore to persist information and will expose its features by accepting incoming Messages and triggering outgoing Events on the Messaging infrastructure.

Those services will be composed to form one or more application(s) that will deliver great value to the company and increase its sales by multiple orders of magnitude !!!

To break with the past, I’ve decided to name this sample Southwind! It sounds warmer and way cooler than Northwind, doesn’t it? :-)  Indeed, it will feature a first personal attempt at building a sample bringing together an Event-Driven Architecture with domain models built following the Domain-Driven Design approach, on top of NServiceBus. Might be a bit ambitious, but it’s so interesting right ?

That’s it for now, till next time where I will focus on the messages & events being exchanged by the different services.

Meanwhile, go read this great article about Event Driven SOA with NServiceBus.

As always, remarks, comments, suggestions are welcome. And if you wanna help building this great sample, you’re more than welcome! ;-)

Stepping onto the Bus

October 12th, 2009 stiiifff No comments

I recently had the chance to follow the Advanced Distributed Systems Design with SOA course with Udi Dahan in Brussels, a rejuvenating experience for various reasons : I had no real-world SOA or Messaging Bus experience, it helped me clear out some misunderstandings I had about DDD and also, although painful at first, Udi finger pointed all the bad habits & misconceptions I had accumulated over the years (I can still hear him squeaking “Northwind ! Northwind !“).

So here I am, entering the realm of SOA, EDA & DDD that might well be heaven on earth for both business people & software-makers, the place we all heard of but never saw. But let’s start slowly, and discover my first endeavor with NServiceBus, shall we? :)

For a good introduction on NServiceBus, I suggest you to read the post from Jan who has been doing research on the same aforementioned topics as well.

This post will focus on how well NServiceBus, NHibernate, FluentNHibernate & Castle Framework play together and how to make them fly in a DDD context. Ok, ok, enough talking, show me the code man !!! :D

To manage my NHibernate sessions (ISession), I like to use the Castle’s NHibernate Integration facility, as it gives me a nice abstraction in the form of the ISessionManager component:

ISessionManager

Next to that, a little more than a month ago, the 1.0 version of FluentNHibernate was released, and it’s really neat for both NHibernate configuration & mappings. So, I like to use it as well:

Fluently.Configure(config)
  .Database(MsSqlConfiguration.MsSql2008
    .DefaultSchema("dbo")
    .ConnectionString(c => c
      .FromConnectionStringWithKey("Northwind"))
    .QuerySubstitutions("true 1, false 0")
    .DoNot.UseOuterJoin()
    .ShowSql())
  .Mappings(m => m
    .FluentMappings.AddFromAssemblyOf<CatalogMap>()
    .ExportTo(System.Environment.CurrentDirectory))
  .BuildConfiguration();

One very nice thing about NServiceBus (and its Generic Host) is that it acknowledges from the start that our softwares have to operate in different environments and for that, it offers a very clean solution : Profiles.

Wrapping it all up, wouldn’t it be nice if I could use Castle‘s NHibernate Integration facility for useful components like ISessionManager (and others, more on that later), FluentNHibernate for configuration & mappings and take advantage of NServiceBus Profiles ? Hell yeah !!! Well, that’s actually quite easy & clean. :)

First, configure the NH facility in your config file:

<castle>
  <facilities>
    <facility id="nhibernate.facility" type="Castle.Facilities.NHibernateIntegration.NHibernateFacility, Castle.Facilities.NHibernateIntegration">
      <factory id="nhibernate.factory"/>
    </facility>
  </facilities>
</castle>

Notice that the configuration for the factory is empty … indeed, we want to configure it fluently in the code.

Create a Profile Handler class (implements a IHandleProfile role interface) which simply registers an object into the container (NSB is container-agnostic) :

public class IntegrationProfileHandler : IHandleProfile<Integration>
{
  public void ProfileActivated()
  {
    Configure.Instance.Configurer
      .RegisterSingleton<IConfigurationContributor>(
        new IntegrationNHibernateConfig());
  }
}

… and finally, an implementation of the IConfigurationContributor interface … which is part of Castle‘s NHibernate Integration facility, and will be called before NH‘s SessionFactory is built in order to, well, contribute to the configuration. :)

public class IntegrationNHibernateConfig : IConfigurationContributor
{
  public void Process(string name, Configuration config)
  {
    Fluently.Configure(config)
      .Database(MsSqlConfiguration.MsSql2008
        .DefaultSchema("dbo")
        .ConnectionString(c => c
          .FromConnectionStringWithKey("Northwind"))
        .QuerySubstitutions("true 1, false 0")
        .DoNot.UseOuterJoin()
        .ShowSql())
      .Mappings(m => m
        .FluentMappings.AddFromAssemblyOf<CatalogMap>()
        .ExportTo(System.Environment.CurrentDirectory))
      .BuildConfiguration();
  }
}

Ok, very nice … but I’m not done yet.

A nice concept that we want to use when querying in a true DDD fashion is the notion of Fetching Strategy (read more about it here & there). We need Fetching Strategies for a very simple reason:

Make sure that once we call into the Domain Model to perform a certain action, it has everything it needs to do its job, without causing lazy-loading to trigger and possibly N+1 select problems.

For that matter, I define a simple interface IFetchingStrategy (IEntityRole is just a marker interface):

public interface IFetchingStrategy<TEntityRole>
    where TEntityRole : IEntityRole
{
  string[] FetchList { get; }
}

… that I can then implement to define a fetching strategy per entity role:

public interface IRegisterProductInCatalog : IEntityRole
{
  void RegisterProduct(string category,
         string productName, string productDescription);
}

public class RegisterProductInCatalogStrategy : IFetchingStrategy<IRegisterProductInCatalog>
{
  public string[] FetchList
  {
    get { return new[] { "Categories.Products" }; }
  }
}

Now, it would be nice if I could get an easy access to those fetching strategies … well, that’s what you use an IoC container for ;) Here is the configuration of Castle’s Windsor container in NServiceBus endpoint’s configuration class:

public class EndpointConfig : IConfigureThisEndpoint, AsA_Server, IWantCustomInitialization
{
  public void Init()
  {
    var container = new WindsorContainer(new XmlInterpreter());

    Configure.With()
      .CastleWindsorBuilder(container)
      .XmlSerializer();

    container.Register(
      AllTypes
        .Of(typeof(IFetchingStrategy<>))
        .Pick(Configure.TypesToScan)
        .WithService.FirstInterface()
    );
  }
}

Fluent configuration for the Bus & the Container ! Woohoo, my head is turning ! :D

Now, for the final part, the MessageHandler that makes use of all those cuties & with the help some little extension methods:

public class ProductManager : IHandleMessages<RegisterProductInCatalogRequest>
{
  public virtual IBus Bus { get; set; }
  public virtual ISessionManager SessionManager { get; set; }
  public virtual IFetchingStrategy<IRegisterProductInCatalog> Strategy { get; set; }

  public virtual void Handle(RegisterProductInCatalogRequest message)
  {
    using (var session = SessionManager.OpenSession())
    {
      var catalog =
            session.For<Catalog>(message.CatalogId)
                   .Apply(Strategy)
                   .UniqueResult<IRegisterProductInCatalog>();

      catalog.RegisterProduct(message.CategoryName,
                              message.ProductName,
                              message.ProductDescription);
    }
  }
}

I don’t know you, but that’s the kind of code that makes me happy (like a hippo). :)

Comments, feedback, suggestions are all welcome ! ;)

Coarse-grained Lock & ORM : Followup

May 31st, 2009 stiiifff No comments

Ayende has a followup post concerning support for Coarse-grained locks in NHibernate.

All I want to be able to do is to define my coarse-grained locks (=> optimistic-lock on aggregate root) in NHibernate’s mapping files … and then forget about it when I know that NHibernate can handle it for me. :)

I will then be confident that changes performed within an aggregate are done in a consistent manner and that concurrency problems are detected without using expensive database locks but using optimistic locking on just 1 table for the whole aggregate.

Categories: DDD, ORM, Patterns Tags: , ,

Entity Framework => Entity Base Class Library

November 23rd, 2008 stiiifff 5 comments

A few days ago the Entity Framework Team released a proposed solution for N-Tiers change tracking on entities … or should I call it a no-solution?

Basically, they will provide a low-level API that will allow YOU to do change-tracking the way YOU prefer.

5 months ago, I was writing a big NO to the Vote of no confidence. Well, now that I had to use Entity Framework on a real project, I must say that I was wrong. I really tried my best using it, thinking that it would be a safe bet for future evolution … and I know what I'm talking about when using ORMs, I'm a very advanced user of NHibernate (multi-tenancy, dynamic filters, dynamic mappings, partial domain models anyone?) … but my only conclusion to the Entity Framework is : WTF are they doing ?! Is that all you could come up with after months of research, brainstormings, experts meetings ?!

If someone give me a set of classes that doesn't bring a A to Z solution to a problem, sorry but I don't call it a Framework … I call it a Base Class Library. I've been vey supportive to the Entity Framework Team (I gave design feedback through multiple channels) but now I think I'm done. And it seems that others have the same feeling : Frans Bouma, author of the LLBGenPro ORM tool, goes in that direction too with its answer to the original post, and a full post on his blog, wich I both totally agree with.

I mean, come on, all those abstractions and discussions are very interesting but after some extensive periods of time trying to make this thing become useable, you have to ask yourself some serious questions. Even the now defunct Linq2Sql is more pleasant & easier to use.

Anyway, I will now go back using something that is customizable, extensible, that allow me to work the way I want (Domain-Driven Design) and most importantly that actually works : NHibernate. I recently discovered that it's moving full speed to version 2.1 with great new features such as Entity Modes : see here and there to know what I'm talking about. Also, a great workshop video on advanced use cases of NHibernate by Ayende.

Update: Ayende's reaction to the Entity Framework Team's design post.

Distributed Domain-Driven Design

July 15th, 2008 stiiifff No comments

Yves Goeleven, a fellow Belgian .Net architect, has a series of very interesting posts on Distributed Domain-Driven Design (DDDD).

If you're researching about how to design your applications with DDD in mind while still being highly scalable, this paper from Pat Helland (Amazon) is a great source of inspiration (thanks Yves for the link). But don't expect to grasp the full potential of it if you don't have a good understanding of both DDD & Distributed Systems (Entities, Transactions, Workflows, Messaging & Scalability in a SOA world).