Essential Insights into Object-Oriented Programming Concepts

Daniel Pham
11 min readAug 15, 2023

--

Intro to Object-Oriented Concepts and Design

1. Essence of Object-Oriented Technology

“OO technology” encompasses languages, frameworks, and tools shaping Object-Oriented programming. It transforms code into tangible entities called objects, each with unique attributes and behaviors.

At the core of OO technology is Object-Oriented Programming (OOP). It structures code around real-world elements, enhancing reusability and manageability. Objects encapsulate data and behavior, managing complexity effectively.

2. Historical Footprints

  • Rooted in pioneering languages, OO technology traces back to Simula’s introduction of classes and objects. Smalltalk elevated OOP with dynamic typing and object-centric development.
  • Prominent languages like C++, Java, Angular, Python, and C# dominate OO programming, each excelling in specific areas.
  • Unified Modeling Language (UML) serves as a practical tool for designing OO systems. Its diagrams illuminate relationships, aiding well-structured designs.

3. Designing for Object-Oriented Programming

OOAD, short for Object Oriented Analysis and Design, is a pivotal process. It revolves around crafting software solutions by dissecting problems into tangible objects and designing their interactions. This systematic approach ensures robust, maintainable, and efficient systems.

The S.O.L.I.D principles encapsulate a set of guidelines for robust Object-Oriented design:

  • Single Responsibility Principle (SRP): Each class should have only one responsibility.
  • Open/Closed Principle (OCP): A class should be open for extension but closed for modification.
  • Liskov Substitution Principle (LSP): Subtypes must be substitutable for their base types.
  • Interface Segregation Principle (ISP): Clients should not be forced to depend on interfaces they do not use.
  • Dependency Inversion Principle (DIP): High-level modules should not depend on low-level modules. Both should depend on abstractions.

4. Fundamental Concepts of OOP

In object-oriented programming, there are several key concepts that form the foundation of the approach:

  • Objects: Objects are individual building blocks that make up our solutions.
  • Inheritance: We can create hierarchical structures of types using inheritance.
  • Liskov Substitution Principle: With specialized classes or subclasses inheriting from a common superclass, we can substitute any of these specialized classes whenever the client references the superclass.
  • Refactoring: Refactoring is the process of reorganizing object representation, analysis, design, and programming to adjust common characteristics that lead to hierarchy and inheritance usage.
  • Encapsulation: Encapsulation involves packaging data and code together not only into a unified entity but also hiding the data and code behind an interface.
  • Messages: Messages are used to invoke behavior on an object and send messages from one object to another, requesting the object to execute a specified or identified code.

5. Structured methodology vs Object-Oriented methodology

Waterfall Model

The Waterfall model is a well-known structured methodology in software development. It follows a sequential approach, where each phase is completed before moving on to the next one.

While the Waterfall model offers a clear process, it comes with some trade-offs. Extensive time is dedicated to planning, analysis, design, and implementation. This extended timeline makes it challenging to predict delivery dates accurately and may not align with the demand for rapid development.

Four Life Cycle Phases

  • Inception Phase: In the inception phase, the project’s objectives and plan are established. All stakeholders collaborate to define a cohesive project plan that aligns with the envisioned outcomes.
  • Elaboration Phase: During the elaboration phase, the focus is on understanding the system’s functionalities. Use cases are developed to outline what the system should accomplish under various scenarios, involving relevant stakeholders.
  • Construction Phase: The construction phase emphasizes the creation of a robust architecture. Activities are fine-tuned, interaction diagrams are refined, and class diagrams are developed, laying the groundwork for implementation.
  • Transition Phase: The transition phase shifts the focus towards system deployment. Resource utilization is evaluated to ensure a seamless deployment process without resource constraints.

Each phase can involve one or multiple iterations, depending on various factors. Evaluation occurs at the end of each iteration to assess progress and determine the need for further iterations.

Comparing the Waterfall Model and Modern Iterative Approach

The Waterfall model is characterized by its structured process, following a linear path through multiple phases, with each phase dedicated to a single aspect.

On the other hand, the modern iterative approach, often used in Object-Oriented Programming, is designed for early delivery, user acceptance, and rapid feedback.

Understanding Core Object-Oriented Programming Concepts

1. Classes / Objects

  • Programmers create classes using OOP syntax. A class serves as a blueprint, defining an object’s structure and behavior.
  • Classes offer reusability. They can be utilized at runtime to create multiple instances or individual objects as needed.
  • Instances are dynamic entities created from classes. Each instance has its memory allocation, preserving its state.

2. Message & Behavior

  • In OOP, objects invoke behaviors on other objects by sending messages. This concept drives interactions between entities in the system.
  • In modern Object-Oriented programming languages, invoking a method is akin to calling a function. This action triggers the execution of the associated behavior within the object.

