Explore 1.5M+ audiobooks & ebooks free for days

Only $12.99 CAD/month after trial. Cancel anytime.

Software Design Simplified
Software Design Simplified
Software Design Simplified
Ebook163 pages1 hour

Software Design Simplified

Rating: 0 out of 5 stars

()

Read preview

About this ebook

This book is a comprehensive guide to understanding and implementing design patterns and SOLID principles in C++. The book is designed for both novice and experienced programmers who want to improve their understanding of software design and development in C++.

Design patterns are reusable solutions to common problems that arise in the design of object-oriented systems. They provide a way to structure and organize code, making it more flexible, maintainable and extensible. This book covers the most commonly used design patterns in C++, such as the Singleton, Factory, Observer, and Decorator patterns. Each pattern is explained in detail, with real-world examples and C++ code snippets that demonstrate how to implement the pattern in an actual C++ application.

In addition to design patterns, the book also covers SOLID principles, which are a set of guidelines for writing maintainable and extensible code. The SOLID principles are widely considered to be best practices in object-oriented software development, and this book explains how they can be applied in a C++ context.

Throughout the book, you will find practical examples that will help you understand and apply the concepts presented. If the code examples are too complicated the code will be split in multiple header files and implementation files and you will find the main function appearing first in the code in order to give you an overview of what the intent of the design pattern is. Hopefully this will also give you a hint about what all the classes that follow are supposed to do. Otherwise, if the examples are not so complex, the main function is last and all the code is written in the same file. Also, sometimes, if the code is too complex, too make it easier to understand, using namespace std is used at the beginning of the file in order to avoid the std:: repetition.

Whether you are a beginner or an experienced programmer, this book will help you to improve your C++ programming skills and write better, more maintainable, and more extensible code.

LanguageEnglish
PublisherLiviu Catalin Dorobantu
Release dateMay 20, 2024
ISBN9798224380282
Software Design Simplified

Related to Software Design Simplified

Related ebooks

Programming For You

View More

Reviews for Software Design Simplified

Rating: 0 out of 5 stars
0 ratings

0 ratings0 reviews

What did you think?

Tap to rate

