Higher Nationals Internal verification of assessment decisions – BTEC (RQF) INTERNAL VERIFICATION – ASSESSMENT DECISIONS Programme title Assessor Unit(s) Assignment title Student’s name BTEC Higher National Diploma in Computing - Software Engineering Mr. Akila Udara Akalanka Internal Verifier Unit 20: Applied Programming and Design Principles Sales Analysis System for Sampath Food City (PVT) Ltd J.K. Induwara Hasaranga / E236222 List which assessment criteria the Assessor has awarded. Pass Merit Distinction INTERNAL VERIFIER CHECKLIST Do the assessment criteria awarded match those shown in the assignment brief? Y/N Is the Pass/Merit/Distinction grade awarded justified by the assessor’s comments on the student work? Y/N Has the work been assessed accurately? Y/N Is the feedback to the student: Give details: • Constructive? • Linked to relevant assessment criteria? Y/N Y/N • Identifying opportunities for improved performance? Y/N • Agreeing actions? Y/N Does the assessment decision need amending? Y/N Assessor signature Date Internal Verifier signature Date Programme Leader signature(if required) Date Confirm actioncompleted Remedial action taken Give details: Assessor signature Date Internal Verifier signature Date Programme Leader signature (if required) Date 2 Assignment no 1 Applied Programming and Design Principles Higher Nationals - Summative Assignment Feedback Form Student Name/ID J.K. Induwara Hasaranga / E236222 Unit Title Unit 20: Applied Programming and Design Principles Assignment Number 01 Assessor 26/05/2025 Date Received 1st submission Submission Date Mr. Akila Udara Akalanka Date Received 2nd submission Re-submission Date Assessor Feedback: LO1. Investigate the impact of SOLID development principles on the OOP paradigm Pass, Merit & Distinction P1 P2 M1 D1 Descripts LO2. Design a large dataset processing application using SOLID principles and clean coding techniques Pass, Merit & Distinction Descripts P3 P4 M2 LO3. Build a data processing application based on a developed design Pass, Merit & Distinction P5 M3 Descripts LO4. Perform automatic testing on a data processing application Pass, Merit & Distinction P6 P7 M4 D2 Descripts Grade: Assessor Signature: Date: Assessor Signature: Date: Resubmission Feedback: Grade: Internal Verifier’s Comments: Signature & Date: * Please note that grade decisions are provisional. They are only confirmed once internal and external moderation has taken place and grades decisions have been agreed at the assessment board. 3 Assignment no 1 Applied Programming and Design Principles Assignment Feedback Formative Feedback: Assessor to Student Action Plan Summative feedback Feedback: Student to Assessor Assessor signature Date Student signature Date 4 Assignment no 1 Applied Programming and Design Principles Pearson Higher Nationals in Computing Unit 20: Applied Programming and Design Principles Assignment 01 General Guidelines 1. A Cover page or title page – You should always attach a title page to your assignment. Use previous page as your cover sheet and make sure all the details are accurately filled. 2. Attach this brief as the first section of your assignment. 3. All the assignments should be prepared using a word processing software. 4. All the assignments should be printed on A4 sized papers. Use single side printing. 5. Allow 1” for top, bottom , right margins and 1.25” for the left margin of each page. Word Processing Rules 1. The font size should be 12 point, and should be in the style of Time New Roman. 5 Assignment no 1 Applied Programming and Design Principles 2. Use 1.5 line spacing. Left justify all paragraphs. 3. Ensure that all the headings are consistent in terms of the font size and font style. 4. Use footer function in the word processor to insert Your Name, Subject, Assignment No, and Page Number on each page. This is useful if individual sheets become detached for any reason. 5. Use word processing application spell check and grammar check function to help editing your assignment. Important Points: 1. It is strictly prohibited to use textboxes to add texts in the assignments, except for the compulsory information. eg: Figures, tables of comparison etc. Adding text boxes in the body except for the before mentioned compulsory information will result in rejection of your work. 2. Carefully check the hand in date and the instructions given in the assignment. Late submissions will not be accepted. 3. Ensure that you give yourself enough time to complete the assignment by the due date. 4. Excuses of any nature will not be accepted for failure to hand in the work on time. 5. You must take responsibility for managing your own time effectively. 6. If you are unable to hand in your assignment on time and have valid reasons such as illness, you may apply (in writing) for an extension. 7. Failure to achieve at least PASS criteria will result in a REFERRAL grade . 8. Non-submission of work without valid reasons will lead to an automatic RE FERRAL. You will then be asked to complete an alternative assignment. 9. If you use other people’s work or ideas in your assignment, reference them properly using HARVARD referencing system to avoid plagiarism. You have to provide both in-text citation and a reference list. 10. If you are proven to be guilty of plagiarism or any academic misconduct, your grade could be reduced to A REFERRAL or at worst you could be expelled from the course. 11. If you are proven to be guilty of plagiarism or any academic misconduct, your grade could be reduced to A REFERRAL or at worst you could be expelled from the course. 6 Assignment no 1 Applied Programming and Design Principles Student Declaration I hereby, declare that I know what plagiarism entails, namely to use another’s work and to present it as my own without attributing the sources in the correct way. I further understand what it means to copy another’s work. 1. I know that plagiarism is a punishable offence because it constitutes theft. 2. I understand the plagiarism and copying policy of the Pearson UK. 3. I know what the consequences will be if I plagiaries or copy another’s work in any of the assignments for this program. 4. I declare therefore that all work presented by me for every aspects of my program, will be my own, and where I have made use of another’s work, I will attribute the source in the correct way. 5. I acknowledge that the attachment of this document signed or not, constitutes a binding agreement between myself and Pearson, UK. 6. I understand that my assignment will not be considered as submitted if this document is not attached to the attached. Student’s Signature: induhasaranga@gmail.com (Provide E-mail ID) 7 Assignment no 1 Date:26/05/2025 (Provide Submission Date) Applied Programming and Design Principles Assignment Brief Student Name /ID Number J.K. Induwara Hasaranga / E236222 Unit Number and Title Unit 20: Applied Programming and Design Principles Academic Year 2022/2023 Unit Tutor Mr. Akila Udara Akalanka Assignment Title Sales Analysis System for Sampath Food City (PVT) Ltd Issue Date 26/04/2025 Submission Date 26/05/2025 IV Name & Date Submission Format: Part 1. Report- Submit a professional report with appropriate report formatting and guidelines followed. All the research data should be referenced along with in-text citations using the Harvard referencing system. Part 2 A fully functional standalone software system (command-line interface based) Unit Learning Outcomes: LO1 Investigate the impact of SOLID development principles on the OOP paradigm. LO2 Design a large dataset processing application using SOLID principles and clean coding techniques. LO3 Build a data processing application based on a developed design. LO4 Perform automatic testing on a data processing application. 8 Assignment no 1 Applied Programming and Design Principles Assignment Brief and Guidance: Assignment Brief Scenario. ‘Data Labs’ is a leading software development company in Sri Lanka. They are focusing on helping businesses to build their businesses through creative and effective solutions. Assume that you work as an apprentice software developer for Data Labs company. As a part of your role, you have been asked to develop a software system (command-line interface based) for the following scenario using python programming language. Sampath Food City (PVT) Ltd is one of the main supermarket networks in Sri Lanka. Currently, Sampath Food City has several branches island wide. At present, transactions of each branch are recorded through a point of sale (pos) system. At the end of each month, recorded data of each point of the sales system are transferred to a centralized database. Top-level management of the company use the centralized data to do the monthly sales data analysis of the whole company at the end of the month to find insights to take managerial decisions for the company. Currently, the company uses a paper-based manual system to do monthly sales data analysis. Some weaknesses and drawbacks that have occurred in the manual system such as human errors leading to inaccurate information, time consuming, data redundancy, inconsistency and difficulty to find insights affect the business performance negatively. Therefore, the management of Sampath Food City has decided that using a customized software system for sales data analysis is the solution for eliminating above mentioned weaknesses and drawbacks of the existing sales data analysis process. Assume yourself as a software developer of Data Labs (PVT) Ltd and assigned to develop a sales data analysis system (command-line interface based) using python programming language for scenario given above. New system should provide following features: 9 Assignment no 1 Applied Programming and Design Principles • Monthly sales analysis of each branch. • Price analysis of each product • Weekly sales analysis of supermarket network • Product preference analysis • Analysis of the distribution of total sales amount of purchases Develop a command-line interface-based solution for the above scenario and produce a report covering the following tasks. Activity 1 • Investigate the characteristics of the object-orientated paradigm, including class relationships (inheritance, association, composition, aggregation) and evaluate the impact pf SOLID principles (single responsibility principle, open/closed principle, Liskov’s substitution principle, interface segregation principle and dependency inversion principle) by taking suitable examples incorporating UML diagrams and coding samples. Your answer should include suitable examples to evaluate the impact of SOLID principles in Object oriented Development. • Explain how clean coding techniques can impact on the use of data structures and operations when writing algorithms by taking suitable examples from the given scenario. Analyse each of the creational, structural and behavioral design patterns with relevant examples. Activity 2 • Design a large data set processing application, utilising SOLID principles, clean coding techniques, a design pattern and data structures by providing justifications for selected design pattern and selected data structures. • Design a suitable testing regime for the application developed with a provision for automated testing, selected test types and selected automatic testing tools, and provide justifications for the selections. Refine the design to include multiple design patterns by justifying the reasons for the inclusion of each design pattern for the given scenario. Activity 3 10 Assignment no 1 Applied Programming and Design Principles Build a large dataset processing application based on the design produced, by using python programming language and provide evidence for the usage of data structures and file handling techniques. Your answer must include an assessment of how effective the use of SOLID principles, clean coding techniques and programming patterns on the application developed. Take suitable examples from the developed application to elaborate your answer. Activity 4 • Examine the benefits and drawbacks of different methods of automatic testing of applications and software systems available for automatic testing by taking examples from the developed application. Provide an action plan to address the identified drawbacks of testing of the developed application. • Implement automatic testing of the developed application by using selected testing tools and provide evidence for the automatic testing. Discuss how developer-produced and vendor-provided automatic testing tools differ for applications and software systems by taking suitable examples from the testing of the developed application. 11 Assignment no 1 Applied Programming and Design Principles Grading Rubric Grading Criteria Achieved Feedback LO1 Investigate the impact of SOLID development principles on the OOP paradigm. P1 Investigate the characteristics of the object orientated paradigm, including class relationships and SOLID principles. P2 Explain how clean coding techniques can impact on the use of data structures and operations when writing algorithms. M1 Analyse, with examples, each of the creational, structural and behavioral design pattern types. D1 Evaluate the impact of SOLID development principles on object orientated application development. LO2 Design a large dataset processing application using SOLID principles and clean coding techniques. P3 Design a large data set processing application, utilising SOLID principles, clean coding techniques and a design pattern. P4 Design a suitable testing regime for the application, including provision for automated testing. M2 Refine the design to include multiple design patterns. LO3 Build a data processing application based on a developed design 12 Applied Programming and Design Principles Assignment no 1 P5 Build a large dataset processing application based on the design produced. M3 Assess the effectiveness of using SOLID principles, clean coding techniques and programming patterns on the application developed. LO4 Perform automatic testing on a data processing application. P6 Examine the different methods of implementing automatic testing as designed in the test plan. P7 Implement automatic testing of the developed application. M4 Discuss the differences between developer-produced and vendor-provided automatic testing tools for applications and software systems. D2 Analyse the benefits and drawbacks of different forms of automatic testing of applications and software systems, with examples from the developed application. 13 Applied Programming and Design Principles Assignment no 1 pg. 1 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles OBSERVATION RECORD Learner name: Qualification: Unit number & title: Description of activity undertaken Assessment criteria How the activity meets the requirements of the assessment criteria Learner name: Learner signature: Date: Assessor name: Assessor signature: Date: pg. 1 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles WITNESS STATEMENT Learner name: Qualification: Unit number & title: Description of activity undertaken (please be as specific as possible) Assessment criteria (for which the activity provides evidence) How the activity meets the requirements of the assessment criteria, including how and where the activity took place Witness name: Witness signature: Job role: Date: Learner name: Learner signature: Date: Assessor name: Assessor signature: Date: pg. 2 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Acknowledgment I would like to thank Mr.Akila Udara Akalanka for his helpful guidance, advice, & support during this assignment. I am also grateful to the everyone who helped in the completing it. Their feedback & encouragement were important in the improving the result. Contents OBSERVATION RECORD ............................................................................................... 1 WITNESS STATEMENT .................................................................................................. 2 Acknowledgment .................................................................................................................................................... 3 Executive Summary ................................................................................................................................................ 6 Object Oriented Programming ................................................................................................................................ 7 SOLID Principles ................................................................................................................................................. 30 Relationship Between SOLID Principles and OOP in Programming ................................................................... 38 Clean Code Technique.......................................................................................................................................... 44 Design Patterns ..................................................................................................................................................... 52 Use Case Diagrams for the Scenario .................................................................................................................... 76 Class Diagram for the Scenario ............................................................................................................................ 77 Entity Relationships Diagram for the Scenario .................................................................................................... 78 Use Of Solid Principles ........................................................................................................................................ 79 Selected Design Pattern (Facade Pattern) ............................................................................................................. 80 Selected Data Structure (Array) ............................................................................................................................ 81 Refining the Design (Multiple Design Patterns) ................................................................................................... 82 Justification of Design Choices for the Sales Data Analysis System ................................................................... 83 Test Case .............................................................................................................................................................. 84 Building and Implementing the Sales Data Analysis System ............................................................................... 90 The Benefits & Drawbacks of Automated Testing ............................................................................................. 102 Automated Testing Used Tools - Pytest and Unittest ........................................................................................ 105 Action Plan ......................................................................................................................................................... 107 Developer-Based Automated Testing Tools ....................................................................................................... 110 Vendor-Based Automated Testing Tools ........................................................................................................... 112 Reference list ...................................................................................................................................................... 115 Figure 1 Principles of OOPs Concepts ........................................................................... 7 Figure 2 Example ................................................................................................ 11 Figure 3 output ................................................................................................... 11 Figure 4 UML Class Diagram Representation ................................................................. 11 Figure 5 Example ................................................................................................ 13 Figure 6 Output .................................................................................................. 13 pg. 3 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Figure 7 UML Class Diagram Representation...................................................................................................... 13 Figure 8 Syntax..................................................................................................................................................... 14 Figure 9 Example.................................................................................................................................................. 15 Figure 10 output ................................................................................................................................................... 15 Figure 11 UML Class Diagram Representation.................................................................................................... 16 Figure 12 Example................................................................................................................................................ 17 Figure 13 Output................................................................................................................................................... 18 Figure 14 UML Class Diagram Representation.................................................................................................... 18 Figure 15 Code Example ...................................................................................................................................... 19 Figure 16 UML Class Diagram Representation.................................................................................................... 20 Figure 17 Code Example ...................................................................................................................................... 21 Figure 18 UML Class Diagram Representation.................................................................................................... 22 Figure 19 Code Example ...................................................................................................................................... 23 Figure 20 UML Class Diagram Representation.................................................................................................... 24 Figure 21 Code Example ...................................................................................................................................... 25 Figure 22 UML Class Diagram Representation.................................................................................................... 26 Figure 23 SOLID Principles ................................................................................................................................. 30 Figure 24 Java Code Example for SRP ................................................................................................................ 31 Figure 25 UML Class Diagram for SRP ............................................................................................................... 32 Figure 26 Java Code Example for OCP ................................................................................................................ 33 Figure 27 UML Class Diagram for OCP .............................................................................................................. 33 Figure 28 Java Code Example for LSP ................................................................................................................. 34 Figure 29 UML Class Diagram for LSP ............................................................................................................... 35 Figure 30 Java Code Example for ISP .................................................................................................................. 36 Figure 31 UML Class Diagram for ISP ................................................................................................................ 36 Figure 32 Java Code Example for DIP ................................................................................................................. 37 Figure 33 UML Class Diagram for DIP ............................................................................................................... 38 Figure 34 Single Responsibility Principle Code Example .................................................................................... 39 Figure 35 Open/Closed Principle (OCP) Code Example ...................................................................................... 40 Figure 36 Liskov Substitution Principle (LSP) Code Example ............................................................................ 41 Figure 37 Interface Segregation Principle (ISP) Code Example .......................................................................... 42 Figure 38 Dependency Inversion Principle (DIP) Code Example ........................................................................ 43 Figure 39 Example from the code......................................................................................................................... 46 Figure 40 Example from the code......................................................................................................................... 47 Figure 41 Example from the code......................................................................................................................... 48 Figure 42 Example from the code......................................................................................................................... 48 Figure 43 Java Code Example for Singleton Pattern ............................................................................................ 56 Figure 44 Java Code Example for Factory Method Pattern .................................................................................. 57 Figure 45 Java Code Example for Abstract Factory Pattern ................................................................................. 58 Figure 46 Java Code Example for Abstract Factory Pattern ................................................................................. 59 Figure 47 Java Code Example for Builder Pattern ............................................................................................... 60 Figure 48 Java Code Example for Builder Pattern ............................................................................................... 61 Figure 49 Java Code Example for Prototype Pattern ............................................................................................ 62 Figure 50 Java Code Example for Adapter Pattern............................................................................................... 63 Figure 51 Java Code Example for Adapter Pattern............................................................................................... 64 Figure 52 Java Code Example for Bridge Pattern ................................................................................................ 65 Figure 53 Java Code Example for Bridge Pattern ................................................................................................ 65 Figure 54 Java Code Example for Composite Pattern .......................................................................................... 66 Figure 55 Java Code Example for Composite Pattern .......................................................................................... 67 Figure 56 Java Code Example for Decorator Pattern ........................................................................................... 68 Figure 57 Java Code Example for Decorator Pattern ........................................................................................... 68 Figure 58 Java Code Example for Facade Pattern ................................................................................................ 69 Figure 59 Java Code Example for Observer Pattern ............................................................................................. 70 Figure 60 Java Code Example for Observer Pattern ............................................................................................. 71 Figure 61 Java Code Example for Strategy Pattern .............................................................................................. 72 Figure 62 Java Code Example for Command Patter ............................................................................................. 73 Figure 63 Java Code Example for Command Patter ............................................................................................. 73 Figure 64 Java Code Example for State Pattern ................................................................................................... 74 Figure 65 Java Code Example for Iterator Pattern ................................................................................................ 75 Figure 66 Use Case Diagrams .............................................................................................................................. 76 pg. 4 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Figure 67 Class diagram ....................................................................................................................................... 77 Figure 68 Entity Relationships Diagram .............................................................................................................. 78 Figure 69 Sales Data Analysis System Code ........................................................................................................ 90 Figure 70 Sales Data Analysis System Code ........................................................................................................ 91 Figure 71 Sales Data Analysis System Code ........................................................................................................ 91 Figure 72 Sales Data Analysis System Code ........................................................................................................ 92 Figure 73 Sales Data Analysis System Code ........................................................................................................ 92 Figure 74 Sales Data Analysis System Code ........................................................................................................ 93 Figure 75 Sales Data Analysis System Code ........................................................................................................ 93 Figure 76 Sales Data Analysis System Code ........................................................................................................ 94 Figure 77 Total Sales by Branch Chart ................................................................................................................. 95 Figure 78 Total Sales by Product Chart ................................................................................................................ 96 Figure 79 Sales Trend Over Time Chart ............................................................................................................... 97 Figure 80 Product Preference Analysis Chart ....................................................................................................... 98 Figure 81 Sales Distribution by Payment Methos Chart....................................................................................... 99 Figure 82 Pytest Testing Result .......................................................................................................................... 106 Figure 83 Unittest Testing Result ....................................................................................................................... 107 Table 1 Advantages of Object-Oriented Programming .......................................................................................... 8 Table 2 Disadvantages of Object-Oriented Programming ...................................................................................... 9 Table 3 Advantages and Disadvantages of Class Relationships. .......................................................................... 29 Table 4 Advantages and Disadvantages of SOLID Principles.............................................................................. 43 Table 5 Advantages and Disadvantages of Clean Coding Techniques . ............................................................... 50 Table 6 Test Case 1 - Monthly Sales Analysis for Each Branch .......................................................................... 84 Table 7 Test Case 2 - Price Analysis of Each Product.......................................................................................... 85 Table 8 Test Case 3 - Weekly Sales Analysis for the Supermarket Network ....................................................... 85 Table 9 Test Case 4 - Product Preference Analysis .............................................................................................. 85 Table 10 Test Case 5 - Analysis of Sales Amount Distribution ........................................................................... 86 Table 11 Test Case 6 - Data Handling for Missing Values .................................................................................. 86 Table 12 Comparison Table................................................................................................................................ 114 pg. 5 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Executive Summary The particular focus of this assignment is to discuss the need and advantages of automated testing tools in software development particularly from the point of view of developer based and vendor based tools. Automated testing tools play an important role within a Sales Data Analysis System, where systems must be reliable, accurate and performant in order to succeed in a data driven application. Automated testing tools on developer based technology is highly flexible, highly customizable and highly cost effective. Pytest, JUnit, like any other test tool, enable developers to write very highly specific and tailored test case that is very particular to their application. They also fit fairly well into existing CI/CD pipelines while providing complete control on test design, execution. Unfortunately, the benefit comes with a trade-off in complexity and the requirement for a strong programming skill set (along with a longer setup time over vendor based tools). In contrast, the user interface of vendor based automated testing tools like Micro Focus UFT and TestComplete is intuitive. Teams with little coding experience will love these tools because they pack almost all the features you can expect from a basic test management tool like test management, reporting and support. Licensing costs and sometimes lack of flexibility and customization that one can get with developer based tools combine with these tools to reduce development time considerably. The analysis of SOLID principles, clean coding and employ of design patterns is also performed while creating a resilient and maintainable Sales Data Analysis System through the assignment. If further, the importance of modular design and following best coding practices to build the system in a scalable, flexible way is demonstrated. Lastly, the action plan outlines how we mitigated potential drawbacks of the system at the system level (e.g., it reduced system complexity through modularity), as well as subsystems by having fallback mechanisms (i.e., manual analysis as a fallback) in place in the case of failures. pg. 6 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Object Oriented Programming Object-oriented programming is a programming paradigm, or classification, that organizes a group of data attributes with functions or methods into a unit, known as an object. Typically, OOP languages are class-based, meaning a class defines the data attributes and functions as a blueprint for creating objects, which are instances of the class. One class may represent multiple independent objects, which interact with each other in complex ways. Popular classbased programming languages include Java, Python and C++.(Herrity, 2023) Principles of OOPs Concepts Object oriented programming paradigm is characterized by the following principles , ➢ Class ➢ Object ➢ Encapsulation ➢ Inheritance ➢ Polymorphism Figure 1 Principles of OOPs Concepts pg. 7 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Advantages and Disadvantages of Object-Oriented Programming (OOP) Advantages of Object-Oriented Programming Table 1 Advantages of Object-Oriented Programming Advantage Description Encapsulation Data and methods are bundled together in classes, hiding implementation details and providing a clear interface. This leads to better data security and reduces complexity. Abstraction OOP allows programmers to focus on high-level functionalities without worrying about low-level details, making it easier to work with complex systems. Inheritance Enables code reuse by allowing a new class to inherit properties and methods from an existing class. This leads to more efficient code maintenance and avoids redundancy. Polymorphism Objects of different classes can be treated as objects of a common superclass. This allows for flexibility in the code, enabling different methods to be called in the same way. Code Reusability Through inheritance, polymorphism, and encapsulation, OOP promotes reusing code, reducing the need for duplication and improving overall efficiency. Modularity Programs are divided into objects, which can be developed and tested independently. This modularity simplifies debugging and maintenance. Flexibility and OOP allows for easy modification and extension of existing code, Scalability making it easier to scale and add new features to a program without altering the existing codebase. Maintainability With clear class definitions, easy-to-understand data structures, and reusable components, OOP helps improve code maintainability over time. Improved OOP encourages collaboration among developers by allowing them Collaboration to work on different objects or classes without interfering with each other’s code. pg. 8 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Improved Security Encapsulation and access control mechanisms ensure that sensitive data is protected and that objects can only be accessed in a controlled manner. Disadvantages of Object-Oriented Programming Table 2 Disadvantages of Object-Oriented Programming Disadvantage Description Complexity OOP can be more complex to design and implement, especially for smaller programs. The overhead of creating classes, objects, and defining relationships can be time-consuming and difficult to manage. Performance The use of objects, methods, and inheritance can lead to additional Overhead memory usage and slower execution, especially for simple tasks that don’t require such structure. Steep Learning Curve OOP requires a good understanding of concepts like inheritance, polymorphism, and encapsulation, which can be difficult for beginners to grasp, leading to a longer learning period. Large Codebase OOP systems can result in a large codebase due to the number of classes, methods, and objects involved, which may make the system harder to navigate and maintain over time. Overhead in Developing an OOP system can take more time than using simpler Development Time programming paradigms due to the need to define classes, design object relationships, and write additional code to handle objects and their interactions. Excessive Sometimes, the attempt to design a highly reusable and Generalization generalized system can lead to overly abstract code that is harder to maintain or extend because of unnecessary complexity. Increased Usage Memory Storing data in objects and maintaining object states can lead to increased memory consumption, especially in large-scale applications with many instances of classes. pg. 9 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Difficulty in Some algorithms or problem-solving approaches may not map Implementing Certain well to an object-oriented approach, leading to less efficient or Algorithms more complex code. Tight Coupling Although OOP encourages modularity, objects can become tightly coupled if not properly designed, making the system difficult to maintain and extend over time. Not Ideal for Simple For small-scale applications or simple tasks, the OOP approach Programs may be overkill and result in unnecessary complexity when simpler procedural programming could suffice. Class & Object A class is an user-defined prototype for an object that defines a set of attributes that characterize any object of the class. The attributes are data members (class variables and instance variables) and methods, accessed via dot notation. An object refers to an instance of a certain class. For example, an object named obj that belongs to a class Circle is an instance of that class. A unique instance of a data structure that is defined by its class. An object comprises both data members (class variables and instance variables) and methods. (www.tutorialspoint.com, n.d.) Example The below example illustrates how to create a class and its object in Python. pg. 10 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Figure 2 Example On executing the above code, it will display the following output , Figure 3 output Figure 4 UML Class Diagram Representation pg. 11 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles The example below creates a class and then makes an object from it in Python. There is a class Smartphone with a constructor called __init__ that saves device and brand as the instance variables self.device and self.brand after receiving them as parameters. Besides, there is a description() method that creates a string with the device’s name and brand. Then, the object phoneObj is made from the Smartphone class and we assign “Smartphone” and “Samsung” to its constructor parameters. When description() is called on phoneObj, the values of device and brand from before are combined to print “Smartphone of Samsung supports Android 14”. With these examples, we show the main ideas around defining classes, building objects and using methods in Python. Class Relationships in Object-Oriented Programming (OOP) OOP is based on classes and how they relate to one another. A class is used to design objects (instances) and class connections explain how these classes are linked. Read on to find out about the principal class relationships in OOP. Encapsulation Data members of class are available for processing to functions defined within the class only. Functions of class on the other hand are accessible from outside class context. So, object data is hidden from environment that is external to class. Class function (also called method) encapsulates object data so that unwarranted access to it is prevented. (www.tutorialspoint.com, n.d.) Example In this example, we are using the concept of encapsulation to set the price of desktop. pg. 12 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Figure 5 Example When the above code is executed, it produces the following result, Figure 6 Output Figure 7 UML Class Diagram Representation This code example depicts how encapsulation is done in Python. The Desktop class is defined by two variables: a constructor (__init__) and two functions: sell() and set_max_price(). The pg. 13 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles sell() function gives the value of the_max_price attribute which is how much the desktop is being sold for. Using set_max_price() modifies the_max_price variable. In the example, an instance desktopObj is made from the Desktop class and its selling price is shown using the sell() method. After that, the setter method set_max_price() is called to give the price 35,000 and its value is updated and printed out at once. The program shows encapsulation by making sure methods handle how cehak the max_price attribute is accessed and changed safely. At first, my code shows “Selling Price : 25000” and changes it to “Selling Price : 35000” once the user enters a new price. Inheritance A software modelling approach of OOP enables extending capability of an existing class to build new class instead of building from scratch. In OOP terminology, existing class is called base or parent class, while new class is called child or sub class. Child class inherits data definitions and methods from parent class. This facilitates reuse of features already available. Child class can add few more definitions or redefine a base class function. (www.tutorialspoint.com, n.d.) Syntax Derived classes are declared much like their parent class, however, a list of base classes to inherit from is given after the class name, Figure 8 Syntax Example The following example demonstrates the concept of Inheritance in Python , pg. 14 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Figure 9 Example When the above code is executed, it produces the following result, Figure 10 output pg. 15 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Figure 11 UML Class Diagram Representation Here, inheritance in Python is shown through the relationship of Child and Parent. In the constructor, the parent class sets up its attribute parentAttr to start at 100 and has methods parentMethod() and setAttr() to manage it. The child class takes the parent class’s methods and adds both a new method and a constructor of its own. A child object called c is formed and both types of methods are called on it as one after another. Initially, it shows that the child’s constructor and method are executed. It then calls the parent’s method first directly and again after the parentAttr is set to 200. The console displays: “Calling child constructor,” “Calling child method,” “Calling parent method,” and finally, “Parent attribute: 200” when the parent’s attribute is changed in the child class. This explains that inheritance makes it possible for a class to inherit behavior from its parent and also change it. Similar way, you can drive a class from multiple parent classes as follows, pg. 16 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles You can use issubclass() or isinstance() functions to check a relationships of two classes and instances. • The issubclass(sub, sup) boolean function returns true if the given subclass sub is indeed a subclass of the superclass sup. • The isinstance(obj, Class) boolean function returns true if obj is an instance of class Class or is an instance of a subclass of Class Polymorphism Polymorphism is a Greek word meaning having multiple forms. In OOP, polymorphism occurs when each sub class provides its own implementation of an abstract method in base class. You can always override your parent class methods. One reason for overriding parent’s methods is because you may want special or different functionality in your subclass. (www.tutorialspoint.com, n.d.) Example In this example, we are overriding the parent’s method. Figure 12 Example When the above code is executed, it produces the following result, pg. 17 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Figure 13 Output Figure 14 UML Class Diagram Representation This code shows polymorphism in Python by having the class’s method override the parent’s one. The parent class features myMethod() which displays the message “Calling parent method.” Because the child class inherits from the parent class, it replaces the virtual method with its own and this new version writes “Calling child method” when it’s called. If an object c of the child class is made and c.myMethod() is called, the overridden method in the child class is executed and prints “Calling child method” in the result. Polymorphism takes place here, since the child’s type decides how the method will behave, even though it was defined by the parent class. Association in object oriented programming Association, in OOP, is the link between different classes of objects that connect them. It shows how objects communicate, even though this doesn’t mean they are owned and fully linked. Basically, association means how objects are connected or related to one another. Let’s say a Library and its Books. Depending on the situation, each Book is tied to its Library, but they are independent from one another. pg. 18 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles There are situations where association runs from a to b and others, where it goes from b to a. In this association type, only one object is aware of the other is not aware of it. When objects are linked in a bidirectional association, each knows about the other. For instance, a Teacher might have several Students and there are situations where a Teacher and a Student already know each other. We will use Python to show an example where a Library and Book are linked. Even though the Library has many Books, that doesn’t always mean the Books themselves know where to find the Library. We define the relationship in Python like this, Figure 15 Code Example In this Python code, The Book class represents is individual books, with attributes like title & author. The Library class represents is the library, which contains a list of the Book objects. The add_book method adds a book to the library, & list_books prints all books in the library. pg. 19 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles UML Class Diagram Representation Association can be used in a UML Class Diagram to connect a Library with Books. With many Books to a single Library, the match is one-to-many. One Library object corresponds to multiple Book objects, with each Book independent as well. Figure 16 UML Class Diagram Representation In this UML diagram, The Library class is associated with many Book objects, shown by the “1” (one) on the Library side & “ * ” (many) on the Book side. The arrow indicates that a Library has many Books, which is a typical one to many association. Aggregation in Object-Oriented Programming Within OOP, aggregation is a kind of association that means a class may contain objects from another class. What matters most in aggregation is that the container object does not control whether the contained objects remain. In other words, when a container object is gone, the contained objects may still remain active. If we look at the example of a Department and Employee relationship, etc... Departments have many Employees, but if a department is no longer active, those Employees are free to work for a new department or operate outside the original department. pg. 20 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles There isn’t a big difference between aggregation and composition. Aggregation is like a “hasa” tie where the presented object remains operationally alive regardless of the container object, in contrast to composition, where the contained object’s lifetime depends on the container object. Python Code Example I’ll show you what aggregation looks like in Python. We’ll design a Department class and an Employee class. There are many Employees in a Department, but they can exist by themselves. Figure 17 Code Example The Employee class in Python describes a person’s name and role. The Department class stores a group of Employee objects as part of a department. Adding an employee to the department is done through add_employee and display_employees shows a list of all employees assigned there. UML Class Diagram Representation Aggregation is shown in a UML Class Diagram with a hollow diamond on the side of the container object. This means that the Department class looks like a hollow diamond from the pg. 21 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Employeeclass, showing that employees can be assigned to departments, not the other way round. Figure 18 UML Class Diagram Representation In the diagram, The hollow diamond on the Department class indicates that Department aggregates Employee. The 1 and * symbols indicate that one Department can have many Employees, but the Employee can exist independently outside the Department. Composition in Object Oriented Programming In Object-Oriented Programming (OOP), composition acts like a more powerful form of association because it uses the “has-a” pattern, just like aggregation, but with the difference that the items inside are kept alive only as long as their container stays alive. Once the container destroys itself, the objects held inside are destroyed too. Because of this, the part is entirely dependent on and connected to the whole. We could use a Room and House relationship as an example. Rooms are part of a House and if the House goes away, all the Rooms do as well. At its core, composition works so that rooms are firmly linked to the house and must finish when the house is finished. Composition is most commonly applied when the components must be present inside the container and if the container is destroyed, its components should be as well. pg. 22 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Python Code Example Here’s an example of composition in Python. The House class will hold several Room objects. Should the House be destroyed, its Rooms will surely be destroyed too. Figure 19 Code Example Here, The Room class models what each individual room in the house looks like. All Rooms are stored in the House object’s list and the rooms can be created using the add_room() method. Composition is shown when the Room objects disappear when the House object is broken since they are strongly connected. UML Class Diagram Representation To show composition in a UML Class Diagram, use a filled diamond next to the container (whole) object. In our model, the diamond in the House class, pointing towards Room, indicates that rooms are essential parts of a house. pg. 23 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Figure 20 UML Class Diagram Representation In the diagram, The filled diamond on the House class indicates that House contains Room objects in a composition relationship. The 1 and * symbols indicate that one House can contain many Rooms, and the Room objects cannot exist without the House. Inheritance in Object Oriented Programming In OOP, inheritance is about a class (subclass) obtaining the properties and behaviors (methods) of a parent class by simply being created from it. As a result, the child class can use, add to or modify the abilities of its parent class. Having inheritance reduces repeated code which makes the code more organized and simple to manage. OOP relies on inheritance to create systems of hierarchical classification. The parent class outlines the basics, but the child class can get those same features and introduce its own addition features. This ensures that whatever happens to parent class is also possible with the child class, by using “ is-a.” A vehicle class might be created as the parent and car and truck classes can inherit everything from the vehicle class. Children classes are able to define their own characteristics (such as pg. 24 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles number of wheels and type of fuel) yet also share identical actions (commonly starting their engine and driving). Python Code Example Let’s have a look at some Python code to show what inheritance means. Our setup will have a parent class Vehicle with children Car and Truck. They will also get the parent’s properties and methods and also add particular behaviors that belong only to them. Figure 21 Code Example The Vehicle class is the main class in Python, and it contains the usual make and model properties, along with a method for starting the engine. The Car and Truck classes are children of the Vehicle class. Using super(), child classes are able to reference and execute the creator method (__init__()) of the parent class. Car has the method honk(), and Truck has load_cargo() as its own specific method. The Vehicle class’ start_engine() method is copied into both the Car and Truck classes. pg. 25 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles UML Class Diagram Representation UML Class Diagram illustrates inheritance by having a line link the child class to the parent class and an empty triangle points away from the child and toward the parent. It means that the child class takes characteristics from the parent class. Car and Truck are derived from the Vehicle class, just as the diagram illustrates. Figure 22 UML Class Diagram Representation The diagram illustrates that inheritance is shown by the open triangle, so both Car and Truck classes get their properties from the Vehicle class. A Vehicle holds typical features such as make and model and starts the engine using the start_engine() method. Each Car and Truck class contains unique attributes and methods that give them more features than the parent class. Importance of Class Relationships in Object-Oriented Programming In Object-Oriented Programming (OOP), how classes interact, exchange data and manage duties depends greatly on their relationships. Understanding how these things relate is key to making systems that can grow, be maintained and be efficient. With OOP, the different relationships ensure components of the system can work together smoothly, are reusable and are adaptable. The reason for these relationships is important in everything from grouping code to boosting system toughness and adjustability. Let’s look at the main reasons why relationships between classes are significant in OOP. pg. 26 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles 1. Code Reusability Because of class relationships, especially through inheritance, the same code can be used more than once. Inheritance means that a subclass does not have to write the same code for properties and methods as its superclass. Developers can use the same functions in new classes, avoiding the copying of code and ensuring it is DRY (Don’t Repeat Yourself). For instance, in an ECommerce system, Product handles basic features for products and Clothing and Electronics inherit the basic functions and introduce their special features too. Thanks to this, code remains organized and simple to modify without repetition which improves the efficiency of the development process. 2. Modularity and Maintainability Objects are designed in modules because of class relationships in OOP. Dividing a system into classes means each class tackles a particular task. Being able to work on separate modules makes it possible for individual team members to build different important sections in a project. Also, dividing code by purpose makes it much simpler to maintain. It is usually possible to update a class without impacting other classes as long as the interfaces you use with them are unchanged. An example would be a library management system, where Book and Library communicate with each other through aggregation and Library’s core operations are still fine as long as their connection is straightforward. 3. Data Encapsulation and Abstraction It is very important to have class relationships to implement encapsulation and abstraction in OOP. The process of encapsulation is to bring data and the functions that work with that data into a single class. Relationships such as aggregation and composition assemble groups of objects, hiding any details of implementation. Because the object handles everything, developers don’t have to be concerned with small details from other groups of classes. If I build a Car class that includes Engine and Tires, the user will use Car functions like start() and stop(), not have to learn about the Engine in detail. 4. Flexibility and Scalability The system is able to respond to new changes because of its flexible and scalable class relationships. For example, inheritance allows you to quickly set up new classes that manage data in the same way as existing classes. It works best when adding new features to a program doesn’t mean you have to adjust every line of code. When your vehicle management system pg. 27 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles grows, by making subclasses based on a Vehicle class, you can easily add features that are unique to Trucks or even Motorcycles. Thanks to its flexibility, the system can adjust when new needs arrive and help the application continue to expand in the future. 5. Real-World Modeling Modeling real-life entities within software systems is made easier by recognizing suitable class relationships. When relationships between classes correspond to real-life actions, developers make systems easier for everyone to use. For example, in the management of a university, a student who takes part in multiple courses is linked to the Course class association of the Student class. It works in the same way as real universities which makes the system both simpler to visualize and explain to others outside of development. When this happens, business needs and technical development go hand in hand. 6. Code Collaboration and Separation of Concerns By having classes, development teams are better able to collaborate when working on large tasks. If all classes handle separate utilities, everyone can code their portions without affecting the others. An example would be that one of the developers improves the way payments are processed, whereas the other developer makes the user authentication process more secure. Dividing the system this way makes it possible to create parts in parallel and helps minimizes coding disagreements. Besides, when classes obey how they are connected, each class serves a specific role which results in better-structured code for everyone to see. 7. Improved Testing and Debugging One of the main benefits of OOP is it simplifies the ways to test and debug them. Each class is self contained and has well defined responsibilities and as such is easy to isolate classes for unit testing. As an example, a Payment class can be tested independently of the User class and the testing is focused with very high efficiency. In debugging, if there is some problem in some class, links between classes, clear as they are, make it easier for programmers to locate a bug. Using mocking or stubbing developers can test class behaviors in isolation which makes the whole testing process very structured and more reliable. Advantages and Disadvantages of Class Relationships. pg. 28 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Table 3 Advantages and Disadvantages of Class Relationships. Aspect Advantages Disadvantages Code Reusability Through inheritance, classes Overuse of inheritance can lead to can inherit common behaviors, tight coupling, making it harder to reducing code duplication. Modularity Class relationships modify or extend. enable Improper use of relationships may breaking down the system into result in excessive complexity and smaller, manageable difficult-to-manage code. components. Maintainability Changes to one class are easier If relationships are not well-defined, to implement without affecting updates to one class might require other parts of the system. Scalability modifications in others. Easier to extend the system by Deep inheritance hierarchies can adding new classes relationships without and make the system harder to scale and major introduce unexpected behavior. changes. Data Encapsulation hides data Over-encapsulation may make the Encapsulation details and exposes only the system more rigid and less adaptable necessary parts of a class. Flexibility to future changes. Class relationships allow the Misuse system to adapt to of polymorphism and new inheritance can lead to code that is too requirements by adding or generalized and hard to manage. modifying subclasses. Real-World Class relationships provide a Some real-world relationships may Modeling natural way to model real- not map well to OOP constructs, world entities and their leading to unnatural designs. interactions. Collaboration Developers can work on Too many relationships between different classes or modules classes can lead to interdependencies independently interfering with others. without that slow down collaboration and development. pg. 29 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Testing Debugging and Easier to isolate and test Complex relationships can make it individual classes, making harder to test and debug the system, debugging more efficient. especially in tightly coupled systems. SOLID Principles The SOLID principles are five essential guidelines that enhance software design, making code more maintainable and scalable. They include Single Responsibility, Open/Closed, Liskov Substitution, Interface Segregation, and Dependency Inversion. In this article, we’ll explore each principle with real-life examples, highlighting their significance in creating robust and adaptable software systems. These five principles are, (geeksforgeeks, 2019) 1. Single Responsibility Principle (SRP) 2. Open/Closed Principle 3. Liskov’s Substitution Principle (LSP) 4. Interface Segregation Principle (ISP) 5. Dependency Inversion Principle (DIP) Figure 23 SOLID Principles pg. 30 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles The SOLID principle helps in reducing tight coupling. Tight coupling means a group of classes are highly dependent on one another which you should avoid in your code. (geeksforgeeks, 2019) • Opposite of tight coupling is loose coupling and your code is considered as a good code when it has loosely coupled classes. (geeksforgeeks, 2019) • Loosely coupled classes minimize changes in your code, helps in making code more reusable, maintainable, flexible and stable. Now let’s discuss one by one these principles. (geeksforgeeks, 2019) Single Responsibility Principle This principle states that "A class should have only one reason to change" which means every class should have a single responsibility or single job or single purpose. In other words, a class should have only one job or purpose within the software system. (geeksforgeeks, 2019) An example is a class that takes care of user data and also sends emails. These are not the same and following SRP, each should be handled by a different class. Java Code Example for SRP Figure 24 Java Code Example for SRP pg. 31 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Here, UserManager violates SRP because it both saves the data and sends out emails. SRP recommends that the User class deals with things related to users, leaving email communication to a different class. UML Class Diagram for SRP Figure 25 UML Class Diagram for SRP This diagram shows how UserManager interacts with User, handling both responsibilities. In SRP, these responsibilities should be split into separate classes. Open/Closed Principle (OCP) This principle states that “Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification” which means you should be able to extend a class behavior, without modifying it. (geeksforgeeks, 2019) For instance, to make things clearer, we can work with a payment system. The system ought to be designed so that we don’t have to edit existing code to add more payment methods (such as PayPal, Credit Card). Instead, we could add extra classes for every type of payment. Java Code Example for OCP pg. 32 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Figure 26 Java Code Example for OCP Here, the Payment class is meant for all basic payment handling and the PayPalPayment and CreditCardPayment classes add extra features without affecting the base class. As a result, the OCP pattern is used because all the new payment methods are attached with extensions instead of being built into the core class. UML Class Diagram for OCP Figure 27 UML Class Diagram for OCP Here, Payment is the main class and both PayPalPayment and CreditCardPayment come from it. Therefore, the system can add new payments, but it is not changeable. pg. 33 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Liskov Substitution Principle (LSP) The principle was introduced by Barbara Liskov in 1987 and according to this principle "Derived or child classes must be substitutable for their base or parent classes". This principle ensures that any class that is the child of a parent class should be usable in place of its parent without any unexpected behaviour. (geeksforgeeks, 2019) For example, if we have a Shape class and its subclasses, like Rectangle and Square, both should be able to function correctly when used in place of a Shape object. Java Code Example for LSP Figure 28 Java Code Example for LSP In this case, Square does not follow LSP because changing the behavior when replacing a Square with a Rectangle is necessary. Substituting a Rectangle with a Square will lead to things not working as expected. UML Class Diagram for LSP pg. 34 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Figure 29 UML Class Diagram for LSP To put it simply, Shape is the parent, Rectangle is the child and so is Square. Still, Square isn't a real subtype because it lacks the Rectangle’s key qualities when degenerated. Interface Segregation Principle (ISP) This principle is the first principle that applies to Interfaces instead of classes in SOLID and it is similar to the single responsibility principle. It states that "do not force any client to implement an interface which is irrelevant to them". Here your main goal is to focus on avoiding fat interface and give preference to many small client-specific interfaces. You should prefer many client interfaces rather than one general interface and each interface should have a specific responsibility. (geeksforgeeks, 2019) For example, in a MultiFunctionDevice (printer, scanner), we should separate interfaces for Printing and Scanning, so a Printer does not need to implement scanning methods. Java Code Example for ISP pg. 35 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Figure 30 Java Code Example for ISP In this case, the PrinterDevice class only follows the ISP rule by supporting just the Printer interface. Both Printer and Scanner interfaces are implemented by the MultiFunctionDevice class to let clients take only the required features. UML Class Diagram for ISP Figure 31 UML Class Diagram for ISP In this case, Only the PrinterDevice from this diagram uses the Printer interface, but the MultiFunctionDevice implements both Printer and Scanner interfaces. pg. 36 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Dependency Inversion Principle (DIP) The Dependency Inversion Principle (DIP) is a principle in object-oriented design that states that "High-level modules should not depend on low-level modules. Both should depend on abstractions". Additionally, abstractions should not depend on details. Details should depend on abstractions. In simpler terms, the DIP suggests that classes should rely on abstractions (e.g., interfaces or abstract classes) rather than concrete implementations. This allows for more flexible and decoupled code, making it easier to change implementations without affecting other parts of the codebase. (geeksforgeeks, 2019) For example, if a Database class directly depends on a specific database implementation (e.g., MySQL), it violates DIP. Instead, we should have both high-level and low-level modules depend on an abstraction like an interface. Java Code Example for DIP Figure 32 Java Code Example for DIP pg. 37 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles In this case, the DatabaseClient class uses the abstract Database interface instead of the regular MySQLDatabase class. As a result, the system is adaptable, so high-level modules can be used with various databases. UML Class Diagram for DIP Figure 33 UML Class Diagram for DIP In this diagram, DatabaseClient depends on the Database interface, and MySQLDatabase implements the Database interface, adhering to DIP. Relationship Between SOLID Principles and OOP in Programming SOLID principles which are part of Object-Oriented Programming (OOP), help designers make software that is maintainable, scalable and flexible. Following the SOLID principles keeps the structure of classes, objects and their interactions suitable for extending, changing and testing software. Since each SOLID principle is connected to OOP ideas such as encapsulation, inheritance, polymorphism and abstraction, OOP becomes even better organized and powerful. Classes and objects form the basis of OOP and SOLID guidelines show how those classes are built and how they should relate to each other. As an example, the SRP helps ensure every class in a system is only concerned with one job which supports the OOP concept of breaking a pg. 38 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles program into modules. To OCP, it is now possible to introduce new features into a system by adjusting interfaces or subclasses which works with OOP’s inheritance and polymorphism. Example of Applying SOLID Principles in OOP Single Responsibility Principle (SRP) According to the SRP, a class should only change because of one type of reason. In other words, a class should concentrate on one task or function. When a class does too many jobs, it becomes tough to modify or maintain them. With SRP, a class remains focused on doing just one job which makes it both easier to manage and to extend. Figure 34 Single Responsibility Principle Code Example pg. 39 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles The UserManager class breaks SRP since it handles saving users and sending emails at the same time. Each of them should be taught as a distinct subject. In this case, the User class follows SRP by working with only user data. Open/Closed Principle (OCP) Open/Closed Principle (OCP) recommends that classes should be able to be adjusted using inheritance, without having to change their own code. Consequently, it is better to add new things to an existing class using inheritance or interfaces instead of directly modifying the original. With OCP and polymorphism, adding new behavior to a system does not disrupt anything that works already. Figure 35 Open/Closed Principle (OCP) Code Example We have a base class Payment that offers a method called processPayment(). Instead of changing Payment to handle several types of payment, we create subclasses such as PayPalPayment and CreditCardPayment. This is achieved following OCP by making the change in a new class and not in the original one. pg. 40 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Liskov Substitution Principle (LSP) LSP claims that an object from a superclass should act exactly as an object from its subclass does in the same type of program. In other words, a subclass should still work the same way as its parent class. Figure 36 Liskov Substitution Principle (LSP) Code Example Circle and Rectangle share a parent class, Shape and redefine the draw() method. Because objects of the Circle or Rectangle class behave exactly as the Shape objects, the LSP is followed. It will always function correctly, regardless of which subclass takes the parent’s role in the program. Interface Segregation Principle (ISP) The Principle of Interface Segregation says that no client needs to implement an interface it doesn’t require. Rather than having a generalized interface, it’s preferable to use a collection of smaller, specific ones. As a result, clients are able to address only what is most important for them. pg. 41 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Figure 37 Interface Segregation Principle (ISP) Code Example In our example, the Printer and Scanner interfaces are not related and each class uses only what it needs. So, the goal of ISP is met, so classes do not have to write extra or duplicated methods. One example is that the PrinterDevice class only fulfills the Printer interface, without meeting the Scanner interface, as scanning is unnecessary for it. Dependency Inversion Principle (DIP) According to DIP, high-level modules should not depend on low-level modules, all modules depend on abstractions (like interfaces). This results in modules that are not tightly connected, so the overall system is both flexible and easy to test. pg. 42 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Figure 38 Dependency Inversion Principle (DIP) Code Example Instead of attaching itself to MySQLDatabase, the DatabaseClient class links to the Database interface which is an abstraction. This part of the design helps DIP keep the database client free from the way the database is implemented. Advantages and Disadvantages of SOLID Principles Table 4 Advantages and Disadvantages of SOLID Principles Aspect Advantages Single Encourages modular design, where Over-segmentation can result in Responsibility each class has one responsibility, too Principle (SRP) making code easier to maintain and increasing the complexity of the understand. Disadvantages many small classes, system. Open/Closed Extends functionality Principle (OCP) modifying existing code, promoting in code that is harder to reusability and scalability. without Excessive abstraction may result understand or modify due to over-engineering. pg. 43 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Liskov Ensures behavioral consistency in Strict adherence to LSP can lead Substitution subclasses, promoting safe use of to overly rigid class hierarchies, Principle (LSP) inheritance. Interface Prevents large, unwieldy interfaces Too many small interfaces can Segregation by splitting them into smaller, more lead to fragmented designs and Principle (ISP) specific ones, making classes easier excessive boilerplate code. limiting flexibility. to implement and maintain. Dependency Promotes loose coupling and Initial setup Inversion flexibility by depending on complex, requiring additional Principle (DIP) abstractions instead of concrete layers of can be abstraction more and implementations, making systems interfaces, which can increase easier to test and modify. the development time. Clean Code Technique Clean Code refers to writing code that is simple to read, look after and grow. It gives developers the basis to make their code serve its purpose and also makes it easy to understand and organize. Tidying up your code means it’s simpler for developers to modify it or find out where things are going wrong. Making the code simple, fast and easy to maintain is the key purpose of having clean code. It works on making code easier to understand, read and follow. The idea of clean code is to produce code others can understand and use, without having to untangle confused or complicated areas. Developers who follow clean code methods can explain their code simply, lessen the chance of errors and cooperate with colleagues more easily. Simple designs are favored and the code is written so that it’s simple to test and refactor. Benefits of Clean Coding There are multiple positive results from writing clean code. To begin with, it makes maintaining the software easier. If your code is organized, making repairs or updates is far less likely to cause problems elsewhere. As a result, making new changes is less dangerous and more productive. Next, well-written code is far easier to follow. New members of the team can quickly learn from the code which makes working with others much easier. Additionally, pg. 44 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles cleaning up the code saves companies from having to re-pay technical debt. It is the extra effort that arises because developers take simple shortcuts rather than doing everything by the book. Better solutions and practices are motivated by clean code, so there is less to pay back slowly. Because of its cleanliness, code can be used and shared in multiple areas. Tidy and independent code can be used in other areas within the project or in external projects too. in the end, clean code helps a project grow. Clear and tidy code helps builders handle increasing system growth with better performance. Clean Coding Techniques • Meaningful Naming - Certain techniques will improve the quality of your code. Significant consideration for children’s names is called meaningful naming. Names of variables, functions and classes should be chosen to describe what they are used for. As an example, calling a variable totalAmount is easier to follow than calling it x. Using simple names allows developers to grasp the code without having to look at every detail. • Keeping Functions Small and Focused - Making functions both small and narrow in their focus is an important approach. Functions need to focus on just one duty and they must do it well. Because of this, the code becomes simpler to test, fix and understand. If we make our large function smaller and focused on only one job, the code will be easier to keep in order. • Avoiding Duplicate Code - Writing similar code only once is a good method to follow. Occurrences of the same code increase the risk of errors and make it difficult to keep the code up to date. Instead, look for ways to reuse the code by writing functions or classes which will help you avoid redundancy. Because only one file is needed, updates are relatively simple. • Commenting Appropriately - Also, you should always comment appropriately. Even though a well-named and structured program is enough, adding comments can describe the difficult or unusual parts of your code. At the same time, comments should not be inserted everywhere; they’re only helpful to explain your intentions in a part of code that isn’t clear. pg. 45 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles • Writing Automated Tests - On top of that, creating automated tests keeps the code clean and ensures it does its job. Using unit tests makes catching flaws early possible and safeguards the code from future problems. Writing code in a clean way leads teams to write tests together which helps build dependable and durable code. Impact on Data Structures and Algorithms - Clean Code Techniques and Their Effect on Data Structures The Sales Data Analysis System relies on NumPy arrays and using clean coding makes the system easier to read, maintain and operate efficiently. Taking care of code readability, short functions and adding explanatory comments and handling errors, makes using NumPy arrays and their algorithms much easier. As a result, the system works as planned, deals with large datasets smoothly and can grow with additional updates. 1. Meaningful Naming One of the most efficient methods to cleave is using meaningful names for variables, functions and classes. It guarantees that what the purpose is of the data structure, the main reason why you would want to use NumPy arrays, why you would want to use this particular data structure for this particular task. In the Sales Data Analysis System, we use NumPy arrays to store our data in variables, branch_sales, total_sales and quantity_sold, therefore it becomes clearer what each variable is for. For example, in branch total sales code listed above, Figure 39 Example from the code This tells us now that branch_sales is the variable where we have the total sales info for each branch. These good named functions are so descriptive in meaning that we don’t need comments or anything to explain it, we can guess its logic by simply reading the function name. Impact pg. 46 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles • Improved Readability - Developers can easily grasp what the NumPy array stores and how that storage will be used in the algorithm. • Better Maintainability - Updated easily and modified code can easily be understood when variables can easily tell their purpose. 2. Small Functions Clean code points out that it is best to write functions that perform only one task clearly. It is very helpful when working with NumPy arrays since it makes it possible to handle complex algorithms step by step. With the Sales Data Analysis System, the analyze_sales_by_branch() function only takes care of examining and displaying sales by branch. Figure 40 Example from the code The more centered and small your module is, the easier it will be to assess, solve issues and expand it. In case we want to update the sales analysis or add more types, we won’t affect the rest of the system. Impact • Improved Efficiency - When functions are small, each can be examined and improved more easily. • Easier Debugging - Problems are easier to find when everything is grouped together in a function. • Better Algorithm Design - If functions are clear and concise, algorithms are designed in a better way and become easier to enhance. 3. Comments pg. 47 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Though most of the time, code should be clear on its own, at times it needs comments to break down harder to follow logic. The use of comments in Sales Data Analysis System helps future developers will easily know what results are expected from each array operation. For example, Figure 41 Example from the code The comment notes that this operation categorizes the data by branch_id and adds up the sales per branch. Often, a beginning developer can take more time to get used to the process if there is no comment. Impact • Enhanced Clarity - Comments in code ensure the purpose of difficult code lines is clearer which makes explanations easier. • Faster Debugging - Comments allow developers to fix errors within a short period after noticing that something is wrong. • Improved Maintainability - To comments, future updates or modifications to the code will be done more easily by whoever is doing them. 4. Error Handling During data processing and NumPy array processing, error handling is a must have clean coding technique to safeguard the system from edge situations. We have checks in the Sales Data Analysis System to handle a missing data or empty data for instance. For instance, Figure 42 Example from the code pg. 48 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles This way if the dataset is empty the system will print a message and exit gracefully instead of crashing or computing something wrong. Sometimes trying to do operations on NumPy arrays and empty or invalid data will give you errors and we need to proactively handle for that. Impact • Prevention of System Crashes - In theory, by handling errors appropriately the system stays in a stable state where it can gracefully handle unexpected or incomplete data making the system crash free. • Improved Stability - The system is able to keep going in edge cases, like missing or little corrupted data, without breaking or returning erroneous results. • User Friendly Experience - Error messages give the user feedback, specifically on why the operation couldn’t be completed and don’t leave the user confused, frustrated or wondering what went wrong. 5. Improved Maintainability and Efficiency The system is easier to maintain and more performance in applying clean coding practices. As an example, small, modular functions operating on NumPy arrays allow for optimizations of each function being optimized independently. The reason why the variable names in NumPy arrays are clear and meaningful makes it simple to understand the data flow when working with large datasets. Clearly, this is more maintainable, since developers can make modifications or extensions of the code with less chance of loosing the ship. Furthermore, NumPy arrays are extremely optimised for numerical operations and writing clean code guarantees that algorithms based on NumPy arrays have both good performance and are easy to understand. The fastest processing and analysis of large sales datasets, enabling decisions in a timely fashion with data in hand. Impact pg. 49 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles • Scalability - The clean and efficient design of the system ensures that as the dataset grows, the performance of NumPy arrays stays optimal and therefore the system can scale without a major performance drop. • Efficiency - Small, self-contained functions that operate on specific data leave the algorithm with minimal time complexity which helps disseminate data for analysis and generating reports faster. Advantages and Disadvantages of Clean Coding Techniques . Table 5 Advantages and Disadvantages of Clean Coding Techniques . Aspect Advantages Disadvantages Readability Clean code is easier to read and Writing clean code can sometimes understand, making it accessible to take more time, especially when it other developers. involves more detailed comments and documentation. Maintainability Easier to maintain and modify due Overuse of clean code principles to clear structure and consistent can lead to excessive abstraction, formatting. making it harder to navigate for simple tasks. Debugging and Faster Testing debugging and easier Clean code practices may lead to testing as clean code follows a over-engineering, where simple logical flow and reduces solutions are complex in complexity. made the overly name of cleanliness. Collaboration Clean code improves collaboration It can require a learning curve for among team members, as others junior can quickly understand contribute to the code. developers or teams and unfamiliar with best practices or design patterns. Code Reusability Promotes reusable components Applying clean coding techniques and functions, which saves time to every part of the project might and effort in the long run. lead to redundancy or unnecessary complexity in smaller modules. pg. 50 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Efficiency Development in Reduced future cost in The time spent on writing clean development and bug fixing due to code may lead to slower the clarity and simplicity of the development initially, especially code. for small projects or tight deadlines. Scalability Clean code is more scalable, as the There is a risk of over-planning modular design and proper and making things overly flexible structure make it easier to add new when the problem doesn’t require features without disrupting such extensibility. existing code. Consistency Ensures consistent conventions, naming Maintaining consistency across a structure, and large codebase can be challenging, formatting across the codebase. especially in large teams or longterm projects. Self- Less reliance on external It can be hard to achieve the Documenting documentation since well-written perfect balance between clarity Code code is self-explanatory. and simplicity, sometimes requiring too many comments. pg. 51 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Design Patterns They offer ready-made ideas to solve problems that usually happen while developing software. They are meant for situations that can repeating and they can be used for many kinds of problems. Consider design patterns as plans or patterns that assist developers in dealing with certain software design problems in a similar and effective way every time. They help deal with common problems by applying methods verified and improved by expert developers with experience. With the help of design patterns, designers are able to minimize effort and concentrate on strong, robust and efficient systems. Design patterns are not bits of code, but rather guidelines that explain how to organize your code to deal with usual problems. They streamline the development by facilitating design with preset templates, simplifying issues and organizing your projects better. While the idea of design patterns started in OOP, the principles can still work in other styles of programming. A popular book about the concept, “Design Patterns - Elements of Reusable Object-Oriented Software”, was released by Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides. The practice of design patterns allows programmers to make code easy to manage and maintain for years to come. It supports the same standards among teams because it’s frequently used in large software projects with many developers. In essence, design patterns allow developers to make software more flexible, easy to scale and efficient. Importance of Design Patterns in Software Development Design patterns provide many important advantages which explain why they are important for software development. • Reusability - They make it possible to solve the same problem successfully and wisely in many projects. • Maintainability - The system is simpler to customize when design patterns are followed. This supports both maintaining the software for the future and making it scalable. pg. 52 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles • Improved Communication - Because of design patterns, developers can communicate difficult ideas and solutions more easily with each other. Rather than describing a new idea, developers can point to design patterns that most other developers know. • Code Organization - Using patterns in coding explains things better and makes even large applications easier to understand. • Efficiency - Building using design patterns helps save time because developers can rely on tried-and-tested design ideas. Types of Design Patterns All design patterns can be arranged into three main families, Creational Patterns, Structural Patterns and Behavioral Patterns. Each field is concerned with a separate set of design solutions. 1. Creational Patterns This set of design patterns deals with how objects are made. They let us design objects so that systems can respond to changes in requirements more smoothly. To creational patterns, adding objects to complex systems becomes simpler. The main well-known creational patterns consist of, • Singleton Pattern - Keeps the class limited to a single instance and gives a way to get to it from anywhere. • Factory Method Pattern - Provides a method for producing objects, but enables subclasses to decide what kind to create. • Abstract Factory Pattern - Enables developers to build groupings of connected objects without knowing the precise object class throughout development. • Builder Pattern - Departments the making of an object from how it is represented, enabling the same process to make multiple kinds of objects. pg. 53 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles • Prototype Pattern - Allows users to create new objects by cloning those already present, so they don’t need to pick the specific class. 2. Structural Patterns These patterns arrange the arrangement of classes or objects. The patterns describe methods for putting together different objects and classes to build larger and more complicated structures. They make sure that school classes are linked in a way that is both practical, adaptable and can handle changes. There are some structural patterns that become famous such as, • Adapter Pattern - Makes it possible for incompatible interfaces to work side by side by providing a layer that changes one format to the other. • Bridge Pattern - Technology allows for an abstraction and its implementation to function independently. • Composite Pattern - Applies a tree design to split data based on parts and wholes, so treatment of each object and collection stays consistent. • Decorator Pattern - Adds to an object’s duties on the fly, so you can change its actions without modifying its original code. • Facade Pattern - Simplifies the way users’ access and interact with a system consisting of multiple classes. • Flyweight Pattern - By using shared data, less objects are made which helps performance and reduces memory use. • Proxy Pattern - Stands in for another object and manages who can use or operate on it. pg. 54 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles 3. Behavioral Patterns The main goal of behavioral design patterns is to describe the ways in which objects interact with each other. Topics in these patterns include algorithms, how objects cooperate and where responsibilities are assigned. They let you talk with objects more easily, use them in more flexible situations and make objects less reliant on each other. Some well-known behavioral patterns include, • Observer Pattern - Permits one object (the subject) to inform others (observers) when its state changes, helping to keep objects loosely connected. • Strategy Pattern - Includes a number of algorithms and makes it possible to pick one at runtime for the client. • Command Pattern - Holds a request in an object that can be used with queues, requests and operations by clients. • State Pattern - Allows an object to cause itself to act differently when its internal state changes, giving the appearance of a new object type. • Iterator Pattern - Enables you to access elements within an aggregate object one after another, concealing its internal design. • Mediator Pattern - Defines an interactor that oversees communication between different objects, helping separate them and reduce needs for collaboration. • Memento Pattern - Freezes the state of an object at a given time, making it possible to restore it later without bypassing the object’s capsule. • Chain of Responsibility Pattern - Provides a way for any of several objects to process a request. • Visitor Pattern - Allows you to add an operation to an object structure without needing to change its existing classes. pg. 55 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Types of Creational Design Patterns Creational design patterns help with the way new objects are made. They aid in making objects that can be changed, updated and applied again. Because of these patterns, object creation logic is easy to manage and change, keeping existing code untouched. Creational patterns help reduce the amount of work needed to make a complicated object that depends on other objects. A number of famous creational design patterns include Singleton Pattern, Factory Method Pattern, Abstract Factory Pattern, Builder Pattern and Prototype Pattern. 1. Singleton Pattern With the Singleton Pattern, a class will only have one instance used across the application. It allows anyone around the world to access that instance. The pattern is applied when just one object is expected to control actions throughout the system such as during logging or managing configurations. It stops the class template from being used twice which helps reduce costs and helps create consistent objects. Figure 43 Java Code Example for Singleton Pattern With Singleton, only one instance of the class can be made. The same instance is returned by getInstance() each time the method is run. A single global instance can be used by any part of the program. pg. 56 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles 2. Factory Method Pattern The pattern makes it possible to use an interface to make objects, but lets subclasses change the class of objects that are made. The pattern makes it so that subclasses handle creating objects which helps keep the entire code better organized. Objects can be created by the framework without having to identify the object’s class type. Figure 44 Java Code Example for Factory Method Pattern pg. 57 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles In this case, the AnimalFactory declares the factory method called createAnimal and it is implemented by the concrete factories DogFactory and CatFactory. The type of animal to be made (dog or cat) depends on which subclass you choose. Using this pattern, we can produce objects without dependent on specific classes. 3. Abstract Factory Pattern This pattern allows you to make families of similar objects through an interface, without indicating the specific classes of those objects. It gives you the ability to make various objects, but makes certain they are all members of a family and can interact with each other. Figure 45 Java Code Example for Abstract Factory Pattern pg. 58 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Figure 46 Java Code Example for Abstract Factory Pattern Here, FurnitureFactory supplies two methods for making a Chair and a Table. The collections created by the ModernFurnitureFactory and VictorianFurnitureFactory result from concrete factories following these methods. This approach allows designers to make related objects, ensuring all their products belong together in the same family (modern or Victorian). 4. Builder Pattern The Builder Pattern allows you to construct a complex object step by step. The process is divided into building an object and displaying it, so the same construction method can be used to make several different forms. It becomes very helpful when an item consists of several parts that must work together. pg. 59 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Figure 47 Java Code Example for Builder Pattern pg. 60 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Figure 48 Java Code Example for Builder Pattern With ComputerBuilder, you step through the build process of creating a Computer object. Constructing everything such as the CPU, RAM, storage, etc., can all be done separately and every time a different computer is made, the builder class stays the same. Building the product is the last task of the build() method. 5. Prototype Pattern New objects are produced using the Prototype Pattern by copying an identical copy from an existing object, instead of making a completely new one. This helps because designing an object this way saves time and money. pg. 61 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Figure 49 Java Code Example for Prototype Pattern So, Shape is a cloneable class and both Circle and Square inherit it and become concrete prototypes. The clone() method duplicates the original object which makes it simple to create many copies without starting over. Types of Structural Design Patterns The focus of structural design patterns is how elements of a system can be connected to build more complex structures. Using these patterns, relationships among classes and objects are simplified to keep the system flexible, effective and simple to look after. With structural patterns, different elements can be arranged so that expanding, updating and interacting is pg. 62 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles simple. Many designers are familiar with the Adapter Pattern, Bridge Pattern, Composite Pattern, Decorator Pattern, Facade Pattern, Flyweight Pattern and Proxy Pattern. 1. Adapter Pattern The Adapter Pattern lets different interfaces cooperate, even if they can’t connect naturally. It allows a client to use a familiar interface instead of interacting with the original interface of the class. It becomes very helpful when you must add a new component to a system, but the new item has a different interface. Figure 50 Java Code Example for Adapter Pattern pg. 63 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Figure 51 Java Code Example for Adapter Pattern The MediaAdapter class links the AudioPlayer with the AdvancedMediaPlayer which includes both the VlcPlayer and Mp4Player. By using the adapter, the AudioPlayer can play files in any format. 2. Bridge Pattern The purpose of the Bridge Pattern is to keep abstraction apart from implementation, so that each can change on its own. It’s especially helpful when there’s a chance that both the abstract class and the class implementing the abstraction will change down the road. With the Bridge Pattern, the Bridge links the abstract part and its implementation. pg. 64 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Figure 52 Java Code Example for Bridge Pattern Figure 53 Java Code Example for Bridge Pattern pg. 65 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Here, the Shape class is the abstract part and the Color class provides details for how things are done. With the Circle and Square classes, each shape can take any color and both the shape and color can change separately. 3. Composite Pattern It gives you a way to combine objects into a nested structure to illustrate part and whole relationships. Clients can use individual objects and compositions of objects in the same way with this approach. Figure 54 Java Code Example for Composite Pattern pg. 66 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Figure 55 Java Code Example for Composite Pattern In this case, the Manager class acts as a composite by holding a team of Employee objects. Both developers and designers use the Employee interface which ensures the same details are shown for both simple and compound employees. 4. Decorator Pattern Decorator Pattern supports the change of an object’s behavior without modifying its structure at runtime. You can use this approach whenever you have to add new features to an object, so they will be reusable. pg. 67 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Figure 56 Java Code Example for Decorator Pattern Figure 57 Java Code Example for Decorator Pattern In our instance, the Car interface is the component and BasicCar is the concrete component. CarDecorator is an abstract decorator that increases the abilities of the base object. Both SportsCar and LuxuryCar classes add extra features directly to BasicCar using concrete decorators. pg. 68 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles 5. Facade Pattern The Facade Pattern covers up the intricacies of a system with an easy to use interface. The system’s complexity is not visible through its higher-level interface which simplifies using it. Figure 58 Java Code Example for Facade Pattern With the CarFacade, interacting with the car system becomes easier. Rather than making calls to each subsystem, the client works with CarFacade which hides if from them. Types of Behavioral Design Patterns In behavioral design patterns, the main issue is what goes on between objects, their roles and how these roles interact. Their purpose is to enable the system to adjust easily, divide up tasks between sender and receiver and promote clearer ways for objects to talk to each other. Such methodologies show the way objects exchange information, helping software systems manage their operations more efficiently. Various well-known design patterns include the Observer Pattern, Strategy Pattern, Command Pattern, State Pattern, Iterator Pattern, Mediator Pattern and Visitor Pattern. pg. 69 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles 1. Observer Pattern The Observer Pattern is about one object (the subject) maintaining a list of other objects (observers) which it updates whenever required. If anything in the subject changes, it sends out an update to all who are observing it. Using this pattern, it is possible to make distributed systems that let a subject notify multiple observers about an event. Figure 59 Java Code Example for Observer Pattern pg. 70 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Figure 60 Java Code Example for Observer Pattern Here, NewsAgency does the action and NewsChannel observes it. Every registered observer (news channel) is informed by the NewsAgency when news does not stay the same. Here, the Observer Pattern is used so that several objects can hear updates made by a single subject. 2. Strategy Pattern Using the Strategy Pattern, a group of similar algorithms are designed, put inside a single interface and made easy to replace. At runtime, the client can pick whichever algorithm fits their needs to help the system remain adaptable and growing. pg. 71 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Figure 61 Java Code Example for Strategy Pattern In this situation, PaymentStrategy is an interface that explains a group of payment algorithm types (strategies). At any time, the ShoppingCart class can be configured to use any supported payment method (Credit Card or PayPal) which is flexible and makes it easy to incorporate future changes. 3. Command Pattern With the Command Pattern, a request is turned into an object, so clients can be passed queues, requests and operations as parameters. As a result, the request can be used flexibly and temporarily stored for future use. pg. 72 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Figure 62 Java Code Example for Command Patter Figure 63 Java Code Example for Command Patter With the Command Pattern, the user can activate steps like turning on the light in a sequence, without having to learn the exact details. With the Invoker (RemoteControl), commands are stored and executed separately, ensuring the request is separate from the work. 4. State Pattern pg. 73 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles By using the State pattern, objects can display new behaviors whenever their states change which makes them seem as if they have changed their class. It helps when advice should vary depending on a situation, as with a traffic light or a turnstile. Figure 64 Java Code Example for State Pattern This example uses the State Pattern so the Context class can change its actions according to its existing state. As the state changes, the object responds differently to its input depending on whether it’s in a StartState or a StopState. pg. 74 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles 5. Iterator Pattern Iterators use this pattern to navigate over a collection and read the elements one at a time while hiding how the items are stored. Collections like arrays, lists and sets can be easily iterated over, without you knowing their detailed structure. Figure 65 Java Code Example for Iterator Pattern To this pattern, you can loop through the elements of NameList one at a time, but the pattern hides how NameList is built. Iteration logic is separated from the collection by the Iterator interface which gives methods to access and retrieve a collection’s next element. pg. 75 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Use Case Diagrams for the Scenario Figure 66 Use Case Diagrams pg. 76 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Class Diagram for the Scenario Figure 67 Class diagram pg. 77 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Entity Relationships Diagram for the Scenario Figure 68 Entity Relationships Diagram pg. 78 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Use Of Solid Principles When making the Sales Data Analysis System for Sampath Food City, we built our software architecture following the SOLID principles. Because of SRP, each class was able to focus on doing only one thing in the system. The SalesRecord class only includes data about a sale, while Branch is only responsible for information about a branch. To this approach, the system can be easily updated and is easy to work with in the future. Applying the Open/Closed Principle (OCP) helped us build the system so that adding new features does not require us to change the code we already have. If we want to add weekly or yearly sales trends to the system later on, we can do so by including new analysis classes with no changes to the old ones. To this, the system will stay smooth even as new features are included. Applying Liskov Substitution Principle permits the program to treat derived classes and their base classes in the same way without any impact on the correctness of the program. For instance, the system allows for similar treatment of all kinds of analysis, including monthly and weekly ones. All types of analysis are developed from the same base class or interface, so they fit together smoothly when used instead of one another. ISP was created so that classes do not have to implement methods they will not fully use. To avoid making classes include several unrelated features, we decided to make smaller, more specialized interfaces instead. This means a class can work well by using just the methods it requires and introducing less clutter and chances of mistakes. Finally, the SalesDataAnalysisSystem was created to depend on the Database and Analysis interfaces instead of its specific versions. This allows the function of the system to be separate from how data is managed, or tasks are analyzed which means the system can adapt to different rules more easily. Any changes to data access or method of analysis won’t affect the top-layer parts of the program, so the code is easy to cope with and update. Following SOLID helps the system be both efficient and scalable and also ensures it’s easier to change, test and maintain. pg. 79 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Selected Design Pattern (Facade Pattern) The use of the Facade Pattern is the best design solution for the Sales Data Analysis System scenario at Sampath Food City. The objective of the Facade Pattern is to provide an uncomplicated interface to the user, sparing from dealing with how every underlying part of the system works. As mentioned, the SalesDataAnalysisSystem deals with many parts of the process: studying sales from various branches, working out product costs, handling weekly or monthly analysis and making finalized reports. If there weren’t subsystems in place, users would have to keep track of different matters by themselves which might be confusing and more likely to lead to wrong actions. It’s possible that every subsystem uses different techniques for working with data, statistics and reporting which may be hard for users to grasp. With the Facade Pattern, all these different tasks come together under one, simple interface for the user. To an easy to use interface, top management can easily ask for various analyses (such as those conducted monthly, weekly or by product) without knowing the inner workings or where the data comes from. The facade reduces the effort needed for users to connect with the underlying complex areas of the system. In addition, the Facade Pattern helps to keep complex parts of the program hidden. All users or other systems have to connect through one main place, making the service easier to use and maintain. The facade gathers the main functions of subsystems into one simple screen, making things easier and more flexible. In Sampath Food City, this is the best way to ensure the management can make useful decisions using a variety of sales data. Because the interface is straightforward, managers can explore the data offered by the system and ignore the technical processes involved. So, as the business changes and adds extra analysis features or data sources, the facade helps the user avoid noticing the changes and ensures the application remains user friendly. pg. 80 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Selected Data Structure (Array) The Sales Data Analysis System case at Sampath Food City should use the array data structure and we will use NumPy arrays. NumPy allows Python users to work with large and multidimensional arrays and supply a collection of functions to work with them. As a result, NumPy arrays are quickly becoming the best way to look at sales data. Since we have large numbers to work with such as sales combined with product and transaction information, we must analyze and process them effectively. This data is naturally handled by NumPy arrays since they provide better features than standard Python lists or similar kinds of data structures. Performance is one of the biggest advantages of working in development. Since NumPy arrays are built using C, they perform mathematical computations and managing large datasets quicker than Python lists. Sales data analysis requires processing large batches of data, including results from each branch, information on products and statistical data on things such as overall sales, prices and so on. NumPy arrays enable us to handle and change data efficiently. To NumPy, we can keep records, quantities and other data neatly arranged, letting us perform quick calculations and analysis. Moreover, NumPy includes vectorized operations and broadcasting that let us calculate data in the entire dataset at once without using a loop. You can benefit from it when you estimate total sales or check product prices across all your branches. To NumPy, all these operations can happen at once which makes the system swift and easier to take care of. Moreover, NumPy arrays integrate smoothly with other Python libraries (e.g. for data analysis, pandas and for visualization, matplotlib) to help analyze results. The use of NumPy arrays allows the system to do complex things on the data without worrying about performance bottlenecks - aggregating sales figures, calculating averages, finding trends, etc. pg. 81 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Refining the Design (Multiple Design Patterns) During refine the design for the Sales Data Analysis System at Sampath Food City, it is possible to use multiple design patterns in order to increase the system's flexibility, scalability and maintainability. There is each design pattern for a certain purpose, for that it resolves other system’s design problems. With a combination of design patterns, it will be possible to build a robust system that can adapt to future changes. For instance, we could then utilize the Facade Pattern once again to generalize the way the user interacts with the complex subsystems used in analyzing the new requirement. At a high level, this pattern offers a thinner, easier to consume interface that allows users to leverage a variety of analysis functions (e.g. monthly, weekly and product preference analysis) without getting into their weeds. We could incorporate Strategy Pattern, alongside the Facade Pattern, to handle different types of analysis. The Strategy Pattern permits the system to encapsulate a family of algorithms (i.e., distinct types of sales analysis) and to keep them interchangeable. When the system needs to perform various types of analysis on the basis of end users’ requirements (e.g., analyze monthly sales for branches separately or product preference across several stores), this is beneficial. The reason we used Strategy Pattern here is so that later we could write new types of analysis and reuse the same code for different analysis types in future. We could also have used the Observer Pattern to keep the system up to date with real time sales data changes. For example, the Observer Pattern allows the system to notify the appropriate components (e.g. analysis modules, reports, etc.) if new sales records are added to the database so that the latest and most current data is available. In these situations, this pattern is quite useful because the sales data is monitored and reflected in many reports from time to time. In the Builder pattern, we could also create complex objects. For example, if the system has to generate report of fine grain or if it has to create structured data (like, product preference analysis or selling total sales distribution) it can make use of the Builder Pattern to create objects in step by step basis and have all the necessary information available in the final report. It makes code clearer to understand and when we need to modify the report generation process in the future, it will be much easier to do. pg. 82 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles By mixing and matching these design patterns (Facade, Strategy, Observer and Builder), we develop a system which is easy to expand upon, refactor and for a client to interact with. These patterns function collectively to make what are complex interactions more simple, more flexible, where new features can be added with as few ramifications to the current system as possible. By incorporating multiple design patterns in this way, the Sales Data Analysis System is made to be well structured and able to handle future needs. Justification of Design Choices for the Sales Data Analysis System The system has been engineered to support growth, change and efficiency. For this reason, we used SOLID principles, decided on a suitable design pattern and picked the correct data structure that matched the needs of the system. An attempt has been made to shape up the system grounded on the SOLID principles so that the system not only turns out to be flexible, but also more straightforward in maintenance. To guarantee that each class within the system has a solid single responsibility, code was kept with Single Responsibility Principle (SRP) in mind . for instance, the SalesRecord class is used to store sales data and the Branch class to store branch specific information. It saves me from complex and hard to manage code. By following OCP, we don’t modify existing code and can easily add new analysis type (for example yearly analysis) in the future. The Liskov Substitution Principle (LSP) guarantees that you can create different types of analysis as subclassing analysis (derived classes) will operate as desired, so you can go on to use derived classes interchangeably. Classes implement only relevant methods according to the Interface Segregation Principle (ISP) and modules are not dependent on how concrete implementation is done. high level modules defined in terms of abstractions as per the Dependency Inversion Principle (DIP). The Facade Pattern was chosen to simplify how the system interacts between the user and the system’s complex subsystems for the design pattern. Using this pattern offers users to interact with many of features such as monthly and weekly sales analysis without being concerned about complexities underneath. The Strategy Pattern was also used, together with the facade, for handling different types of analysis such as monthly/weekly sales analysis. This enables pg. 83 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles new analysis strategies to be added without changing existing code and to meet requirements found later. To keep the system updated with real time sales data so that relevant components would be automatically notified when new data was available, the Observer Pattern was used. Additionally, the Builder Pattern was selected to construct report objects constructively, object by object, to ensure that the system can produce well formed and structured reports while not sacrificing code complexity. NumPy arrays are the data structure we use, since they are extremely efficient for working with a lot of numbers like sales figures, prices of products and quantities of sales. Because numbers in NumPy arrays are handled efficiently, they make it ideal to conduct the math needed in sales analysis. The system’s ability to apply operations to all data elements at once makes it suited for working with and testing, large datasets. Applying different design patterns to the design ensures that the system remains both tough and versatile. When we combine Facade, Strategy, Observer and Builder patterns, we give users a simple interface, make different analyses easier to manage and enable future changes to the system. As a result, the system’s complexity is reduced, more parts can be interchanged and the whole system can continue to work as Sampath Food City needs change. To SOLID principles, the Facade and Strategy design patterns and NumPy arrays being used, the Sales Data Analysis System helps Sampath Food City handle their data analysis easily and efficiently. Test Case Test Case 1 - Monthly Sales Analysis for Each Branch Table 6 Test Case 1 - Monthly Sales Analysis for Each Branch Test No 1 Test Case Verify that the system correctly calculates the total sales for a specific branch for a given month. pg. 84 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Expected Output The system should display the total sales amount for the branch for the month specified. Test Case 2 - Price Analysis of Each Product Table 7 Test Case 2 - Price Analysis of Each Product Test No 2 Test Case Verify that the system correctly calculates the price analysis of each product for a given period. Expected Output The system should display the price of each product along with the sales quantity and total revenue for each product. Test Case 3 - Weekly Sales Analysis for the Supermarket Network Table 8 Test Case 3 - Weekly Sales Analysis for the Supermarket Network Test No 3 Test Case Verify that the system correctly calculates and displays the total sales for all branches for a given week. Expected Output The system should show the total sales for the week across all branches in the supermarket network. Test Case 4 - Product Preference Analysis Table 9 Test Case 4 - Product Preference Analysis Test No 4 pg. 85 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Test Case Verify that the system analyzes and ranks the most preferred products based on sales data. Expected Output The system should display a list of products, ranked by their sales quantity or total sales value. Test Case 5 - Analysis of Sales Amount Distribution Table 10 Test Case 5 - Analysis of Sales Amount Distribution Test No 5 Test Case Verify that the system correctly calculates the distribution of total sales amounts across different product categories. Expected Output The system should display a graphical representation (bar chart or pie chart) showing how the total sales are distributed across different product categories. Test Case 6 - Data Handling for Missing Values Table 11 Test Case 6 - Data Handling for Missing Values Test No 6 Test Case Verify that the system handles missing data appropriately (e.g., for missing sales transactions or product information). Expected Output The system should either handle the missing data gracefully by notifying the user or by filling in pg. 86 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles with default values, and not crash or give erroneous results. Automated Testing Automated testing means testing software using software tools which in turn execute predefined test cases on a software system, compare actual results with expected results and report the results. Automated testing chiefly has the benefit of making testing more efficient and coverable. Automated testing helps you to perform repetitive testing quickly and on time. One area where automated testing is especially handy is with continuous testing which is a case when the software is tested everytime some change is made, e.g. regression testing (testing the system to make sure that new bugs were not introduced as a result of the new change). Additionally, it is also helpful in performance testing and load testing which asks that the system handle many users or requests over a long interval. Types of Automated Testing Many types of automated testing are useful in performing different tasks as a software is developed. Depending on what they are testing, different tests support the system working as planned. • Unit Testing Unit testing tests each part of the application one at a time, in isolation. Such functions are set up at the individual level, rather than as a group. The main objective of unit testing is to assure that individual functions function as they should, after being tested with a set of predefined inputs and outputs. Most often, testers use this kind of testing which developers usually write. • Integration Testing Once unit testing is done, integration testing comes in to see if various sections of the application communicate with each other as intended. It verifies that connected components for interacting with a database, using APIs or handling data are all working properly. pg. 87 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles • System Testing It proves that everything in the system is working fine by operating it in surroundings that are like real life. In system testing, everything in the application is checked to make sure all connected parts cooperate well from the beginning to the end. • Acceptance Testing The purpose of acceptance testing is to see if the system follows the requirements put in place by the business. At this step, testing occurs to make sure the system is ready for use by users. It guarantees that users will see the software operate as they require and that all requirements for deploying are achieved. • Regression Testing Regression testing checks that the application remains unchanged in parts that were previously in good shape after the main changes or bug fixes. This becomes most important when working with big systems that have frequent updates. • Performance Testing The main goal of this kind of testing is to determine how the system works under various stresses. It checks the system to keep it working steadily under the pressure of high levels of traffic or data. • Smoke Testing It is a basic method for finding out if vital software features work after a new update or build is added. Usually, the workout is meant to be quick and wide-ranging to make sure the application will withstand further tasks. • End-to-End Testing End-to-End testing acts like a real user, so the system works as designed throughout the entire application. It ensures that the system works for every step a user might take, including with all different systems. Testing Tools Selected (Pytest and Unittest) pg. 88 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Pytest and Unittest were chosen as the tools for testing the Sales Data Analysis System because these are both very robust tools, easy to use and very flexible. The two tools are equally good at testing in Python and will enable us to write robust tests confirming the preciseness and constancy of the system. • Pytest Pytest has amazing ease of use, and its syntax is very user friendly. Because of that, it is a great fit for both junior and senior developers. Pytest requires little boilerplate and provides cleaner looking code, so it’s faster and easier. Pytest is feature rich having fixtures, parametric tests and in build assertion methods. Turning next to these features, we will find them to be incredibly useful for testing a variety of sales scenarios and edge cases. For example, we can use fixtures to load up reusable test data and parameterized tests to test input for different values. Being a Sales Data Analysis System that processes large datasets, we are able to efficiently run tests on the complex, large datasets because of the scalability of Pytest. Its performance and flexibility are a good fit for testing different test case for the wide variety of functionalities supported by the system. • Unittest Unittest is one of the built in Python Library, so you don’t have to install its third party. It is nice to avoid this, for the sake of consistency and ease of integration with Python ecosystem while working on initial tests. Unittest encourage us to use structured testing. It gives us test cases and test suites to organize run related tests and as you scale the system it becomes more important. The structure here means this is easy to deal with long lists of tests over time. Unittest has strong compatibility which can work with other Python libraries and tools well, so it can be used to test more formally structured and formal components of the Sales Data Analysis System. For instance, if you are using the Unittest tool together with Mocking libraries you can emulate external systems or system interactions that are too hard to implement in the real world. pg. 89 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Justification for the Selection of Pytest and Unittest As Pytest and Unittest have complementary strength, they are selected for testing the Sales Data Analysis System. I chose Pytest because their approach to writing complex test scenarios and handling large datasets is simple and flexible which gives it a unit and integration testing sweet spot. Converselly, Unittest offers a nice option to structure your test routines and to guarantee that all component are tested in a consistent form. When used together, we make sure we’re testing the system as much as possible with automated tests that will test individual components as well as how they interact. We also get flexibility though and we can test different aspects of the system without breaking Python's best practices. Pytest offers the possibility to write more dynamic and complex tests and therefore, from Unittest it is easier to guarantee rigorous and consistent tests in every part of the application which in turn serves for making more reliable and stable the final system. Building and Implementing the Sales Data Analysis System Figure 69 Sales Data Analysis System Code pg. 90 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Figure 70 Sales Data Analysis System Code Figure 71 Sales Data Analysis System Code pg. 91 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Figure 72 Sales Data Analysis System Code Figure 73 Sales Data Analysis System Code pg. 92 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Figure 74 Sales Data Analysis System Code Figure 75 Sales Data Analysis System Code pg. 93 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Figure 76 Sales Data Analysis System Code The code aims to give management at Sampath Food City the ability to analyze different parts of their sales data. The application uses a Facade Pattern to give a simple users interface for handling complex sales analysis steps. Using SOLID techniques in coding, the system is well put together and can be improved when necessary. The main job of the system is to read and analyze sales data which comes from an Excel file uploaded by the user through Google Colab. With data loaded, the SalesDataAnalysisSystem leads the way and handles the coordination of analysis work. The classes looking after this are SalesAnalysis for analyzing branch and trend statistics, ProductAnalysis for looking at what products are sold and PaymentMethodAnalysis for examining payments used by sales. Every class in our program applies SRP by concentrating on one part of the sales data analysis. Sales data in the system is presented as bar charts for individual stores and products, line graphs for the evolution of sales over time and pie charts for the number of payments chosen by customers. The insights are easily seen because each class uses the helper methods _plot_bar_chart(), _plot_line_chart() and _plot_pie_chart() to present the data in graphs. SOLID principles are followed to allow easy extension of the system. A new type of analysis class can be introduced just by building a new class, in accordance with the Open/Closed Principle. Because the system is flexible, it is easy to integrate tasks or analysis that weren’t there initially. Cooperation with the Facade Pattern enables the user to set up several analyses using a few function calls, not being bothered with details of the underlying processes. pg. 94 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Total Sales By Branch Figure 77 Total Sales by Branch Chart The chart displays the overall sales numbers by branch for Sampath Food City, separating its performance at five branches, B001, B002, B003, B004 and B005. Sales totals are shown along the vertical y-axis from 0 to 60,000 and the horizontal x-axis spans B001, B002, B003, B004 and B005 branch IDs. The numbers on the chart refer to the sales of every different branch included. Each branch is spaced according to the sales it made and B005 achieved the highest sales of all, about 60,000. Out of the three remaining branches, B001 and B003 both sell between 50,000 and 60,000 products and B004 is only slightly better with sales near 50,000. The light blue bars on the chart help management see how each branch ranks in sales. With this information, businesses can plan how to use resources, give promotions and set up overall sales strategies in each branch. Total Sales By Product pg. 95 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Figure 78 Total Sales by Product Chart This chart lists the total sales for each product at Sampath Food City. On the y-axis, you’ll find the total sales, beginning at zero and rising to 35,000. Across the x-axis are the items sold in the supermarket, including Rice, Milk, Chicken, Eggs, Banana, Orange, Fish, Bread and Apple. You can read how much of each product was sold by the length of the bar and the height tells you the amount of profit the product made. The figure reveals that Rice, Milk, Chicken and Eggs have the largest total sales, all being just above 30,000. There are differences, but Banana, Orange, Fish, Bread and Apple have sales similar to those of Chicken. Light blue bars allow for simple comparison of how each product has sold. Search this chart to see which products generate the most sales which allows management to know which items to promote, how much stock to have and how to market them. Sales Trend Over Time pg. 96 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Figure 79 Sales Trend Over Time Chart In this chart we have January 2025 to March 2025 sales trend over time of Sampath Food City. On y axis you have total sales from 2,000 to 7,000. On x axis are dates from January to March in the year 2025. But a line connecting the points indicates the ups and downs of sales and each point on the line indicates the total sales of an exact date. The sales figures have large variation as seen on the chart whereby some peaks reach as high as 7,000 meaning days of high sales while the other deepds can fall to about 2,000 as we see in the chart meaning days of very low sales. The green line is used to watch the daily sales to figure out what is normal, what is a pattern and what is an anomaly with the sales data. Specific day that that poked up some of the spikes were really sharp, maybe that was promotions or something, but poked up to 400 of sales that particular day. The chart generally allows management of Sampath Food City to determine the high performing days and periods of lower sales to understand their sales patterns and take well informed sales performance improving decisions like planning for promotion or tackling the sales of low periods. pg. 97 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Product Preference Analysis Figure 80 Product Preference Analysis Chart Product preference analysis for Sampath Food City is shown in this chart, showing how many units of each product were sold. On the y-axis are the quantities sold, from no units to 600 and the x-axis includes Fish, Chicken, Milk, Rice, Banana, Eggs, Apple, Orange and Bread. The tops of the light blue bars mark how many items of each product were sold. Fish and Chicken show up as the most popular items, since 500 of them were ordered. You can see that Milk, Rice and Banana are popular because they sell very high volumes. The other products, Eggs, Apple, Orange and Bread, are not selling as much as Banana or Lettuce, but they are still favored by shoppers. Management of Sampath Food City relies on this chart to understand what products their customers like best. Using this information, the company’s management can plan the right stock amounts, when to run special promotions and how to plan inventory in advance, all based on customer demand. pg. 98 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Sales Distribution By Payment Methos Figure 81 Sales Distribution by Payment Methos Chart This chart compares the different types of payments used by customers at Sampath Food City. It’s a pie chart, with every segment standing for the percentage of sales made using different payment options, Cash, Credit Card, Debit Card and Online. We can clearly see from the chart that the biggest method used for making sales is also the least used one, meaning each method makes up roughly the same amount of the total. Debit Cards make up the biggest part of the sales at 26.0%. Cash sits in second place with 24.3%, just ahead of Credit Card at 24.4% and Online at 25.3%. pg. 99 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles The pie chart allows Sampath Food City’s management to see clearly how their customers pay for their goods. Being aware of these trends enables a company to change its payment system, plot upcoming sales and check what payment methods customers prefer. Overall Impact of Applying SOLID Principles on the Development of the “Sales Analysis System” The application of SOLID principles to the Sales Analysis System development raises the maintainability, scalability and flexibility of the developed solution. Based on these principles, the design will be robust, efficient and extensible. The structure of measurement observation. The next part will be some critical thinking of how each SOLID principle impacts the system’s development. Single Responsibility Principle (SRP) The SRP makes sure each class in the sales analysis system is dedicated to just one task. Because of this, the system is easier to maintain and read since each class does not depend on any others. SalesAnalysis is responsible for sales analysis, ProductAnalysis for product analysis and PaymentMethodAnalysis for payment metrics. Because each part of a system has a distinct responsibility, updating any feature can be accomplished with ease. On the other hand, when the system grows, having classes split by the SRP may lead to too many small classes, making it tough to control everything. Open/Closed Principle (OCP) Because of OCP, you can add more functionality without changing any existing parts of the system. This shows up in the Sales Analysis System, as adding CustomerAnalysis or RegionSalesAnalysis does not require any changes to existing classes. The modular design ensures the system can adjust to new demands without introducing many risks of errors. Still, to add more new features and maintain a consistent design, a more formal approach such as using abstract classes or interfaces is recommended. Liskov Substitution Principle (LSP) With LSP in place, the system’s behavior does not change when a subclass replaces its parent class. At present, the design does without inheritance, but it could be added at a later stage. pg. 100 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles When unique analysis is required, for example, regional sales or analysis by month, we can use inheritance to add those capabilities to the base analysis classes. For this reason, any subclass must preserve the standard behaviors found in the base class. Inheritance must be applied correctly or changing to a subclass may not work smoothly and LSP could be broken. Interface Segregation Principle (ISP) Under ISP, clients should have interfaces that are tailored to their needs and nothing more. The Sales Analysis System achieves a basic form of this principle by making each analysis class manage a single area. In this way, someone focused only on product sales will interact only with the ProductAnalysis class and won’t need to deal with extra unrelated methods. To improve this system, using more formal or abstract classes may be advantageous if new functions are required, to keep exposure of methods to only what the client needs. Dependency Inversion Principle (DIP) DIP suggests that abstractions should act as the common dependency between higher-level and lower-level modules. The design currently shows the SalesDataAnalysisSystem class directly passing values to the Analysis classes. You can improve this by implementing dependency injection or a factory pattern so the system’s parts are not tightly connected. If the system is split up, it can be easier to put parts under test and change or extend modes of analysis without touching the core closely related parts of the system. To become maintainable, the application can follow the DIP principle in its structure. Overall Impact of Applying SOLID Principles By applying SOLID principles, the Sales Analysis System has contributed to maintaining decision, flexibility and scalability of the software. The system is well structured for grow because of SRP (On to each class one responsibility) and OCP (Open for extension, closed for modification) - making sure that each class is responsible for doing one thing only and that new things can be added without touching existing code. Using this approach adds the potential for the system to be more LSP (inheritance), ISP (more refined interfaces) and DIP (a decoupled architecture). That said, there is scope for improvement in making our use of formal design patterns and abstractions to help ensure our system is not rigid and can be extended and changed easily as we continue to evolve it. Challenges and Areas for Improvement pg. 101 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles It was evidenced that the implementation of SOLID principles leads to a clean and maintainable design, though there still is much room for improvement. However, first of all, no explicit inheritance, interfaces, makes it harder to extend the system in a uniform, for example, by thinking about decomposition of component hierarchy, because you do not have explicit inheritance interfaces. If you had abstract base classes or interfaces it would give you a much nicer architecture for adding new analysis types. Secondly, the system is tightly coupled in particular areas, e.g. instancing of analysis classes within the SalesDataAnalysisSystem. These components can be decoupled by applying dependency injection or a factory pattern and then in Unit been made blindly testable. Lastly, although SRP has been effectively implemented, the addition of the smaller specialized classes seems likely to make the system harder to manage as it grows. The Benefits & Drawbacks of Automated Testing Benefits of Automated Testing 1. Efficiency and Speed Tests that are performed automatically run more quickly than those performed by hand. You can run written test scripts many times, eliminating the time you would spend performing tasks repeatedly. It comes in handy whenever you need to keep testing the same things after updates are made to the system. Because automated tests can be run late in the evening, problems with the system’s performance can often be found early. Because of this, problems can be found and solved faster by developers. 2. Consistency and Accuracy Running tests automatically eliminates any chances for human error. Whenever a test is performed, it always executes exactly as before, hence the outcomes are always the same. Automated tests mean all the tests are run every time, so they won’t be missed and the results will be exactly the same each time. pg. 102 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles 3. Reusability You can use test scripts many times in various test cycles, building stages and environments. It becomes important when regression testing is required after a new software version is released. It allows us to avoid running the same tests every time the system is updated. Doing this allows for longer term improvements and time savings. 4. Improved Test Coverage Running lots of tests can be done much faster with automation, which is especially important for testing systems with lots of data, complex codes or crucial functions. More tests running leads to improved coverage of the whole system. For this reason, it allows the group to identify borders and keep the system operating properly under all situations. 5. Continuous Integration and Delivery Automated tests are compatible with CI/CD, meaning they can test the code whenever new code is put in the repository. As a result, developers get immediate feedback on their coding code. When using automated tests, it is possible to keep testing software throughout the development process which allows for quicker delivery and better-quality software. 6. Cost-Effectiveness in the Long Run Automating testing may need a bit of effort and expenses upfront, but the saving it generates over the long run is far greater. With automated tests, you don’t need to test everything manually and can easily spot glitches early which lowers costs and is time-efficient. If you do more tests, the payoff from them improves. The longer a project continues, the more money automated testing will save, particularly in cases of large software or regular maintenance. Drawbacks of Automated Testing 1. High Initial Setup Cost pg. 103 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles It takes time, effort and different resources to establish an automated testing environment. Taking on writing tests, setting up tools and using automated tests together with other applications might be challenging and demand a lot of effort. The expense and work required to set up automation are often considerable for little or medium-sized groups just starting out. 2. Requires Skilled Resources In order to design and use automated tests, testers must be familiar with programming and some automated test tools. Having no important skills can act as a hindrance for unskilled teams. Skilled developers are needed for automated tests, meaning the project often needs to either train their own staff or hire those with experience which can add to the project’s expenses. 3. Limited to Predefined Scenarios Automated tests run only what is programmed into them. When a situation or the rules change more than what was expected in the tests, the current automated tests will fail. Testing that requires following a fixed sequence works best with automation, but exploratory or unplanned testing usually needs the involvement of a human. 4. Maintenance Overhead You must keep test scripts and automation frameworks up to date and maintain them. As the application updates, it may be necessary to adapt the test scripts which can continue to increase expenses and effort. You can’t just create automated tests and leave them; you have to update them regularly as the application grows. 5. Limited User Experience Testing Tests performed by machines are unable to spot how simple the interface is, accessibility issues or the emotional reactions users have towards an application. A lot of times, these features of pg. 104 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles the software must be checked by testing personnel. Even though automation can check how a product works, it is not as good as a human at picking up issues related to design. 6. Over Reliance on Automation If you depend heavily on automated testing, you may miss certain factors that require human approach, for example, user interface or exploring new possibilities. Instead of taking over, automation should be used in addition to manual testing. If you use automated testing too much, you may find issues that manual testing would have picked up, missing some parts of testing. Automated Testing Used Tools - Pytest and Unittest Pytest and unittest are two widely used Python testing frameworks, each offering unique advantages tailored to different testing needs and developer preferences. Pytest Pytest is a modern simple and expressive syntax testing framework. devtools further allows developers to write test functions in a clean concise way without having the boilerplate that traditional testing frameworks often carry. pytest is easy to use which enables great adoption for beginners of automated testing whilst being sufficiently powerful to solve problems in larger systems. As part of pytest’s key strengths is automatic test discovery. For simple test cases, one needs to do nothing by default, pytest finds and runs tests if their name begins with test_(or Test), for example test_func() or TestClass. Moreover, pytest provides fixtures, reusable components for creating test contexts such that they can be made very easy to write maintainable tests which makes use of common setup logic like preparing of mock data. I’ve used pytest to test various components of the Sales Data Analysis System in this project. For example, the tests did verify that sales by branch were figured correctly, product price analysis was accurate and payment method distribution was taken care of. During development these functionalities were quickly tracked down and verified as correct with Pytest’s detailed output and user friendly reporting. pg. 105 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Figure 82 Pytest Testing Result On the screenshot, you see what pytest has reported after executing the tests. First, a message appears saying the tests have begun and then lines appear describing which test is being performed, for example, “Testing monthly sales analysis...” and “Testing product price analysis...”. After all the steps are completed, you receive a confirmation like, “The monthly sales analysis test is passed.” By default, pytest tells you detailed information about each test step in a straightforward way. The type of descriptive information provided is extremely useful while developing the application, because it lets the developer know precisely where the problem is. The screenshot concludes with the message “--- All tests passed! ---” which means that each test used in the suite finished successfully without any mistakes. This demonstrates that the major functions in the tested system were solid while being tested. Unittest On the flip side, unittest is Python’s very own built in testing framework and is based on xUnit architecture pattern. This forces you to write your test cases as classes with your test as a method inside these classes. It also supports setup and teardown methods that run prior to and subsequent to each test so that testing environments are readily prepared and cleaned. The nice thing about Unittest is that it is very structured which can be important for large projects with formalized standards of testing. It’s a staple in the professional Python testing world because it integrates with many development tools and continuous integration pipelines. For this project, unittest was used to invent a special test class for the Sales Data Analysis System. The tests within this class were aimed at testing a specific functionality of the system, pg. 106 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles console application such as testing totals sales aggregation and sales trend. In both cases I was able to reuse the same mock data across multiple tests, due to using setUp(). Figure 83 Unittest Testing Result This screenshot is the output from running of unittest framework. In other cases, here, each test method is listed with its name, test_analyze_product_preferences and test_analyze_sales_by_branch for example and a simple ok to indicate success. unittest summary results are slanted, so this report style is concise. Once you list all tests, the framework puts a single summary line that reports the total number of tests that ran and their duration (e.g., “5 Ran tests. in 0.023s” and then “OK” if all tests were successful. Now the default output (final line) of showing the unittest program instance (<unittest.main.TestProgram at 0x…>)… Although more verbose than pytest, this format is a quick peek into test success that’s familiar to many developers used to xUnit type test reporting. Action Plan Reducing Drawbacks through Modular Design The basic strategy to minimise the drawbacks of the data analysis system is the adoption of the modular design, the Single Responsibility Principle. The system is divided and looks in parts as each part takes its own responsibility of a specific task , sales analysis, product price analysis and payment method analysis. It separates this out and therefore simplifies development and testing and debugging. As an example, suppose that when an issue occurs in a certain product pricing module, the developers can worry only about that particular module without thinking of any undesired impacts on the sales analysis module. Also, the modular design supports future system improvements where new features can be seamlessly integrated by adding or upgrading individual modules, without rewriting the complete system. Ensuring Reliability with Automated Testing pg. 107 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Maintaining the system’s quality and reliability highly depends on automated testing. With the use of testing frameworks like pytest and unittest, extensive tests were composed which encompass all the critical functions of the system. These tests require the same calculations of sales totals, product preferences and payment distributions that are taken into system. Testing automation provides the ability to find bugs early during the development time, fast feedback for the developers and stop regressions which are when new code breaks existing functionality. For instance, if a new update somehow tweaked how sales data are aggregated, the automated tests will identify and flag that problem straight away before the system is deployed, so that it won’t have an impact on end users. Using Mock Data for Robust Test Coverage Augmenting the testing of the system, well designed data emulations represent real-life scenarios the system will be exposed to. This approach allows for verification of system behavior to multiple data input, where some edge cases may be less probable in real operation but which may fail if unhandled. For instance, in the mock data there are many branches, products and types as well to ensure the systems performs aggregations and inspections properly throughout different categories. Unit testing with fake data guarantess the system stability and appearence, increasing confidence the system will work as expected in production. Planning for Better Error Handling and Data Validation Currently, although the system is able to effectively handle realistic data values, more robust error checking and data validation are acknowledged as necessary. This future extension will allow the system to recognize corrupt, bad, or out-of-order data inputs and respond in a graceful manner, for example by skipping bad records and reporting to the user rather than aborting. E.g., if there is a sales entry which has an invalid product name or even has negative sales, strong validation will catch such anomalous cases and avoid them to trigger runtime errors. The introduction of such measures will lead to greater system resiliency, enhance the User experience and reliably reduce the occurrence of unforeseen system crashes while giving clearer direction with regard to data issues. Plan B - Fallback Procedures in Case of Failure Manual Data Analysis as a Temporary Solution pg. 108 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles However, and despite the best efforts to develop an automatic system, there may be unexpected failures. A manual data analysis is planned ready as a contingency against business disruption. In both these cases raw sales data is exported into spreadsheets, like Microsoft Excel for analysts to manually calculate key metrics with formulas and pivot tables. This is a more tedious anda human prone process, but it is a way to ensure that management will not be disconnected from valuable sales insights until the automated system is fixed. It is this manual fall back that serves as a safety net to avoid complete loss of analytical power during system downtime. Backup Lightweight Scripts for Core Analysis Simple version of the analysis scripts are kept separately as a contingency. These are the lightweight scripts written to scratch the analysis itches - think adding sales totals together by branch or product - without needing complex, automated charts or reports. These scripts can be deployed quickly if all of the system break but less power-hungry and easier to operate. This disaster failover option ensures that urgent sales data is replicated and guarantees that a sales operation is not disrupted by system downtime. Fast Issue Diagnosis and Recovery When a system fails, it must be identified and resolved as fast as possible. The action plan includes the addition of mechanism for detailed system state and input data logging and error report to capture environment and system state and input data as they are at the time of system failure. With these data points developers can diagnose the root cause more efficiently and speed up repair. Furthermore, as long as code is under rigorous version control and submitted to peer review, this process can be switched back to a known stable copy of the software if recent updates lead to bugs. Combined, these practices lower downtime and return the system to functionality quickly with as little data loss and operational disruption as possible. Future Plans for Cloud-Based Redundancy For future work, the deployment of the data analysis system on cloud infrastructure with built in redundancy is planned in order to enhance resilience and availability. The system can be deployed into multiple instances on different geographic locations and failover is automatic if one instance fails i.e., it is available as a cloud platform. Because of this setup, access to sales analytics is continuous and the risk of a complete outage is significantly cut down. In addition, cloud based deployment makes it simpler to scale when data volume increases and provides pg. 109 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles out of the box monitoring tools for proactively checking the health of the system. These enhancements put us on a path to utilizing best practices for mission critical business applications including high reliability. Developer-Based Automated Testing Tools Typically, open-source frameworks or libraries called developer-based tools are used by developers in their day-to-day software development process. They give great flexibility since developers are able to create unique test scripts that address just the needs of their application. Because these tools are for coders, they are mostly accessed by developers who feel at ease performing testing tasks alongside application development. There are many free tools for developers that work together with groups committed to making them better every day. Pytest is used for Python, JUnit for Java and Selenium WebDriver for browser automation. Even though these tools can do a lot, developers need special skills and must put in continuous work to manage the test suite as the software changes. Importance of Using Developer-Based Automated Testing Tools Typically, developer based automated testing tools are frameworks or libraries created by developers for developers. All the tools here are open source or free and allow you to produce highly customized test scripts and integration with development lifecycle. Compared to other tools on this list, these tools will require you to be familiar with programming in order to use them effectively, but they still have unique advantages which are great for teams with strong development skills to get in your testing environment. An exploration into why developer based automated testing tools are important is below. 1. Flexibility and Customization Flexibility is one of the primary reasons of using developer based automated testing tools. There are ways, however, for developers to customize (or even create from scratch) test cases, frameworks and scripts to meet the specific needs of their application. One such example included in Pytest (Python) or JUnit (Java), enables teams to write a custom test case from their application logic. One of the advantages here is this flexibility, that allows the testing framework to adjust to the requirements that quite often are not supported by vendor based pg. 110 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles tools. Therefore, teams can concentrate on testing particular application behaviours, i.e. complicated business logic, that is certainly out of this out from the box answers. 2. Cost-Effectiveness Often, open source or free developer based testing tools are the best fit for companies that are low on budget or do not have the desire to maintain a continuous commercial software cost. Selenium, JUnit and Mocha are all available freely so you can do a lot with automated testing for little or no cost. When it comes to startups or small teams, it’s important to spend the money wisely and that’s where this stands out, because these guys offer high quality testing frameworks while keeping things in the most reasonable budgets. 3. Integration with Development and Continuous Integration (CI) Systems The testing tools that are designed to allow developers to seamlessly do their testing are also designed to seamlessly fit into existing development workflow as well as CI/CD systems. Selenium WebDriver works great with popular CI tool such as Jenkins which allows the teams to automate the tests as part of continuous integration pipeline. With this tight integration teams are able to automate tests quickly within the development cycle, catching issues earlier and saving time between development and production deployment. Furthermore, most of these tools can be configured quite quickly in IDEs and can be tuned to be executed in parallel over multiple machines or environments. 4. Full Control over Test Design With developer based tools it’s up to the developer to define how the tests get designed, executed and reported. For example, pytest developers can compose complex test scenarios, define reusable fixture and perform parametrized testing to test every corner of codebase. Because of this level of control, developers can be exacting in their test strategies and achieve the particular requirements of their applications, but also address edge cases that could not be (easily) accomplished by rigid, vendor based solutions. 5. Community Support and Documentation But the most important benefit of developer based tools is that support community is strong. Fortunately, many of these tools are open source, meaning they get great development from a team of developers constantly improving them, collaborating and passing on shared knowledge and support through forums, Stack Overflow and GitHub repositories. More generally, they pg. 111 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles also come with comprehensive documentation, so that developers can easily learn how to use the tools in their projects. Open source tools are collaborative which leads to innovation and improvements become available continuously to fix bugs quickly and add new features. Vendor-Based Automated Testing Tools Commercial automated testing tools from companies are made to be simple to use and full of useful features. These tools feature intuitive user interfaces, the ability to record and replay tests and many tools for managing tests, so people with little programming knowledge can benefit from them. A big advantage for teams needing reliable, supported software is that vendor-based tools include official support, relevant training and documentation. As a rule, you’ll have to pay for a license or subscription which may not be affordable for everyone. Some examples are Micro Focus UFT (Unified Functional Testing), TestComplete and Ranorex. Regardless, testing with these tools can be easier, yet their efforts at customization might not always be up to par with frameworks made by software developers. Importance of Using Vendor-Based Automated Testing Tools Commercial vendors provide the vendor based automated testing tools for streamlining the software testing process with more features, friendly user interface and lots of support. Notwithstanding the costs which accompany these tools, they have their place, in certain environments. Below are several reasons why software development teams need to use vendor based automated testing tools. 1. User-Friendly Interface User friendly interface is one of most important advantages of vendor based automated testing tools. For that reason, these tools are often built keeping non–developers, for example, QA engineers, business analysts and other stakeholders with low programming experience, in mind to easily create, execute tests and manage tests. Vendor based tools are often equipped with drag and drop functionality, record and playback features and interactive dashboards which targeting team that wants to use automated testing without having a deep technical background. 2. Comprehensive Features and Capabilities pg. 112 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Besides test execution, vendor based tools encompass a complete suite of features. It contains built in test management and reporting, performance testing and integration with CI/CD pipelines. I intend these tools to be part of an entire suite of tools geared to function, regression, performance as well as security testing. All in one nature of these tools offer to team a uniform way of automating, managing and tracking of the test without going through the trouble of managing the different disparate tools. 3. Official Support and Training Organizations which procure testing tools from vendors are able to receive vendor provided official support which ever proves to be a huge advantage for those looking to keep their test operations running smoothly and seamlessly. Vendors of most such products provide 24/7 technical support, documentation, tutorials and troubleshooting help to fix problems fast and efficiently. Vendors also provide programs to train the team members and certification courses to ensure that the staff is well versed with usage of the tool and, also, the best practices for test automation. 4. Faster Implementation and Setup Tools based on vendors are often built to be quickly implemented using pre built templates that tie in with common development environments and tools. This translates into the fact that teams can get started with automation testing much quicker than writing a custom solution from scratch. Due to easy setup and configuration, as well as a good documentation on the web, it is really possible to start using it with a next to none delays which is essential in the world of a fast development cycles. 5. Reliability and Proven Solutions There are many well known and real world proven, vendor based testing tools that are very reliable. These tools come from established vendors and are therefore developed and maintained and hence have iterated many times, been improved and updated for stability, scalability and accuracy. It allows teams to have confidence that they are using a solution that's known to work in different environments and thousands of other companies trust it, too. Comparison of Both Approaches pg. 113 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Table 12 Comparison Table Aspect Developer-Based Tools Vendor-Based Tools Cost Mostly free/open source Paid licenses/subscriptions Flexibility High, full control via code Moderate, GUI and pre-built features Ease of Use Requires programming skills User-friendly GUI, less coding required Support Community-driven Integration Easily integrated into CI/CD Often pipelines Official vendor support and training includes integrated test management Customization Highly customizable via code Limited to tool capabilities Examples Micro Focus UFT, TestComplete, Pytest, JUnit, Selenium Ranorex The main difference between the two types of testing tools is how flexible they are, versus how simple it is to use them. Because of their coding nature, developer-focused tools are highly versatile for groups with good programming knowledge and plenty of testing needs. Alternatively, vendor-based testing tools are built to be simple, so testing even without much coding knowledge is possible for many. On the other hand, these benefits can be countered by reduced flexibility and greater costs because of licensing charges. Pytest and JUnit make it easy for programmers to test individual parts of the application closely which speeds up development by providing fast feedback. Those who understand programming best take advantage of Selenium WebDriver to automate browser testing. Alternatively, Micro Focus UFT includes all tools needed for functional and regression testing, with handy options for capturing and editing test scripts used by testers who want to write less code. By offering codeless automation, TestComplete and Ranorex allow testing teams who lack coding skills to finish their work in less time. Many organizations pick tools from vendors so that testing processes can be followed by large workgroups and environments that need ease of use and quick assistance. pg. 114 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles Reference list geeksforgeeks (2019). SOLID Principle in Programming: Understand With Real Life Examples. [online] GeeksforGeeks. Available at: https://www.geeksforgeeks.org/solidprinciple-in-programming-understand-with-real-life-examples/ [Accessed 11 May 2025]. Herrity, K. (2023). What Are the Four Basics of Object-Oriented Programming? | Indeed.com. [online] www.indeed.com. Available at: https://www.indeed.com/career-advice/careerdevelopment/what-is-object-oriented-programming [Accessed 10 May 2025]. www.tutorialspoint.com. (n.d.). Python - OOP Concepts. [online] Available at: https://www.tutorialspoint.com/python/python_oops_concepts.htm [Accessed 10 May 2025]. pg. 115 J.K. Induwara Hasaranga / E236222 / Unit 20: Applied Programming and Design Principles
0
You can add this document to your study collection(s)
Sign in Available only to authorized usersYou can add this document to your saved list
Sign in Available only to authorized users(For complaints, use another form )