Great... I have committed that to 'develop', together with a bunch of other things.
On Tue, Jun 16, 2015 at 11:15 PM, Paul Merlin <[email protected]> wrote: > 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 > -- Niclas Hedhman, Software Developer http://zest.apache.org - New Energy for Java
