views:

705

answers:

6

I am looking for pointers, suggestions, links, warnings, ideas and even anecdotical accounts about "how to design an application in a modular way". I am going to use python for this project, but advice does not need to necessarily refer to this language, although I am only willing to implement a design based on OOP.

Here's some context to understand where I come from and what I am trying to achieve...


My project will be a small application that will consume web services and display the results in a variety of ways, including:

  • notification popup containing just the result of the call
  • tab in the main window of the application with graphics plotted from retrieved raw-data
  • buffer of messages (visible on domand) where results from various services will pile up

The application will be released as free (as-in-speech) software, and for this reason I would like to make it really easy for other devs to write plugins/modules that will extend the functionality of the main application without needing to change the core code.

At this point in time, plugins should essentially enable a developer to activate a new webservice, by defining the provider, the data manipulation (if any) and the way the data will be presented to the user.

I have extensive experience in developing with drupal which has a powerful modular approach, but that also follows a non-object-oriented design, so I suspect that for python, drupal design might not be the optimal solution.

If this is of any importance - the core will be natively developed for GNU/Linux.

Thank you in advance for your time!

+2  A: 

Well, probably the first place to start is to sit down and figure out what the plug-in might need to fulfill its purpose.

You'd want to consider two main aspects in your design.

  • How will your framework pass requests / receive responses from the plug-in?
  • What helper classes or modules might be good to provide?

And probably also, since this sounds like a learning project.

  • What do you want to write yourself, and what are you happy just to pick out of an existing library?

I'd also recommend developing some basic plugins as you design the API. The experience of having to actually use what you design will allow you to see where a given approach might be making things harder than they need to be.

Adam Luchjenbroers
Thank you for your answer (+1). Some additional points: (1) *"How will your framework pass requests / receive responses from the plug-in"* is probably the main focus of my question. I am used to a system for which the core "invokes" hooks in all registered modules, but I do this procedurally, and I was interested in finding out how to do it in a OOP. **Any hints on that?** (2) This is a learning project [meaning: I do it for fun, for my own learning]. The main focus for me is modular design. I am happy to use libraries for those parts like plotting data, notification popups, etc...
mac
(3) My idea is to have the "core" already shipped with some "core modules" providing example services. So I will go with your advice of using the API myself! :)
mac
Re 1,2: One solution would be to create a PlugIn class to be used as a base class for all plugins. It should provide default implementations for all of your 'hooks' (Or throw NotImplemented for mandatory hooks) which can then be overridden by the plugin.
Adam Luchjenbroers
+1  A: 
  • design the api for your app, carefully (How To Design A Good API and Why it Matters)
  • make everything, which could be used independently a module, then group and build larger parts out of the simple parts (KISS)
  • don't repeat yourself (DRY)
  • write/publish short documentation frequently, for yourself and others (open source mantra) ...
The MYYN
Thank you for the answer (+1). The guy in the video is a bit verbose [he starts off saying the subject does not land itself to brief presentations... but I feel like disagree on that!], but it gives some concrete advice that I will try to stick to! :)
mac
+7  A: 

Short Answer to make Modular Design

You can check,

  • (Inversion of control) pattern
  • Dependency Injection pattern
  • Locator pattern

All of them are described in Martin Fowler:IOC and Microsoft:Modularity

to Implement them in real world

First of all select methadologies to planning and processing project. I use Scrum.

SCRUM


Test is more important than coding and check out TDD

TDD


Also Refactoring is important.

REFACTORING


Source Version Control (SVN, CVS, GIT etc.) is important

SOURCE CONTROL


Continious Integration (Hudson, Cruise Control etc.) is important. (Also you can check Continious Integration Tools)

alt text


Keep everythings simple, don't make things harder.

KISS


Use maven or same things to manage dependency (this can help in modular way) Additional you can check Grails and AppFuse

MAVEN


Use software pattern, oo principles etc. and patterns, principles, idea based frameworks (like spring, guice etc.).

OO


Also be careful to select which language, Os platform, technologies etc. that you choose. It usually depends on what do you want to develop.

SAMPLE LANGUAGE GRAPH


Issiu tracking is important also. We can use trac, bugzilla etc. Eclipse and another IDEs have got connector of tracking system.

alt text


And last, manageability is No:1 important things.

IMPORTANT


After that we can develop everything in modular etc.

