The PhilosophyModular Programming has never been marketed like Object Oriented programming has. A lot of modular programming is done in well thought out procedural code, and in well thought out object oriented code, sometimes. However objects can lead to private restrictions where algorithms are welded to a class or object (or even a file). Procedural code on the other hand can lead to global spaghetti code (as seen in plenty of PHP the Pasta Home Page language)What is in between? Modular Programming. All good procedural programmers create modules.. without always necessarily knowing it. All object oriented programmers try to make modules at some point or another. The problem is when a module becomes overly complex with modules inside classes inside modules inside classes. Powtils uses the KISS principle (Keep It Simple Stupid). The idea is that one can always wrap a module, into something more complex.. if they wish. By default, one should not be forced to use an overly complex architecture with all decisions made for them ahead of time. Rather the framework should be flexible and prepared for growth. Modular programming is not a purist paradigm.. but just a guideline and a concept. Modular CellsHumans, have cells - thousands - which are all modules. Modules are essential for any large sized project. For if your cell dies, it is replaced with another and is not a big deal. A cell can die on the human skin without a human noticing. It is replaced promptly, i.e. swapped with a newly grown one.Dead CellStandard Pascal lacked modules - and it died for a good reason. It was not prepared for growth by modules - it was only prepared for growth by adding another procedure to the end of the program.Modular PowtilsThe core (base) Powtils framework or API makes use of modules and units wherever possible to encapsulate data and algorithms. Powtils makes heavy use of Delphi and Freepascal's unit system to separate code into maintainable plugin-able modules. In version 1.7.x, Powtils especially demonstrates this with the plug-in session and config units.The use of classes and objects are optional. Powtils does not force one to instantiate an object before using many utilities. ExampleThe heavily used OutLn() and Out() procedures are not part of a class, but are part of a module. No class needs to be instantiated before using the Out() or OutLn() procedures in Powtils. This especially keeps code simple and clear.program easy; uses pwinit, pwmain; begin outln('hello'); end. Build Classes As You WishAddons, extra units, and some modules contain classes where needed.Any Powtils function, module, procedure, or class can be wrapped to a higher level by any programmer. The Powtils project aims to be wrap-able and extensible... prepared for growth, instead of making all the decisions for you and forcing them on you. Modular LibraryPowtils also offers a library that can be loaded into the web program in some versions, as an alternative to static compilation.Modular SwappingModular programming practice offers strong swapping abilities, and strong debugging and troubleshooting abilities as a side effect.For example
Modular IDEAn IDE can only grow and continue to be maintainable in a worldwide project if it has a modular component or plug-in system. The PowDev IDE and any IDE offered by the Powtils team will have modular plug-ins and extensibility available.NamespacesNamespaces are actually a form of modular programming in disguise. They don't call namespaces modules, since they don't want to sound too much like Modula... but that's really what they are emulating.Modular Analogies and ReferencesAn article with plenty of references and analogies is at PasWiki. Included are some links to PDF files and quotations from other programmers who have found modular programming extremely useful.Ruby and Modula?Ruby has "modules" in addition to classes, which is good. Ruby's syntax also borrows heavily from Modula. However, ironically, Ruby goes against all the laws set out by Wirth when he created Modula.. a simple language with common simple syntax. Ruby is actually more like perl complexity when it comes to syntax. Ruby is okay, but Lars has some opinions on it too.Real World Modular ProgrammingModula, Oberon, and ComponentPascal (modular languages) are not so useful in the real world right now as they are not mass market languages with lots of developers. However Modula is a language that all other languages have borrowed from.Modular programming does not require using Modula. One can implement and practice modular programming in other languages, especially ones that have a unit or module system in place. Namespaces can work, but why is everyone calling it their own new term? Egos. A namespace is just a different kind of module. Ruby's modules are like namespaces, in fact... they just call them "module" since it rightly makes more sense (as Modula gave them the idea, so why not?). What Is Modular ProgrammingLars' definition of Modular programming is not just slapping some functions into a namespace or a unit.. rather it is actually applying several modular concepts into the entire framework.. such as plug-in-able units, replaceable functions, swappable functions, swappable plug-ins, swappable modules, swappable dynamic link libraries, replaceable database, replaceable session management, etc.Bugs Bugs Bugs (and reuse)One big problem with software is bugs.. and by having a replaceable module one can replace a buggy "cell" with a new "cell" much easier. A lot of object oriented hype revolves around people claiming that we can greatly reuse objects.. but in fact many times this reuse actually kills our program - the object has a bug hard-coded into it and all the other objects abstract from this bug and carry it with them, making it greatly more difficult to find the bug, since the bug becomes more and more encapsulated!Modular Myths BustedSome claim that modular programming does not offer encapsulation or reuse like objects do.Modules can be reused too. Modules encapsulate too. A module can be a capsule that encloses code (with more public flexibility than objects.. but with ability to use restricted objects in the capsule!). Modules can have objects in them, but objects aren't required for encapsulation. Of course modules can have bugs too.. and modules are not the holy grail that solves every world problem. One might argue that "but my definition of encapsulation requires OOP feature XYZ". However if you look up the definition of encapsulation.. it is just about creating capsules. Emulating Modular ProgrammingThe ".C" files in Cee and the ".PHP" files in PHP are poor capsules. Hacks can be used such as mynamespace_and_function using underscore tricks. They are not true modules.However, if you are stuck with a language that doesn't support good modular programming.. then you can still apply the concepts to your tool. i.e. a good programmer can write clean code in any language. Some languages just make it easier - and this is very important. Some languages also set good habits that allow a programmer to understand modular programming, instead of the programmer trying to reinvent it himself each time with underscores or such hacks. Languages that make it easier are ones like Modula, Modern Pascal (but FPC and Delphi lack some important features), ComponentPascal, Ruby, C#, C++, (namespaces are a module in disguise), Qomp, Erlang, Limbo, etc. OOP vs MOPThere is no fight here between modular vs object oriented coding. They are not in a boxing match. This is not the procedural versus object oriented debate. Modular programming is a neutral war country. You can use procedures, functions, or objects in modular programming.Simplicity ClicheUltimately modular programming revolves around a cliche related to "simplicity". i.e the simplest solution fits. In much of the code we see today, there are far too many overly complicated architectures.A good module is not complicated to wrap, use, and update. Simple programming can be very hard.. but it shouldn't be complicated. i.e. a module may have algorithms in it that took years to refine.. and this was very hard work. However that doesn't mean the module should be complex to use, maintain, and wrap. A lot of architects unfortunately equate complexity and "number of lines of code" with quality. Not so. |