Moving "from scripting to programming" is so much broader than whether to embrace
a "fully fledged, object oriented approach"!
Conway's Ten Essential Development Practices
should help you appreciate that. For example:
- Design the Module's Interface First. The most important aspect of any module is not how it implements the facilities it provides, but the way in which it provides those
facilities in the first place.
- Write the Test Cases Before the Code.
- Use a Revision Control System.
- Add New Test Cases Before you Start Debugging.
- Don't Optimize Code -- Benchmark It.
Modularity is a fundamental aspect of all successful large programs.
In Perl therefore, modules are fundamental and you must master them.
A study of top-rated CPAN modules is time well spent.
For more details see: Writing Solid CPAN Modules.
High-level Design Checklist
- Know Architectural patterns. Choose wisely. Multitier archtecture is common.
- Coupling and Cohesion. Systems should be designed as a set of cohesive modules as loosely coupled as is reasonably feasible.
- Testability. Systems should be designed so that components can be easily tested in isolation.
- Information hiding: Minimize the exposure of implementation details; provide stable interfaces to protect the remainder of the program from the details of the implementation (which are likely to change). Don't just provide full access to the data used in the implementation. Minimize the use of global data.
- Interfaces matter. Once an interface becomes widely used, changing it becomes practically impossible (just about anything else can be fixed in a later release).
- Design the module's interface first.
- Design interfaces that are: consistent; easy to use correctly; hard to use incorrectly; easy to read, maintain and extend; clearly documented; appropriate to your audience. Be sufficient, not complete; it is easier to add a new feature than to remove a mis-feature.
- Use descriptive, explanatory, consistent and regular names.
- Correctness, simplicity and clarity come first. Avoid unnecessary cleverness. If you must rely on cleverness, encapsulate and comment it.
- DRY (Don't repeat yourself).
- Establish a rational error handling policy and follow it strictly.
As for whether and when to use OO, there is no substitute for judgement and taste
based on understanding and experience.
A simple rule of thumb is to ask "do I need more than one?":
if the answer is yes, an object is indicated;
if the answer is no, then a module.
For some general background on programming paradigms,
I quite like Stroustrup's description of different programming styles in C++,
a multi-paradigm programming language:
- Procedural: Decide which procedures you want; use the best algorithms you can find.
- Modular: Decide which modules you want; partition the program so that data is hidden within modules.
- Data Abstraction: Decide which types you want; provide a full set of operations for each type.
- Object Oriented: Decide which classes you want; provide a full set of operations for each class; make commonality explicit by using inheritance.
- Generic: Decide which algorithms you want; parameterize them so that they work for a variety of suitable types and data structures.
Though Perl is also a multi-paradigm language, it has significant differences from C++ --
for example, Perl is dynamically typed while C++ is statically typed --
so a Perl design of a given system may vary significantly from a C++ one.
Updated 2020: Minor changes to "High-level Design Checklist" section.