IBuilder and IFactory

0 views
Skip to first unread message

Bil Simser

unread,
May 8, 2008, 7:03:53 AM5/8/08
to xeva
Rik added these to trunk and the comment was to see the groups for a
description? What are these interfaces for and are there going to be
implementations in the framework at some point?

David Laribee

unread,
May 8, 2008, 8:18:09 AM5/8/08
to xe...@googlegroups.com
IBuilder is an interface for the builder pattern. We use this when building up entities, e.g.

CustomerBuilder b = new CustomerBuilder("one", "two", "three");
Customer c = new Customer(b);

IFactory is meant to represent a DDD Factory pattern for more complex entities with invariants scattered across aggregate roots, etc. So:

Customer c = new CustomerFactory(b); // where b is a builder

My plan is to create a static class called New where we can register factories and create fluent builders, e.g.

New.RegisterFactory(new CustomerFactory());

Customer c = New.Customer
                            .Named("Bob's Auto Supply")
                            .WithCreditLimit(1000)
                            .ChildOf(someCustomer)
                            .Status(CustomerStatus.Active);

When the implicit cast happens we'll run the builder through a factory (if present) for more complex logic. Imagine for example, that we need to create an "Account" in an AR module/context to correspond with the customer above.

It should be possible to use messages (ala Greg Young's post on Fluent Builders and Messages as Value Objects) to feed directly in to handle mapping scenarios though I personally feel that mapping should be done at a facade-boundary so as to avoid leaky abstractions in or out of a particular domain model.

This stuff is early and we're playing with it in our own applications before we get too ambitious with putting it out there for public consumption. That said, now would be a great time to tell us what you'd like in terms of Factory/Builder support in our Model framework. One thing I'd like to toy around with someday is having a Store implementation (XF.Model.Store) not for NHibernate but for a cache with a messaging pipeline. I mean to discuss this with Greg in Toronto; there are a lot of issues such as thread safety and shared cache that make this harder than I'd like. And this idea is very much just an inclination at this point. I'd love to be able to have certain contexts just function as in-memory messaging repeaters with tweakable cache lifetimes for performance.

Rik, can you add any more insight here?
--


/ Dave

http://thebeelog.com

Bil Simser

unread,
May 8, 2008, 9:04:22 AM5/8/08
to xeva
Thanks Dave for the explanation. All sounds good and what I expected
(although registering a factory with the New class then invoking it
via it's builder is slick).

In keeping with the DDD approach (which I'm all for) should maybe we
have an IAggreateRoot as a constraint on some generics (maybe in the
store as you would probably only want to persist root nodes and let
the store take care of it's children). There's already an IEntity and
IRepository so if we get more DDD lingo/patterns in there might make
sense?
> *
> Rik, can you add any more insight here?*

David Laribee

unread,
May 8, 2008, 9:20:52 AM5/8/08
to xe...@googlegroups.com
I agree re: ARs. Going to talk to Greg about how to best implement. I have some ideas, but would like to get some feedback.

I'm also toying around with creating a UniqueIdentifier object that can be used at an AR level to obtain a lock which will be important in non-NHibernate scenarios, e.g.

MyRoot root = MyRoots.FindBy(someGuid);

lock(root.UniqueIdentifier)
{
   root.DoSomethingNice();
}

Of course Guids are value objects and can't be used to lock, so... There's probably a way to use implicit casting magic (but then we roll into boxing/unboxing issues) to obtain a lock. At any rate for NH we'd also want this persisted as a Guid anyway.

Bil Simser

unread,
May 9, 2008, 1:23:07 PM5/9/08
to xeva
You're going to add the New classes from the fluent fixture code out
there by Aaron? Just wondering how the IBuilder interface (which is
empty at the moment) would fit into this.

For example I want to build an about box which would be in the
framework and common, consumers would just set the title and image
(with other information coming from the calling assembly through
reflection). Jeff Atwood put together an about box similar to this so
I was looking at how to fold it in here using the presenter/view/
callbacks.

I can do it with some ugly code like this:

// AboutBoxAdapter is an empty dialog with no min/max button, etc.
IWindowAdapter adapter = new AboutBoxAdapter();
adapter.ChangeCaption("About Bank Teller");
adapter.Modal = true;
adapter.Height = 400;
adapter.Width = 550;

// AboutBoxView is a user control implementing IAboutBoxView :
IView<IAboutBoxViewCallbacks>
AboutBoxPresenter presenter = new AboutBoxPresenter(new
AboutBoxView());
presenter.DisplayIn(adapter);
presenter.Start();

However if we have the fluent builder class this might work better:
New.AboutBoxPresenter
.WithCaption("About Bank Teller")
.WithHeight(400)
.WithWidth(550)
.IsModal(true)
.Start();

The AboutBoxPresenterCreator would hide the adapter and all the stuff
to make that work and delegate to the presenter call to Start()
> http://thebeelog.com- Hide quoted text -
>
> - Show quoted text -

David Laribee

unread,
May 9, 2008, 2:02:50 PM5/9/08
to xe...@googlegroups.com
We went down exactly this road for Composite Controllers, e.g.:

Controller.AddLayout(a).AddPresenter(b).UseLayout(a).AddCommand(x).SetState("hello").Done;

Turns out that was kind of a dead end.

I like what you're saying about using a builder and hooking that into a new... The builder could simply create an IRequest that starts up in the presenter. The other thing it could do is to create the WindowOptions and/or specify the WindowManager that'll either return a new or find an existing WindowAdapter, e.g.

IPresenter p = New.Presenter<ICustomerDetailPresenter>
                            .Window
                                .ManagedBy(customerShellWindowManager)
                                .Size(800,600)
                                .Modal;

That would called DisplayIn on the implicit cast between IPresenter and PresenterBuilder.

We could also do something like:

New.RegisterWindowManager<ICustomerShellWindowManager>(customerShellWindowManager);

Or if you wanted to use string keys:

New.RegisterWindowManager("customer-shell", customerShellWindowManager);

I'd be up for something like this. I'll spike something out and see if it makes things a bit tighter. Good idea.
Reply all
Reply to author
Forward
0 new messages