3. Relationships

During development, relationships are established between classes and instances. Even before formal design methodologies, the concepts of “is-a” and “has-a” relationships were inherent in Object-Oriented programming.

Collaboration and Association

Collaboration involves interaction among different classes to accomplish tasks. Association is a form of relationship, and a set is a specific type of association.

Aggregation vs. Composition

Aggregation represents a specific type of association where an object has a reference to another object. This relationship is often referred to as “has-a” in the Object-Oriented programming community.

Aggregation implies that if the owner object is destroyed, the owned object doesn’t necessarily get destroyed. Composition, on the other hand, means that if the owner object is destroyed, the owned object is also destroyed.

💡 Note: To differentiate between aggregation and composition, consider whether destroying the owner object implies destroying the owned object. If the owned object can exist independently, it’s aggregation; if its existence is tied to the owner’s, it’s composition.

4. Encapsulation

  • Encapsulation involves hiding details within objects, exposing only an interface while preventing direct access to data from other classes.
  • Encapsulation empowers us to freely modify a class’s internal structure while keeping its interface intact. Data and method code are concealed, with only the interface visible and accessible from external code.

5. Inheritance

  • Inheritance establishes a relationship between a parent class and a child or subclass. All attributes of parent classes are inherited by their children, becoming progressively more specialized as we move from parent to child, and even further to grandchildren.
  • The term “is-a” captures the essence of inheritance. Inheritance signifies that all attributes of the parent class hold true for all its child classes.
  • Inheritance ensures that a parent class’s attributes are shared among all its child classes. The needs of a parent class are fulfilled by all child classes, but the reverse is not necessarily true.

6. Polymorphism

  • Polymorphism refers to the ability to use a common interface across diverse objects. Different object types can implement the same interface in distinct ways.
  • Multiple object types can implement the same interface with varying implementations. The client sends a message to the interface, and the recipient handles it through code linkage.
  • The transmitted code doesn’t concern itself with the recipient’s specific type; it’s only important that the recipient supports the message.
  • Polymorphism manifests differently in various programming languages. Object-oriented languages can be categorized into runtime-dispatch languages and statically-typed languages.

Creating a Visual Model using UML

1. Exploring Visual Modeling

Visual models are essential for understanding complex systems, such as object-oriented ones. They simplify reality, aiding comprehension as we transition from the current to the desired system state. These models act as proxies, representing software components and capturing crucial real-world concepts. While precision varies among models, our overview of UML will explore different types, each providing unique insights into the intricate world of object-oriented programming and design.

2. Unified Modeling Language

UML, or Unified Modeling Language, is a visual graphic language used to model various components and interactions within a software system.

In 1994, Grady Booch, James Rumbaugh, and Ivar Jacobson successfully merged different methodologies into a single graphical modeling language, UML.

Today, UML remains a widely accepted industry standard. It serves as a visual language enabling us to analyze, document, build, and comprehend software systems. Developed by capitalizing on strengths and addressing weaknesses, UML is a powerful tool though it still strives for perfection.

Example of a UML Diagram Created Using draw.io

3. Key Aspects of UML Unveiled

UML delineates two primary class diagrams: structural diagrams, portraying the static composition of system components, and behavioral diagrams, capturing operational or runtime facets of the system.

Class diagrams unveil the essence and components of classes, encompassing class names, attributes, and methods. These diagrams also illustrate inheritance and aggregation relationships. Package diagrams elucidate relationships between groups of classes.

Composite structure diagrams allow us to scrutinize interactions between services at a higher level of component interaction.

BPMN (Business Process Model and Notation) stands as a robust standard for symbolizing and modeling business processes, maintained by an object management group.

UML state diagrams visually manage intricate complexities by amalgamating multiple states into coherent visual components. UML also supports concurrent states, allowing multiple states to function simultaneously.

4. UML Class Diagram

UML class diagrams stand as one of the most commonly used diagram types, with class diagrams being the backbone of this category. The only other type that frequently emerges is UML sequence diagrams. Class diagrams capture the relationships between classes and their collaborators, establishing connections among their instances at runtime.

Connections and Relationships

The interconnections in class diagrams are depicted through lines connecting classes. Various types of links, such as inheritance and aggregation, signify different relationships between classes.

One crucial concept in this context is Multiplicity, representing the quantity of associations — an essential notion to comprehend when transitioning to diverse functionalities (with the default being one).

Understanding Relationships

Within class diagrams, relationships like Aggregation indicate that two objects have a “has-a” relationship. However, the destruction of the owning object doesn’t necessarily imply the destruction of the owned object.

