Lesson 5
Object Oriented Programming Conclusion
This lesson has shown you the benefits that OOP brings to a project and to a programmer.
You have learned how to:
- Keep your analysis in the business world, using business words, with encapsulation of related strings and numbers into classes
- Make teamwork more productive by separating classes that require specialized knowledge from those that do not.
- Achieve reuse without instruction lists from the programmer who wrote the code you are reusing.
- Compare the responsibilities of your classes with the overall project scope to ensure nothing's been forgotten.
The next module discusses classes and objects in more detail and illustrates how to create class and object diagrams.
Employ Strategies that segregate Classes
To enhance productivity in a team environment, especially in object-oriented programming (OOP), it's crucial to employ strategies that segregate classes requiring specialized knowledge from those that do not. This approach not only streamlines the development process but also leverages the diverse skill sets within a team. The following strategies can be instrumental in achieving this separation effectively:
- Encapsulation and Abstraction:
Encapsulation involves hiding the internal state and functionality of an object and exposing only the necessary interfaces. This principle enables developers to work on classes without needing to understand their intricate details, thus reducing the need for specialized knowledge. Abstraction, on the other hand, focuses on exposing only the relevant features and functionalities of an object, making it easier for team members to interact with complex systems without being overwhelmed by their complexities.
- Interface and Inheritance Design:
Designing clear and concise interfaces allows classes to interact with each other without requiring deep knowledge of their implementations. This is particularly useful in teams where specialized knowledge is unevenly distributed. Inheritance can be used to create a hierarchy of classes where more general behaviors are defined in parent classes, and specialized behaviors are implemented in child classes. This approach allows developers to work on different levels of the hierarchy according to their expertise.
- Use of Design Patterns:
Design patterns provide templated solutions to common software design problems. By employing design patterns, teams can standardize the structure and behavior of classes that require specialized knowledge, making it easier for other team members to understand and work with them. Patterns such as Factory, Strategy, or Observer can encapsulate complex logic within a well-defined structure, thereby reducing the cognitive load on developers unfamiliar with the specifics.
- Modularization and Component-Based Development:
Breaking down the software into smaller, manageable modules or components allows team members to focus on specific areas without the need to understand the entire system. Each module can encapsulate a set of functionalities that require specialized knowledge, while providing a simple interface for interaction with other modules. This approach not only simplifies development but also enhances maintainability and scalability.
- Documentation and Code Comments:
Well-documented code and comprehensive documentation play a pivotal role in bridging the knowledge gap among team members. Documentation should clearly outline the purpose, functionality, and usage of classes, especially those that encapsulate complex logic or require specialized knowledge. Code comments can provide valuable insights into the implementation details and decision-making processes, aiding in knowledge transfer and collaborative problem-solving.
- Continuous Integration and Code Reviews:
Implementing a continuous integration (CI) pipeline ensures that code changes are integrated and tested frequently, allowing for early detection of issues and misunderstandings about class functionalities. Regular code reviews promote knowledge sharing and collective code ownership, enabling team members to gain insights into parts of the codebase that may require specialized knowledge, thereby fostering a collaborative learning environment.
By adopting these strategies, teams can effectively manage the complexity of object-oriented software development, ensuring that specialized knowledge is encapsulated within specific classes while maintaining overall accessibility and comprehensibility for all team members. This balanced approach not only enhances productivity but also promotes a collaborative and inclusive team culture.
Evolve Object-oriented Code
To evolve object-oriented code, one must understand both the code structure in terms of classes, and the runtime structure
in terms of abstraction of objects that are being created and the relation between those objects.
To help with this understanding,
static program analysis[1] can extract heap abstractions such as object graphs. But the extracted graphs can become too large if they do not sufficiently abstract objects, or too imprecise if they abstract objects excessively to the point of being similar to a class diagram that shows one box for a class to represent all the instances of that class.
One previously proposed solution uses both annotations and abstract interpretation to extract a global, hierarchical, abstract object graph that conveys both abstraction and design intent, but can still be related to the code structure. Here we define metrics that relate nodes and edges in the object graph to elements in the code structure to measure how they differ, and if the differences are indicative of language or design features such as 1) encapsulation, 2) polymorphism and 3) inheritance. We compute the metrics across eight systems totaling over 100 KLOC, and show a statistically significant difference between the code and the object graph. In several cases, the magnitude of this difference is large.
Object-Oriented Programming
In object-oriented (OO) programming, an application consists of a series of objects that ask services from each other.
Each object is an instance of a class that contains a blueprint description of all the object's characteristics. Contrary to procedural programming, an object bundles both its data (which determines its state) and its procedures (which determines its behavior) in a coherent way. An example of this could be a student object having data elements such as ID, name, date of birth, email address, and so on, and procedures such as registerForCourse, isPassed, and so on. A key difference between OO and procedural programming is that OO uses local data stored in objects, whereas procedural programming uses global shared data that the various procedures can access directly. This has substantial implications from a maintenance viewpoint. Imagine that you want to change a particular data element (rename it or remove it). In a procedural programming environment, you would have to look up all procedures that make use of the data element and adapt them accordingly. For huge programs, this can be a very tedious maintenance exercise.
When you are using an OO programming paradigm, you only need to change the data element in the object's definition and the other objects can keep on interacting with it like they did before, minimizing the maintenance. OO programming is the most popular programming paradigm currently in use. Some examples of object-oriented programming languages are Eiffel, Smalltalk, C++, and Java.
Object Oriented - Quiz
[1] Static program analysis: In this type of analysis of computer software, analysis is performed without actually executing programs, in contrast with dynamic analysis, where analysis is performed on programs
while they are executing.