javaloper
I was going to comment to the question that it would require a very long answer covering far too many things for one post, but you managed to pull it off! +1 for that.
Makis
@javaloper - Thank you for the extensive answer and the time you dedicated to that (+1). This is most certainly an interesting answer, yet I fail in seeing the *specificity* to modular design of most of the points: I would say that all of the points apply to good practices in programming in general, while some belongs to *agile development* principles, which I like and try to develop accordingly. Is there something I am missing? Would it be possible for you to clarify?
mac
Congratulations, so little meaning encoded in so may bits! Some sort of new SO record, I suppose.
anon
That is an epic answer! +1
Robert W
@mac you can give it a try to use spring and osgi framework together with springsource tools ide for modularity (http://www.javaworld.com/javaworld/jw-04-2008/jw-04-osgi2.html). Also eclipse is OSGI based ide. I think that eclipse ide is modular as possible :)
javaloper
Pictures don't always make a good answer...
Skilldrick
@Skilldrick You are right, picture just attract attention to words like presentation documents.
javaloper
Thank you @Neil Butterworth
javaloper
Is it just me or do you have an error in the TDD picture? Shouldn't you go to the rewriting the test if the test fails and write production code if the test passes? Not the other way around as you have there?
Tofystedeth
@Tofystedeth, this is wiki image of TDD. "Write Production Code" means for me ; realisation of test. For example i write test assertEquals(4,calculatorService.add(2,2)); this is not real, this line is just imaginary of calculatorService to add 2 numbers process. It is not exist yet. Then my test will fail after unit running. I must implement calculatorService. This will be also production code implementation or just production interface code (It depends on me if i want to use mock object)
javaloper
Copy pasting of pictures, reciting common wisdom with poor spelling and grammar, many of those items are only tangentially relevant to the original question and no evidence of any real thinking involved.... -1.
Adam Luchjenbroers
Thank you @Adam Luchjenbroers. Excuse for my English, i try to improve my english by the time. But still i was happy, you understand my explanations, because of you can criticize. Additional original question is "how to design an application in a modular way" for me. Then i tried to explain in my way.
javaloper
+7  A: 

As you will deliver some basic functionality with your app, make sure that you code the part that should be extendable/replaceable already as a plugin by yourself. Then you'll best get a feeling about how your API should look like.

And to prove that the API is good, you should write a second and third plugin, because then you will discover that you made a lot of assumptions when writing the first one. Normally things clear up a bit after doing this 2nd and 3rd step.

Now, you should write one more plugin, because the last plugins you wrote resemble the first one in type, input data and presentation (maybe yet another weather webservice). Choose something total different, with absolutely different data, and you will see your API being still too tailored. (Else you did a good job!)

MicSim
Thanks for this (+1). Actually your answer resemble closely one of the points given in the google presentation linked by "The MYYN" in his answer! :)
mac
+2  A: 

Try to keep things loosely coupled, and use interfaces liberally to help.

I'd start the design with the Separation of Concerns. The major architectural layers are:

  • Problem Domain (aka. Engine, Back-end): the domain classes, which do all the actual work, have domain knowledge implement domain behaviour
  • Persistence: storage management for domain classes, database/filesystem layer
  • User Interface: the GUI, which talks to the domain classes
  • System Interfaces: talking to other systems, eg. networking, web services

The domain classes do the work, but don't know about the UI. The persistence layer knows about the domain classes, enough to save/load as required. The system interface layer abstracts away external systems, which lets you plug a simulator in behind while testing. The UI should ideally use MVC, for maximum flexibility.

Without putting too fine a point on it, one would not ordinarily look to Drupal as an exemplar of good architectural design. It has grown rather organically, and there have been many upheavals of the design, as evidenced by the regular plugin breakage upon system upgrades.

I would also echo what MicSim said, regarding carefully designing the plugin interface and writing multiple different plugins to exercise it. This is the only way to really flesh out the issues of how the app and plugins interact.

gavinb
Thank you for this! (+1)
mac
+1  A: 

Look into the listener-subscriber pattern. Sooner or later, your app will be complex enough that you need to implement callbacks. When you hit that limit, use listener-subscriber (there's an implementation in wxPython).

For example, several modules will want to watch for new data from a number of feeds. Modules that link together might want to update themselves, based on new data.

wisty
Thank you for this (+1). I was looking up on the GoF the *Observer* pattern (which I notice now is also known as "Publish-Subscribe"). I will research on the listener-subscriber one, then. It looks like a promising lead!
mac