Orchestrating functions with the layered approach
Functions seldom exist in a vacuum. They work with other functions, exchanging and processing data to get tasks done. Writing functions that work well with other functions in the same group or module is important because it's precisely these groups of functions or modules that you must be able to reuse.
Let's continue with your hypothetical page-building example. The responsibility of the module here is to build a page by using HTML. (Let's not dive into specifics and code right now because the object of the example is to simply illustrate how functions and groups of functions can be made to mesh easily while increasing the reusability factor.)
Starting with built-in PHP functions, you can build abstraction functions, use them for making more functions that deal with basic neccessities, and then use them in turn to build functions specific to the application. Figure 2 gives you an idea of how this works.
Now, you'll build the page first in memory and then dish out the completed page to the browser.
Building the page in memory offers two major benefits:
- You can cache completed pages using your own scripts.
- If a page can't be built successfully, you can discard the half-done page and point the browser to an error page.
Now your users won't see pages screaming with error messages in between.
According to the structure of most pages, you'll divide your page-building module into functions that:
- Draw the top bar
- Draw navigation bars
- Display content
- Add the footer
You'll also have functions to:
- Cache the page
- Check to see if the page has already been cached
- Display the page if it has been cached
Let's call this the pagebuilder module.
The pagebuilder module does its job by querying a database. Because this database is external to PHP, you'll use a database-abstraction module with the responsibility of providing a homogeneous interface to PHP's different vendor-specific database functions. Important functions in this module are connecting to a database, querying the database, and giving out results of the query.
Pretend you also want to implement a site-wide search engine. This module will be responsible for searching documents on the site related to a keyword or a group of keywords and displaying results based on the relevance or maximum occurrence of the search string. If you also want to log the searches for audit, this module will work with the database-abstraction module.
Remember, you are accepting input from the user. You need to screen it and discard things that seem malicious. This calls for another module, one that validates the data that users submit through forms.
By now you must have a rough idea about the concept I am hinting at. Most core functionality must be separated into logical modules and to do their tasks, your applications must use the functions that these modules provide.