














































Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
A comprehensive overview of object-oriented programming (oop) principles, including encapsulation, inheritance, and polymorphism. It also explores design patterns like abstract factory and strategy, highlighting their role in creating scalable and maintainable software. The document further emphasizes the importance of clean code techniques and solid principles for improving code quality and collaboration within development teams.
Typology: Study notes
1 / 54
This page cannot be seen from the preview
Don't miss anything!















































I am working as a junior mobile developer in software and mobile app development company Myan Pro Solutions. I was assigned to help in improving the documentation of the company’s in-houses libraries. As a part of my role, I was assigned to develop an app for the Prestige Automobile Company Limited (PAC) which is an official importer and distributer of BMW vehicles and Genuine BMW parts to provide services. The company wants an application that can allow them to add new cars, display car list, searching and updating of the car model and delete unnecessary ones. In here, I will discuss about the OOP paradigm, design principles and relationship between them, and example with the UML diagrams and application’s UML diagrams along with the explanation of them.
OOP is a class-based programming that contains a group of attributes and methods to create an object. A class may represent multiple objects that interact with each other and in complex ways. In OOP structure it contains a class that provide a framework for creating objects, objects that represents a creation of class which defines specific data like properties and behaviors to implement a code, method which is a function that can perform a task and attribute which stores information about an object. For example, that a Human class defines a template for a human. Attributes of this class that define a person include name, email, and address. It can also include procedures, or functions that characterize the behaviors or acts that a human can carry out. Methods like verify and send email to for emailing and checking that if it is valid or not.
In OOP they contain data, that refers to the attributes, and methods by allowing them to interact with each other with these principles.
Encapsulation – is a principle that keeps all critical information inside the object and restricts assess to public functions or methods from hiding detail information from the outside world. This provides security control over state changes, reduces errors and improve program understanding. For example, if there is a class that encapsulate variables and methods in a single unit which protect the internal state of the object and improve modularity by limiting direct access to some of its components. Inheritance – inheritance allows the developers to create new classes based on the parent class enabling them to override their properties and methods. This principle is useful in programs with thousands of like of code by simplifying the maintenance and can reduce code duplication. This inheritance relationship enables the extension of class A's functionality and the reuse of code by allowing class B to inherit attributes and methods from class A. Single inheritance supports a hierarchical classification and assists in maintaining of a logical and clear structure within the codebase. Polymorphism – this principle complete inheritance by enabling the objects of different classes to perform tasks with the same name with different code. It can simplify the development process by developing common functions and methods for many types of projects. It contains method overriding, where subclasses provide specialized implementations of superclass methods, and method overloading, when many methods with the same name but different parameters exist in the same class. Abstraction – this principle simplifies the complexity of the program on essential elements and hiding unnecessary features making the code more understandable. This allows developers to manage complexity by focusing on high-level concepts rather than detailed implementations. Abstraction highlights important aspects of
relationship but a parent can exist without a part of child and vice versa. For Example, an employee may belong to many departments within organization but if the department is deleted the employee object will not be erased. Realization – refers to the relationship between interface and a class that implement the interface. For example, there is a car interface that contains methods like start and stop method and implemented by “Mercedes” and “Tesla” classes. Each class has their own implementation like unfolding roof and charge battery. (Kanjilal,
Design patterns are reusable solutions to often occurring problems. Design patterns were started as guidelines that were applied again and again to comparable issues found in different context of software design.
Creational design Pattern provide creation of objects that are trying to build objects in manner correspond to the situation. Design issues or complexity may increase from the basic form of object production. This design pattern can solve this problem by managing the object creation process. Singleton Pattern – it can enables to ensure that a class has only one instance while offering a global access point to this instance. This example shows the creation of a Singleton class named MySingleton, protected from outside creation by a private constructor _internal(). The instance is kept in a static variable _instance; a factory constructor validates whether an instance has been generated.
Abstract Factory Method Pattern – Abstract factory design enables users to create related objects through abstract factory methods which are implemented by specialized factory classes for each product category. For example, in the diagram, the client request animal from the “AnimalFactory” interface which has two concrete classes “WildAnimalFactory” which will produce “WildDog” and “WildTiger” and “PetAnimalFactory” which will produce “PetDog” and “PetTiger” to create associated animals. This pattern can ensure the scalability and loose coupling by enabling the client to obtain specified animal objects without being aware of their concrete classes.
Structural design patterns define how to combine things to create new functionality. The additional flexibility of object composition come from the ability to change the composition at runtime, which is not available with static class composition. Adaptor Pattern – This pattern enables different interfaces to function together by creating an extension that transforms one interface into another requested by the client. This is particularly useful when integrating current or third-party code that doesn't match the user's expected interface. For example, the "Rect" class is an adapter with a private instance of "OldRectangle", allowing clients to send arguments and modify input to meet its requirements. When using the render() method, it is
Open-Closed Principle (OCP) – this principle allows software components to be open for extension but closed for modification which means the code should be able to add new functions without changing the existing code. Implementing this principle can improve code extensibility which is new functions can be add without affecting the existing code and can reduce the risk of occurring bugs. Liskov Substitution Principle (LSP) – this principle show that superclass or parent class should only be replaceable with the objects of subclass without affecting the program accuracy. The subclass or child class should function as expected when used in place of their parent class. This principle ensure that subclasses continue to behave as their parent class probably would, resulting in more dependable and predictable code. Interface Segregation Principle (ISP) – this principle shows that many client interfaces are better than one general purpose interface which is clients should never be forced to implement a function they don’t need. Since clients are not forced to depend on large interfaces, changes made to one part of the system are less likely to impact to others. Dependency Inversion Principle (DIP) – this principle shows that the classes should depend on interfaces instead of concrete classes and functions. Following this principle makes the design more modular and flexible by reducing the link between high- and low-level components and makes it easier to test individual components by replacing mocks for the dependencies. As it allows the components to be developed and modify independently, it can increase the scalability of the system. (Y.K, 2020)
In software engineering, it is not just about learning languages and coding. As a software developer, if is important to write the code easy to understand and easy to change. Clean code is a technique that developers should follow which is also important between developers. Naming conventions – when giving the name of classes, methods, and variables, using short form like (int a or void b ()) are not allow to use. Instead, it should be
the meaning name that is understandable once it is read by the developer themselves and others. Example, in the following code, the variable name on the left are not understandable and on the right one, they created the variable name which are easily understandable. Single Responsibility Principle (SRP) – this is one of solid principle mentioned above, which most of the beginners do. They write a function that can handle all the tasks which makes code confusing for developers and may face problems while finding bugs and a part of code. For example, the following code has three methods that return specified components of date, time with clear format of method names and proper formatting. Commenting – all the developers use comments to show the purpose of the specific line in the code. It is helpful and help in explaining and understanding the code. If the duplicate comment exist in the same place can be a big problem. Which developers can confuse and get destructed because of the useless comments.
Following clean code techniques have a great impact on the use of data structures and operations many ways. Proper use of clean code techniques can help to improve the code readability by giving proper function and variable names, clear and consistent formatting. Properly organized code with clear documentation allows the developers in maintaining the code like code changes with minimal risk of occurring errors. If the code is well organized, it will be easier in debugging and handling errors. Clean code techniques help to improve the efficiency of data structure and processes which in turn allows for modifications that accelerate the execution of the program. If the code is followed clean code techniques, it is more likely to be reusable. Also, if the code is well- documented, modular and written in understandable way allows developers for easy to recuse multiple parts across the software application. With reusability of the code, the development process can become more efficient and less redundant. Thus, clean code has a great impact on the readability, maintainability, debugging, efficiency, reusability while building the robust and high-quality software project.
In programming, OOP and design patterns are linked in somehow, with the design pattern build based on the principles of OOP to provide solutions to software design problems.
design allows subclasses to offer their own implementations for certain algorithmic components by using abstraction to establish the fundamental structure of an algorithm inside a method.
Following the solid principle has a several good impact and affect on the development process. For example, following the single responsibility principle (SRP), it can help in easier understanding of code and classes that are implemented in the project and easy to debug because of their specified responsibility. It can also improve reusability of the code by allowing easy integration across various part of the application. If the developers followed SOLID principles, it can help in easier collaboration within development teams because of clear roles and well-defined structures, the team members can easily understand different part of code or classes by making it easier to work for various components without confusing in understanding of code. This can reduce the likelihood of facing bugs and errors when the changes are made and increase the project’s integrity and functionality. Also, the code that is written based on the solid principles are more scalable and expendable as they can be expend and develop new requirements without
The UML diagram shows a design where the Transmission class is an abstract class defining the changeGear(int gear) method, which is implemented by the ManualTransmission and AutomaticTransmission classes. The Vehicle class has a composition relationship with the Transmission class, represented by its transmission attribute, which is initialized through its constructor. The Vehicle class sends the changeGear(int gear) method to the Transmission object, allowing for different transmission methods (manual or automatic) to be used interchangeably, displaying polymorphism and encapsulation in the design. (www.linkedin.com, n.d.)
The following example shows an abstract class Bird with an abstract method move(), showing that all bird types must implement their own movement behavior. The FlyingBird class extends Bird and offers a concrete implementation of the move() method to represent flying behavior. Similarly, the Penguin class extends Bird and modifies the move() method to represent walking or swimming behavior. This design shows polymorphism, allowing different types of birds to define their specific movement behaviors while sharing a common interface.
(www.linkedin.com, n.d.)
In the following example there are two abstract classes, Drivable and Flyable, each having single abstract methods drive() and fly() respectively. The Car class implements Drivable, giving its own implementation of drive() for driving behavior specific to cars. Similarly, the Airplane class implements both Drivable and Flyable, describing its own versions of drive() and fly() for airplane-specific driving and flying functionalities. This structure illustrates how classes can extend abstract behaviors described in abstract classes, displaying the specialization of methods according to the type of vehicle they represent. (www.linkedin.com, n.d.)
In here the Singleton class uses the Singleton design pattern, ensuring that only one instance of the class can exist. There is a private static variable called _instance that holds the single instance, and a private constructor called _internal() that prevents direct creation. If it is, it uses the private constructor to create a new Singleton object and assigns it to _instance. If it is not null, it returns the current instance. This makes sure that getInstance() always gives the same instance, so there is only one shared object throughout the lifecycle of the app. (www.linkedin.com, n.d.)
In the example UML class diagram, the CarFactory class acts as a car factory's order system, generating certain types of cars depending on the CarType enum, which includes sedan, SUV, and hatchback. The Car abstract class defines a common drive method that is implemented by the Sedan, SUV, and Hatchback classes, each with its own driving behavior. The CarFactory's createCar function accepts a CarType and returns an instance of the appropriate car class. This approach enables for easy
extension with new car types by adding new classes and modifying the CarType enum and createCar function, which promotes code flexibility and maintainability. (www.linkedin.com, n.d.)