Working with Drupal for half of year and constantly tuning it for better maintainability, code consistency I came to the idea – Drupal is going to be a toy, a pretty popular but only toy, unless they decide to rewrite everything from the scratch. Studying Drupal 7 I find the CMS wasn’t really refactored. They dramatically improved administrator panel, included CCK/ImageCache into the core, added file handlers and Unit-test framework. However it’s still a mess of coding styles and approaches. You can enter any module folder and you’ll find bunch files with no concern separation. View components, business logic, helpers, domain entities – all can be met in the same file. I understand that laying strict requirements on modules would affect the army of contributors. But anyway with Drupal 7 all the modules must be rewritten. Maybe the committee just can’t agree on a structuring strategy. As for me, it must be like that.
Drupal should consist of the components split up by namespaces: libraries shared among Drupal and other applications when they tied together (e.g. phpBB), modules shared among all sites built on an instance of Drupal and modules of particular site.
The libraries must be designed to be used in different contexts (e.g. context is given as a parameter when necessary). All the libraries are of the same name convention and easy accessible through auto-loader (spl_autoload_register). I see Zend Framework library as a best practice here.
The libraries contain abstract classes and interfaces required when extending a library within a module. For an instance, within a module a View helper can be defined (e.g. to display some video format). That means the helper extends View_Helper_Abstract following the rules and naming convention defined there.
As I said, modules can be of global scope or local one, as it is already designed in Drupal. But what wasn’t good designed that’ module structure.
Data sets used in modules are structured into objects kept in Entity folder. No stdObject anymore! Entities or Data Transitional Objects if you wish, define objects to be passed as parameters within application business logic. So in Drupal Node can be an Entity. It means you can use its name to restrict method arguments. You can control its behavior, e.g. to make some attributes read-only. You can always quickly check what properties the Entity has. And, what I like most, you can reflect on Domain Model relations among Entities. E.g. Entity_Image extends Entity_Field and is used by Entity_Node.
Since Entites contain only data and optionally control flows for attribute accessing/mutating, we need functionality to read/save/update/delete them onto a storage layer: DB or file system. Here we go with Data Abstract Objects kept in DAO folder. Drupal has something like first-level pseudo-objects (e.g. Node, now File) which treated through <object>_load, <object>_save, <object>_delete. If this is an implementation of DAO design pattern, it’s an obscure one. Much better would be to have classes (one per file) like DAO_Node extending DAO_Abstract and requiring mandatory methods (e.g. fetch/update/delete).
I consider every Drupal module as a micro-application. Simplifying PAC paradigm I would put it as set of inter-related MVC instances. So any module can be such MVC instance and this will help to get into what is really happening inside the module, where requests come, where their handlers take business logic, what and in which form is given to the presentation layer. Why not? Drupal’s core dispatcher determines which controllers of which modules ought to be invoked. The decision is made by requested URL and routers, which can be defined in modules. Model folder keeps classes which use DAO and Entities of global or local scope. It defines the business logic required by the module. Let’s keep Controllers as light as possible. Their task is to show request handling flow explicitly, nothing more. It’s obvious models use shared libraries including their derivatives, such as Validators. Since shared library has only very general Validators like Email, EmptyValue, all the custom Validators of the module can be kept in Library/Validate folder. Another folder Library/View can contain View Helpers specific for the module. In module template or in the page template the helpers can be called like $view->HelperName()->HelperMethod(…).
As for module assets (images, css) and JS, those files must be placed in some predefined folder for any module. Besides it would be great to have a sort of JS framework with minimum interfaces unifying coding style.
I see this as the only way to make Drupal really maintainable. Just imagine you find a new promising module. But before enabling you can quickly check what really happening in there. You can decide yourself if it’s secure enough for you, if it won’t affect your site performance. Besides it would be much easier to tune Drupal for yourself when you need it, to use the entire range of Drupal features which are easily seen in the code instead of being spread out in tons of books and documentation variants.