Review must be at least 10 words

    Book preview

    Software Design Simplified - Liviu Catalin Dorobantu

    Preface

    ––––––––

    This book is a comprehensive guide to understanding and implementing design patterns and SOLID principles in C++. The book is designed for both novice and experienced programmers who want to improve their understanding of software design and development in C++.

    Design patterns are reusable solutions to common problems that arise in the design of object-oriented systems. They provide a way to structure and organize code, making it more flexible, maintainable and extensible. This book covers the most commonly used design patterns in C++, such as the Singleton, Factory, Observer, and Decorator patterns. Each pattern is explained in detail, with real-world examples and C++ code snippets that demonstrate how to implement the pattern in an actual C++ application.

    In addition to design patterns, the book also covers SOLID principles, which are a set of guidelines for writing maintainable and extensible code. The SOLID principles are widely considered to be best practices in object-oriented software development, and this book explains how they can be applied in a C++ context.

    Throughout the book, you will find practical examples that will help you understand and apply the concepts presented. If the code examples are too complicated the code will be split in multiple header files and implementation files and you will find the main function appearing first in the code in order to give you an overview of what the intent of the design pattern is. Hopefully this will also give you a hint about what all the classes that follow are supposed to do. Otherwise, if the examples are not so complex, the main function is last and all the code is written in the same file. Also, sometimes, if the code is too complex, too make it easier to understand, using namespace std is used at the beginning of the file in order to avoid the std:: repetition.

    Whether you are a beginner or an experienced programmer, this book will help you to improve your C++ programming skills and write better, more maintainable, and more extensible code.

    SOLID Principles

    SOLID is an acronym for five principles of object-oriented design that were first introduced by Robert C. Martin in his book Agile Software Development, Principles, Patterns, and Practices. These principles are:

    Single Responsibility Principle (SRP): A class should have only one reason to change. This means that a class should have only one responsibility and should not be responsible for multiple things.

    Let’s take a look at the following class:

    class Order {

    public:

    void save() {

    // Saving order to the database

    }

    void send_email() {

    // Sending email to the customer

    }

    void print_invoice() {

    // Printing invoice

    }

    };

    The above class violates the SRP principle, because it has three responsibilities: saving to the database, sending email to the customer and printing invoice. The solution would be to split the class into three different classes each with one responsibility.

    class Order {

    private:

    int id_;

    std::string customer_;

    double amount_;

    public:

    Order(int id, std::string customer, double amount) : id_(id), customer_(customer),

    amount_(amount) {}

    int get_id() { return id_; }

    std::string get_customer() { return customer_; }

    double get_amount() { return amount_; }

    };

    class OrderDatabase {

    public:

    void save(Order& order) {

    // Saving order to the database

    std::cout << Order saved to database: << order.get_id() << std::endl;

    }

    };

    class EmailSender {

    public:

    void send_invoice(Order& order) {

    // Sending invoice email to the customer

    std::cout << Invoice email sent to: << order.get_customer() << std::endl;

    }

    };

    class InvoicePrinter {

    public:

    void print(Order& order) {

    // Printing invoice

    std::cout << Invoice printed for order: << order.get_id() << for amount: <<  

    order.get_amount() << std::endl;

    }

    };

    In this example, the Order class has a single responsibility of storing the data related to the order. The OrderDatabase class has a single responsibility of saving the order to the database, the EmailSender class has a single responsibility of sending the invoice email to the customer and the InvoicePrinter class has a single responsibility of printing the invoice. Each class has a single, well-defined responsibility and can be easily reused and tested independently.

    Open-Closed Principle (OCP): A class should be open for extension but closed for modification. This means that a class should be designed in such a way that it can be extended to add new functionality without modifying its existing code.

    Let’s take a look at the following class:

    class Order {

    private:

    double base_price_;

    double tax_;

    public:

    Order(double base_price) : base_price_(base_price) {}

    double get_total_price() { return base_price_ + tax_; }

    };

    The above class violates the OCP principle because if we want to change the tax calculation method, we have to modify the existing class. The solution would be to create a separate class for tax calculation and make the Order class depend on it:

    class TaxCalculator {

    public:

    virtual double calculate(double base_price) = 0;

    };

    class Order {

    private:

    double base_price_;

    std::unique_ptr tax_calculator_;

    public: 

    Order(double base_price, std::unique_ptr tax_calculator) :  

    base_price_(base_price), tax_calculator_(std::move(tax_calculator)) {}

    double get_total_price() {

    return base_price_ + tax_calculator_->calculate(base_price_);

    }

    };

    In this example, the Order class is closed for modification, as we can change the tax calculation method by creating a new class that implements the TaxCalculator interface and passing an instance of it to the Order class, without changing the Order class itself.

    Liskov Substitution Principle (LSP): Subtypes should be substitutable for their base types. This means that objects of a superclass should be able to be replaced by objects of a subclass without affecting the correctness of the program.

    Let’s take a look at the following code:

    class Rectangle {

    protected:

    int width_;

    int height_;

    public:

    Rectangle(int width, int height) : width_(width), height_(height) {}

    virtual int get_width() { return width_; }

    virtual void set_width(int width) { width_ = width; }

    virtual int get_height() { return height_; }

    virtual void set_height(int height) { height_ = height; }

    virtual int get_area() { return width_ * height_; }

    };

    class Square : public Rectangle {

    public:

    Square(int size) : Rectangle(size, size) {}

    void set_width(int width) override {

    width_ = height_ = width;

    }

    void set_height(int height) override {

    width_ = height_ = height;

    }

    };

    The above example violates the LSP principle, because the Square class is not substitutable for its base class Rectangle. When we call set_width or set_height methods on a square it changes the height and width to the same value, but a rectangle can have different width and height values, so the behavior

    Enjoying the preview?
    Page 1 of 1