Summary

This document is a lecture on SOLID design principles used in software development. It covers topics like the Single Responsibility Principle (SRP) and the Open/Closed Principle (OCP). The lecture also discusses the importance of minimizing software complexity and maximizing flexibility and maintainability in design.

Full Transcript

1 SOLID Design CSCI 2134: Software Development Agenda Lecture Contents Goal of good design Characteristics of good design SOLID Principles Brightspace Quiz Readings: This Lecture: Chapter 5 Next Lecture: Chapter 5 3 Goals of Go...

1 SOLID Design CSCI 2134: Software Development Agenda Lecture Contents Goal of good design Characteristics of good design SOLID Principles Brightspace Quiz Readings: This Lecture: Chapter 5 Next Lecture: Chapter 5 3 Goals of Good Design Satisfy requirements Minimize complexity The primary problem of software development is managing complexity A good design reduces complexity through techniques such as Abstraction Decomposition Encapsulation Complexity cannot be eliminated, but it can be managed Maximize flexibility Requirements change over the course of the project A good design is flexible, accommodates change, and reduces the amount of changes in implementation as well Maximize maintainability Understandability Readability 5 Why is Software Complex? Software models the real world The real world is complex Large software systems have to: Interact with a variety of users Interact with a variety of systems Interact with a complex world Meet a variety of different requirements Large software systems are built without ever completely understanding the entire problem 6 Example: Hammer.jar 7 Characteristics of Good Design Minimal complexity Flexibility Loose (low) coupling Adaptability Low-to-medium fan-out: single class Extensibility does not use too many other classes Portability Leanness: minimum amount of code Stratification: layering Standard techniques Maintainability Reusability Understandability Readability High fan-in: single class is used by many classes) 8 Two Common Design Criteria Cohesion: a measure of relatedness to a single idea or responsibility of a class Coupling: a measure of dependence between classes or packages 9 Cohesion Cohesion is a measure of relatedness to a single idea or responsibility of a class A measure of how well everything sticks together Aim for high cohesion Low cohesion means that either Too many methods or classes are needed to complete a simple task (because the functionality is fragmented) or One method or class has multiple functions, which makes the code difficult to understand Key Ideas: Each class should represent a single concept All methods of the class should be directly applicable to the concept Classes that are multi-concept or have unrelated methods reduce cohesion and indicate improvements are needed to the design. 10 Cohesion Bad cohesion Good cohesion Too fragmented Bad cohesion Overloaded 11 Example: Bad vs Good Cohesion public class Car { public class Car { int engineSize; Engine engine; int gasTankSize; Transmission transmission; boolean diesel; FuelTank fuelTank; boolean autoTransmission; … … } } public class Engine { public class Transmission { public class FuelTank { int size; boolean automatic; int size boolean diesel; … … … } } } Coupling Coupling is the density of dependencies among classes High coupling means there are many dependencies Low coupling means there are few dependencies Low coupling is preferred If a class changes and there is high coupling, many other classes will need to change as well Coupling High Coupling / Low Coupling / Tight Coupling Loose Coupling 14 SOLID: Maximize Cohesion & Reduce Coupling SOLID is a set of basic object-oriented design principles for better design Uses: Use SOLID principles to create code that is flexible and minimizes complexity Use class-level refactoring to apply SOLID principles to classes that violate these principles SOLID stands for: Single Responsibility Principle (SRP) Open / Closed Principle (OCP) Liskov Substitution Principle (LSP) Interface Segregation Principle (ISP) Dependency Inversion Principle (DSP) 15 SOLID - Single Responsibility Principle (SRP) Multiple Responsibilities Single Responsibilities 16 SOLID - Single Responsibility Principle (SRP) Principle: Each class represents a single concept, role, or function “Every module or class should have responsibility over a single part of the functionality provided by the software, and that responsibility should be entirely encapsulated by the class.” - Wikipedia “A class should have only one reason to change.” - Robert C. Martin (Uncle Bob) Purpose: Improves cohesion and reduces coupling Notes: A class may have multiple methods, but these methods are all related to the same concept If there are two unrelated methods in the same class, this is a sure sign that the SRP has been violated 17 Example of SRP Violation: Scenario: Single class in an E-commerce system that Accepts orders from a web page Saves the order to the database ECommerce Emails the customer + acceptOrderFromCustomer() Code smell: + saveOrderToDatabase() Three different functions in one class + emailCustomer() Three unrelated dependencies Input source Database API How email is sent Bad design choice because: Multiple functionality is coupled together Changing one part of the class could break another part 18 Fixing an SRP Violation To fix a single responsibility violation we typically split the offending class into multiple classes, each with a single responsibility Order Input Database Email Input Database Email 19 public class User { private int id; private String firstName; Another Example private String lastName; private String email; of SRP Violation public User(String firstName, String lastName, String email) { this.firstName = firstName; this.lastName = lastName; this.email = email; Primary function: } Store a user public boolean isValid(){ return (firstName != "" && firstName != null && lastName != "" && lastName != null && email != "" && email != null); } public String displayName() { if (isValid()) { return "" + firstName + " " + lastName + "" + email + ""; Secondary function } else { Output HTML return "INVALID!"; } } 20 } public class User { private int id; private String firstName; private String lastName; private String email; SRP Fix public User(String firstName, String lastName, String email) { this.firstName = firstName; this.lastName = lastName; this.email = email; } Primary function: public boolean isValid(){ Store a user return (firstName != "" && firstName != null && lastName != "" && lastName != null && email != "" && email != null); } } public class HTMLUser extends User { public HTMLUser(String firstName, String lastName, String email) { super(firstName, lastName, email); Secondary function } Output HTML public String displayName() { if (isValid()) { return "" + firstName + " " + lastName + "" + email + ""; } else { return "INVALID!"; } } 21 } SOLID – Open/Close Principle (OCP) Principle: Classes should be extendable but not modifiable. “Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification” - Object-Oriented Software Construction, Bertrand Meyer Write once – Use many There should be no need to modify a class to extend functionality. Definitions: A class is open, if fields can be added, data structure changed, or internal functions modified A class is closed, If it can be safely used by other classes because it will not be modified 23 SOLID – Open/Close Principle (OCP) Purpose: reduce coupling If class A uses class B, this creates coupling. If class B is modified, this forces class A to be modified. If class B is closed, the coupling is less dangerous Goal is to design classes that, once completed and tested, should never need to be modified again. All extensions are done through subclasses 24 SOLID – Open/Close Principle (OCP) Example of an OCP violation: An insurance company has a number of different policies The business rules are encoded in a the InsurancePolicy class Every time a new kind of insurance product is created, the InsurancePolicy class needs to be modified Code Smell: This class may need to be modified in the future for other reasons than defect fixing! Class cannot be extended without modifying it. 25 Example of OCP Violations Example from http://joelabrahamsson.com/a-simple-example-of-the-openclosed-principle/ // This class violates the Open/Closed principle. public class Rectangle { // Why? private float height; private float width; public class AreaCalculator { public static float Area(Rectangle[] shapes) { public Rectangle(float height, float width) { float area = 0.0f; this.height = height; for (int i = 0; i < shapes.length; i++) { this.width = width; area += shapes[i].getHeight() * } shapes[i].getWidth(); } public float getHeight() { return area; return height; } } } Are there other public float getWidth() { shapes beyond return width; rectangles? } } YES! 26 Example of OCP Violations Example from http://joelabrahamsson.com/a-simple-example-of-the-openclosed-principle/ // This class violates the Open/Closed principle. public class Rectangle { // Why? private float height; private float width; public class AreaCalculator { Danger Danger! … public static float Area(Object[] shapes) { } float area = 0.0f; for (int i = 0; i < shapes.length; i++) { public class Circle { if (shapes[i] instanceof Rectangle) { private float radius; Rectangle rect = (Rectangle) shapes[i]; area += rect.getHeight() * public Circle(float radius) { rect.getWidth(); this.radius = radius; } else if (shapes[i] instanceof Circle) { } Circle circle = (Circle) shapes[i]; area += circle.getRadius() * public float getRadius() { circle.getRadius() * Math.PI; return radius; } } } Are we deciding } how to treat an return area; } object using an YES! } if or a switch? 27 Example of Fixing the OCP Violations Example from http://joelabrahamsson.com/a-simple-example-of-the-openclosed-principle/ // This class adheres to the Open/Closed principle. public class Rectangle implements IShape { // It never needs to change, for the rest of time private float height; // this class can calculate the total area of any private float width; // objects passed to it, so long as those objects // implement the area() method of the IShape … // interface contract. public float area() { public class AreaCalculator { return height * width; public static float Area(IShape[] shapes) { } float area = 0.0f; } for (int i = 0; i < shapes.length; i++) { area += shapes[i].area(); } All shapes that public class Circle implements Ishape { return area; private float radius; } implement the } IShape interface … public float area() { public interface IShape { return radius * radius * Math.PI; public float area(); } } } As long as a Shape implements the IShape interface, AreaCalculator will never change! 28 Key Points Good design reduces complexity and improves flexibility and maintainability Coupling and cohesion are two measures of good design, with low coupling and high cohesion leading to lower complexity and better flexibility and maintainability SOLID is a set of object-oriented design principles intended to reduce complexity The Single Responsibility Principle states that each class should have a single responsibility The Open/Closed Principle states that classes should be designed to be extendable (open) but not modifiable (closed) 29 Image References Retrieved January 29, 2020 http://pengetouristboard.co.uk/vote-best-takeaway-se20/ Image from StackOverflow, attributing it to https://www.coursera.org/lecture/object-oriented-design/1-3-1-coupling-and-cohesion- q8wGt https://library.kissclipart.com/20181002/cae/kissclipart-printer-icon-clipart-printer- computer-icons-clip-a-4355e69e2147b9a3.png http://clipart-library.com/printer-cliparts.html https://lh3.googleusercontent.com/proxy/Bln9JbfTJUZLqFBN6I5cBSMl6ww_z31qieplSeIl FzI3y7tMvFUIyPtWt-2HGgx3DGSYRC6lD-PmfiFz7Qc1XodvqTTmArCdcg https://lh3.googleusercontent.com/proxy/EjmkwGKjVndigDIQa4BpI6eQHDucnKJJ47EVJC LlHgP0c3SX16aHum4kGVL0Q6uEQrc1gaGh6jD7lpPMYm2GQSoAT3L_RQfQ6_nw https://cdn3.vectorstock.com/i/1000x1000/56/72/car-rental-car-for-rent-word-on-red- ribbon-vector-26835672.jpg Retrieved November 18, 2020 https://images.slideplayer.com/25/8104238/slides/slide_7.jpg 30

Use Quizgecko on...
Browser
Browser