polygene-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Paul Merlin <p...@nosphere.org>
Subject Re: Assembly proposal
Date Tue, 16 Jun 2015 15:15:23 GMT
Niclas,

I agree that the ApplicationBuilder DSL gets messy easily. Just like any
home-made assembly using the low-level api. It's JSON support is neat
but I had no use of it yet, so ...

I like your approach for Layered applications. I can't see any limit to
what can be done that way and it feels cleaner than low-level assembly.
Probably much easier for newcomers.

Jiri, I agree, this solves only a part of the "problem". For "external
view", I'd say something like Tower or Stacks/BluePrints that we
discussed in the past will be needed.

My 0.2c.

/Paul




Niclas Hedhman a écrit :
> Gang, (again, a bit long...)
>
> I am comparing the ApplicationBuilder, with its DSL and the way I did it in
> my latest application.
> The ApplicationBuilder is cute that it supports JSON, but IMHO it doesn't
> read nicely in code, as there is no "natural" isolation/separation, and
> quickly gets rather 'unruly'. Such 'messy' tendency might become the case
> of the "magic" that I wrote about earlier in this thread as well, since I
> haven't tested that yet. That will be revisited later...
>
> But the ModuleAssembler, LayerAssembler and LayeredApplicationAssembler
> that I am using "feels" quite nice, at least to me and I think(!) that it
> is easier for a newbie to follow and "do the right thing" rather than the
> DSL, which easily gets messy without discipline.
>
> Let's look at a concrete example, and a STRESS that there are no "snips" in
> the assembler classes below other than "import", the classes below are
> complete...
>
> The top application ends up look like this;
>
> public class TestingLayeredApplicationAssembler extends
> LayeredApplicationAssembler
> {
>     public TestingLayeredApplicationAssembler( String name, String version )
>         throws AssemblyException
>     {
>         super( name, version );
>     }
>
>     @Override
>     protected void assembleLayers( ApplicationAssembly assembly )
>         throws AssemblyException
>     {
>         LayerAssembly configLayer = createLayer( ConfigurationLayer.class );
>         ModuleAssembly configModule = configLayer.module(
> "Configuration Module" );
>         LayerAssembly infraLayer = new InfrastructureLayer(
> configModule ).assemble( assembly.layer( InfrastructureLayer.NAME  ));
>         LayerAssembly domainLayer = createLayer( DomainLayer.class );
>         LayerAssembly serviceLayer = createLayer( ServiceLayer.class );
>         LayerAssembly connectivityLayer = createLayer(
> ConnectivityLayer.class );
>
>         connectivityLayer.uses( serviceLayer );
>         connectivityLayer.uses( domainLayer );
>         serviceLayer.uses( domainLayer );
>         domainLayer.uses( infraLayer );
>         infraLayer.uses( configLayer );
>     }
> }
>
> And Layers can either be 'manual' such as in the InfrastructureLayer
> example above, or can be 'magical' as the others are. Name to the layer is
> given through the classname of the LayerAssembler.
>
> So, the DomainLayer would look like;
>
> public class DomainLayer extends LayeredLayerAssembler
> {
>     @Override
>     public LayerAssembly assemble( LayerAssembly layer )
>         throws AssemblyException
>     {
>         createModule( layer, InvoicingModule.class );
>         createModule( layer, OrderModule.class );
>         return layer;
>     }
> }
>
>
> where again it is mostly 'magical' deriving names from the ModuleAssembler
> name, but can be 'manual' as we need in the InfrastructureLayer;
>
> public class InfrastructureLayer extends LayeredLayerAssembler
>     implements LayerAssembler
> {
>     public static final String NAME = "Infrastructure Layer";
>     private final ModuleAssembly configModule;
>
>     public InfrastructureLayer( ModuleAssembly configModule )
>     {
>         this.configModule = configModule;
>     }
>
>     @Override
>     public LayerAssembly assemble( LayerAssembly layer )
>         throws AssemblyException
>     {
>         new StorageModule( layer.module( StorageModule.NAME ),
> configModule ).assemble();
>         new IndexingModule( layer.module( IndexingModule.NAME ),
> configModule ).assemble();
>         createModule( layer, SerializationModule.class );
>         return layer;
>     }
> }
>
>
> since we are using the DSL in the Assemblers of storage and indexing.
>
> ModuleAssemblers have no 'magical' part, so they are fairly straight
> forward. So from the above, an OrderModuler could be;
>
> public class OrderModule implements ModuleAssembler
> {
>     @Override
>     public ModuleAssembly assemble( ModuleAssembly module )
>         throws AssemblyException
>     {
>         module.entities( Order.class, Customer.class );
>         module.values( Address.class );
>         return module;
>     }
> }
>
>
> and the IndexingModule would have something like;
>
> public class IndexingModule
>     implements ModuleAssembler
> {
>     private final ModuleAssembly configModule;
>
>     public IndexingModule( ModuleAssembly configModule )
>     {
>         this.configModule = configModule;
>     }
>
>     @Override
>     public ModuleAssembly assemble( LayerAssembly layer, ModuleAssembly module )
>         throws AssemblyException
>     {
>         new FileConfigurationAssembler().assemble( module );
>         new ESFilesystemIndexQueryAssembler()
>             .visibleIn( Visibility.application )
>             .withConfig( configModule, Visibility.application )
>             .assemble( module );
>         return module;
>     }
> }
>
>
> So, what's the verdict? I have this more or less ready (need to document
> it), and although I think it "competes" with other ways of doing assembly,
> I think it is quite neat and tidy, helping newcomers to get structured (I
> create one package per layer, and its parent contains the
> ApplicationAssembler implementation)
>
>
> Cheers

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message