3

A simple billing system (on top of ColdBox MVC) is ballooning into a semi-enterprisey inventory + provisioning + issue-tracking + profit tracking app. They seem to be doing their own thing yet they share many things including a common pool of Clients and Staff (login's), and other intermingled data & business logic.

How do you keep such system modular? from a maintenance, testability & re-usability stand point?

  • single monolithic app? (i.e. new package for the base app)
  • ColdBox module? not sure how to make it 'installable' and what benefits does it bring yet.
  • Java Portlet? no idea, just thinking outside the box
  • SOA architecture? through webservice API calls?

Any idea and/or experience you'd like to share?

ThinkingStiff
  • 64,767
  • 30
  • 146
  • 239
Henry
  • 32,689
  • 19
  • 120
  • 221

5 Answers5

7

I would recommend you break the app into modular pieces using ColdBox Modules. You can also investigate on separate business logic into a RESTful ColdBox layer also and joining the system that way also. Again, it all depends on your requirements and needs at the moment.

Modules are designed to break monolithic applications into more manageable parts that can be standalone or coupled together.

Luis Majano
  • 334
  • 2
  • 2
  • How does Module break monolithic app really? I can't visualize how it helps decoupling the model w/ parent app's model, other then easy to copy it out when needed, unless the Module's model is totally independent? Thank you – Henry Apr 19 '11 at 09:59
  • 1
    Well first a round of analysis to see the bigger parts of the system and see how they are coupled to each other. This will dictate the major modules that can be in play here. Also, each module can interact with common domain services that are either part of an soa strategy or just part of the overall domain model and part of a common library module. The module itself will only consume these services and provide it's ownn. If you have such a big cohesive application not everything will be totally decoupled. That is an unattainable nirvana. You have to have certain balance between modularity and – Luis Majano Apr 19 '11 at 16:54
  • 1
    And coupling. Good domain model model architecture will help younand if you leverage a di library like wirebox or cold spring you can have betternmanagement of these domainnobjects and how et will be wired. Again my advice is to document the big picture of the application and getnto a place where you have common services and specific services and construct your modules accordingly – Luis Majano Apr 19 '11 at 16:56
  • Thank you Luis, I will read the CB's Module doc first. Any comment on turning the app into SOA architectural with ColdBox Relax? When to use it and What benefit does it bring? Thanks again – Henry Apr 19 '11 at 18:29
3

Stop thinking about technology (e.g. Java Portals, ColdBox modules, etc...) and focus on architecture. By this I mean imagining how you can explain your system to an observer. Start by drawing a set of boxes on a whiteboard that represent each piece - inventory, clients, issue tracking, etc... - and then use lines to show interactions between those systems. This focuses you on a separation of concerns, that is grouping together like functionality. To start don't worry about the UI, instead focus on algorithms and data.

If you we're talking about MVC, that step is focusing on the model. With that activity complete comes the hard part, modifying code to conform to that diagram (i.e the model). To really understand what this model should look like I suggest reading Domain Driven Design by Eric Evans. The goal is arriving at a model whose relationships are manageable via dependency injection. Presumably this leaves you with a set of high level CFCs - services if you will - with underlying business entities and persistence management. Their relationships are best managed by some sort of bean container / service locator, of which I believe ColdBox has its own, another example is ColdSpring.

The upshot of this effort is a model that's unit testable. Independent of of the user interface. If all of this is confusing I'd suggest taking a look at Working Effectively with Legacy Code for some ideas on how to make this transition.

Once you have this in place it's now possible to think about a controller (e.g. ColdBox) and linking the model to views through it. However, study whatever controller carefully and choose it because of some capability it brings to the table that your application needs (caching is an example that comes to mind). Your views will likely need to be reimagined as well to interact with this new design, but what you should have is a system where the algorithms are now divorced from the UI, making the views' job easy.

Realistically, the way you tackle this problem is iteratively. Find one system that can easily be teased out in the fashion I describe, get it under unit tests, validate with people as well, and continue to the next system. While a tedious process, I can assure it's much less work than trying to rewrite everything, which invites disaster unless you have a very good set of automated validation ahead of time.

Update

To reiterate, the tech is not going to solve your problem. Continued iteration toward more cohesive objects will.

Now as far as coupled data, with an ORM you've made a tradeoff, and monolithic systems do have their benefits. Another approach would be giving one stateful entity a reference to another's service object via DI, such that you retrieve it through that. This would enable you to mock it for the purpose of unit testing and replace it with a similar service object and corresponding entity to facilitate reuse in other contexts.

In terms of solving business problems (e.g. accounting) reuse is an emergent property where you write multiple systems that do roughly the same thing and then figure out how to generalize. Rarely if ever in my experience do you start out writing something to solve some business problem that becomes a reusable component.

orangepips
  • 9,891
  • 6
  • 33
  • 57
  • I'm already using DDD w/ DI. However, I wonder which of those technologies I mention would give me a better organization of the pieces. The high level view suggests that they should be more loosely coupled, yet the reality is that the DB tables had to be coupled (e.g. FK to Staff.staff_id). Once coupled, it is harder to get out for reuse. Looking for a best of both world solution but doesn't seem like there's one. – Henry Apr 19 '11 at 18:21
2

I'd suggest you invest some time in looking at Modules. It will help with partitioning your code into logical features whilst retaining the integration with the Model.

Being ColdBox there is loads of doc's and examples...

http://wiki.coldbox.org/wiki/Modules.cfm

http://experts.adobeconnect.com/p21086674/

Richard Herbert
  • 616
  • 3
  • 5
1

You need to get rid of the MVC and replace it with an SOA architecture that way the only thing joining the two halves are the service requests.

So on the server side you have the DAO and FACADE layers. And the client side can be an MVC or what ever architecture you want to use sitting somewhere else. You can even have an individual client for each distinct business.

Even for the server side you can break the project down into multiple servers: what's common between all businesses and then what's distinct between all of them.

Salsero69
  • 2,160
  • 3
  • 23
  • 27
1

The problem we're facing here luckily isn't unique.

The issue here seems not to be the code itself, or how to break it apart, but rather to understand that you're now into ERP design and development.

Knowing how best to develop and grow an ERP which manages the details of this organization in a logical manner is the deeper question I think you're trying to get at. The design and architecture itself of how to code from this flows from an understanding of the core functional areas you need.

Luckily we can study some existing ERP systems you can get a hold of to see how they tackled some of the problems. There's a few good open source ERP's, and what brought this tip to my mind is a full cycle install of SAP Business One I oversaw (a small-mid size ERP that bypasses the challenges of the big SAP).

What you're looking for is seeing how others are solving the same ERP architecture you're facing. At the very least you'll get an idea of the tradeoffs between modularization, where to draw the line between modules and why.

Typically an ERP system handles everything from the quote, to production (if required), to billing, shipping, and the resulting accounting work all the way through out.

ERPS handle two main worlds:

  1. Production of goods
  2. Delivery of service

Some businesses are widget factories, others are service businesses. A full featured out of the box ERP will have one continuous chain/lifecycle of an "order" which gets serviced by a number of steps.

If we read a rough list of the steps an ERP can cover, you'll see the ones that apply to you. Those are probably the modules you have or should be breaking your app into. Imagine the following steps where each is a different document, all connected to the previous one in the chain.

  1. Lead Generation --> Sales Opportunities
  2. Sales Opportunities --> Quote/Estimate
  3. Quote Estimate --> Sales Order
  4. Sales Order --> Production Order (Build it, or schedule someone to do the work)
  5. Production order --> Purchase orders (Order required materials or specialists to arrive when needed)
  6. Production Order --> Production Scheduling (What will be built, when, or Who will get this done, when?)
  7. Production Schedule --> Produce! (Do the work)
  8. Produced Service/Good --> Inventory Adjustments - Convert any raw inventory to finished goods if needed, or get it ready to ship
  9. Finished Good/Service --> Packing Slip
  10. Packing Slip items --> Invoice

Where system integrators come in is using the steps required, and skipping over the ones that aren't used. This leads to one thing for your growing app:

Get a solid data security strategy in place. Make sure you're confortable that everyone can only see what they should. Assuming that is in place, it's a good idea to break apart the app into it's major sections. Modules are our friends. The order to break them up in, however, will likely have a larger effect on what you do than anything.

See which sections are general, (reporting, etc) that could be re-used between multiple apps, and which are more specialized to the application itself. The features that are tied to the application itself will likely be more tightly coupled already and you may have to work around that.

For an ERP, I have always preferred a transactional "core" module, which all the other transaction providers (billing pushing the process along once it is defined).

When I converted a Lotus Notes ERP from the 90's to the SAP ERP, the Lotus Notes app was excellent, it handled everything as it should. THere were some mini-apps built on the side that weren't integrated as modules which was the main reason to get rid of it.

If you re-wrote the app today, with today's requirements, how would you have done it differently? See if there's any major differences from what you have. Let the app fight for your attention to decide what needs overhauling / modularization first. ColdBox is wonderful for modularization, whether you're using plugin type modules or just using well separated code you won't go wrong with it, it's just a function of developer time and money available to get it done.

The first modules I'd build / automate unit testing on are the most complex programatically. Chances are if you're a decent dev, you don't need end to end unit testing as of yesterday. Start with the most complex, move onto the core parts of the app, and then spread into any other areas that may keep you up at night.

Hope that helped! Share what you end up doing if you don't mind, if anything I mentioned needs further explanation hit me up on here or twitter :) @JasPanesar

Jas Panesar
  • 6,597
  • 3
  • 36
  • 47
  • Thank you for such a thoughtful and well written response. I am still lost on how to architect an ERP in CF, or is CF even the right tool for building such system? Currently, I think Order's Status are not enough to capture the flow of events... I can only think of using State Pattern, but doesn't make much sense when there are 10+ states... – Henry Apr 25 '11 at 20:05
  • Thanks for the kind words. I had to learn ERPs pretty painfully so it became painfully clear lol. CF or any other tool is fine for the ERP, if you already have a codebase in place. Many ERPS work off the concept of "documents" where the data kept being copied from one document (sales order) into the next (production order) and the next (packing slip) into the next (invoice whatever got built and packed to ship).. – Jas Panesar Apr 25 '11 at 20:34
  • Any framework to build an ERP on? Did you learn ERPs using any book or other resources? Thank you. – Henry Apr 25 '11 at 20:42