Inheritance, another form of linkage, signifies that subclasses inherit all attributes and behaviors from their parent class. By grasping the nuances of these relationships, developers can construct accurate and insightful class diagrams that enhance their understanding of complex software structures.

Developing Object-Oriented Programming

1. Transitioning from Design to Code

In practice, each use case must lead to corresponding tests, forming the foundation for thorough testing. Adopting a test-driven development approach encourages leveraging visual models to facilitate communication. As object-oriented designers, we should focus on reusing existing classes and assessing the creation of new ones for potential reusability.

A Test-Driven Journey

One way to delineate a test-driven development journey is by starting with writing tests based on use cases. For each new test, as we write the accompanying code and develop it to pass that test, we view the process as an iterative step forward. This iterative cycle fosters a methodical progression, ensuring that code remains robust and functionality is systematically verified.

2. Transitioning from Use Case to Design

A well-structured use case culminates in a detailed use case diagram that delineates the steps, actions, and activity diagram of the scenario. High-level interaction diagrams are crafted based on the interactions identified within the use case description.

Striking a Balance

It’s essential to strike a balance between fully defined designated concepts and the flexibility required for programming. Overemphasizing predefined notions without accommodating programming adaptability could inadvertently lead to a waterfall approach, impeding agility.

Avoiding Premature Development

Avoiding scenarios where coding precedes testing is crucial. Utilizing use cases as a foundation, we pinpoint the tests required to validate each scenario. These tests drive the development of classes and methods tailored to fulfill the demands of each use case.

3. Defining Classes

Beyond a class’s name, the next natural focus is on its methods. These methods are unveiled by examining sequence diagrams, communication diagrams, activity diagrams, and state machine diagrams. Real-world data must remain private, except for showcased constants. All data types must be given meaningful names and types.

Supporting Test-Driven Programming

For test-driven development, maximum deployment is aimed at transforming a “Fail” into a “Pass.” UML supports the concept of visibility similar to Java. When programming with a test-driven approach, we can officially recognize reuse and inheritance as part of the restructuring phase following testing.

Holistic Data Gathering

A comprehensive class diagram draws from various UML diagrams to gather the information needed. “Public” provides a documented interface for a class, while “private” encapsulates a class’s internal implementation. In UML, public attributes can be visualized as public data.

4. Distributed Processing & Distributed Components

Distributed Processing

Distributed processing involves physically partitioning elements of a solution across multiple computers. The term “client-server” is broadly applicable to various use cases, with client-server processing being one of the most prevalent forms of distributed processing.

Typically, the client system is less powerful compared to the server system. In a Three-Tier solution, we have a client, a customized application logic layer on the server side, and a shared data layer on the server side.

In contrast, peer-to-peer structures differ from asymmetric interaction and emphasize symmetrical relationships. In modern service-oriented architectures, including microservices, relationships truly manifest as n-tier configurations. These distributed approaches optimize performance and resource utilization across a network of interconnected components.

Component Architectures

A component is an object that can be automatically composed at runtime with other components to form a solution. Components are objects hidden behind an interface.

Modern component architectures are often built around the concept of managed containers. These containers are responsible for providing a range of services that components can rely on when accessed within that environment.

Distributed Components

Distributed Components involve creating reusable and language-independent components that can be executed on various hosts, allowing them to interact seamlessly. These components rely on interfaces to facilitate behavior invocation across different components.

An object broker acts as a technology bridge, enabling remote method calls on objects located in separate processes or platforms. This process involves intermediary objects, ensuring that the invoking client and the invoked server remain oblivious to the remote interaction, resulting in a seamless and transparent distributed computing experience.

5. Persistance

Persistence involves the ability to store an object’s data in a storage system or retrieve data into an object from a store. Persistent classes must handle both has-a and is-a relationships. Relational databases are not designed to store object graphs. One approach to storing object graphs is serializing them into a stream and then persisting the stream as a binary large object (blob). In the spirit of object-oriented programming, we should consider persistence as a capability provided by objects, a responsibility of objects, and an integral part of the domain.

Conclusion

Here are the key takeaways summarizing the content of our lessons that you should keep in mind:

  1. We’ve covered fundamental concepts, the process of object-oriented design, and essential design principles.
  2. Differentiated between two approaches: structured and object-oriented methodologies.
  3. Explored core OOP concepts: classes/objects, encapsulation, messages & behavior.
  4. Gained insights into Inheritance and Polymorphism, and how they relate.
  5. Discussed the essentials of UML and popularly used UML class diagrams.
  6. Discovered UML design techniques.
  7. Explored the basics of design and code development processes.

By internalizing these fundamental concepts and principles, you’ve laid a strong foundation for your development journey.

--

--

Daniel Pham

Blockchain Developer | Mobile Developer | Full-stack Developer