From da9d26cf15fa2ad7eb793045ca6490b48416406e Mon Sep 17 00:00:00 2001 From: Shaun Reed Date: Tue, 11 May 2021 16:03:03 -0400 Subject: [PATCH] Add example of bridge pattern in C++ --- cpp/patterns/bridge/CMakeLists.txt | 21 ++++++++++++++ cpp/patterns/bridge/abstraction.cpp | 10 +++++++ cpp/patterns/bridge/abstraction.hpp | 40 ++++++++++++++++++++++++++ cpp/patterns/bridge/implementation.cpp | 2 ++ cpp/patterns/bridge/implementation.hpp | 38 ++++++++++++++++++++++++ cpp/patterns/bridge/main.cpp | 28 ++++++++++++++++++ 6 files changed, 139 insertions(+) create mode 100644 cpp/patterns/bridge/CMakeLists.txt create mode 100644 cpp/patterns/bridge/abstraction.cpp create mode 100644 cpp/patterns/bridge/abstraction.hpp create mode 100644 cpp/patterns/bridge/implementation.cpp create mode 100644 cpp/patterns/bridge/implementation.hpp create mode 100644 cpp/patterns/bridge/main.cpp diff --git a/cpp/patterns/bridge/CMakeLists.txt b/cpp/patterns/bridge/CMakeLists.txt new file mode 100644 index 0000000..119b1cf --- /dev/null +++ b/cpp/patterns/bridge/CMakeLists.txt @@ -0,0 +1,21 @@ +############################################################################### +## Author: Shaun Reed ## +## Legal: All Content (c) 2021 Shaun Reed, all rights reserved ## +## About: A project for practicing the bridge C++ design pattern ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +############################################################################## +# +cmake_minimum_required(VERSION 3.15) +project( + #[[NAME]] Bridge + VERSION 1.0 + DESCRIPTION "An example of the bridge design pattern in C++" + LANGUAGES CXX +) +add_compile_options("-Wall") + +add_library(abstraction "abstraction.cpp") +add_library(implementation "implementation.cpp") +add_executable(bridge-test "main.cpp") +target_link_libraries(bridge-test abstraction implementation) diff --git a/cpp/patterns/bridge/abstraction.cpp b/cpp/patterns/bridge/abstraction.cpp new file mode 100644 index 0000000..ecb3f2e --- /dev/null +++ b/cpp/patterns/bridge/abstraction.cpp @@ -0,0 +1,10 @@ + +#include "abstraction.hpp" + +int VerboseCalculator::doMath(const int &a, const int &b) const +{ + int result = method->math(a, b); + std::cout << "Performing " << method->getName() << " on input: a = " << a + << ", b = " << b << std::endl << "Result: " << result << std::endl; + return result; +} diff --git a/cpp/patterns/bridge/abstraction.hpp b/cpp/patterns/bridge/abstraction.hpp new file mode 100644 index 0000000..eb4ab91 --- /dev/null +++ b/cpp/patterns/bridge/abstraction.hpp @@ -0,0 +1,40 @@ + +#ifndef ABSTRACTION_HPP +#define ABSTRACTION_HPP + +#include +#include + +#include "implementation.hpp" + +// Abstract calculator that can only perform one operation +class Calculator { +public: + explicit Calculator(Implementation *method_) : method(method_) {} + + virtual std::string getName() const = 0; + virtual int doMath(const int &a, const int &b) const = 0; + +protected: + Implementation *method; +}; + +// Simple calculator that can only perform one operation +class SimpleCalculator : public Calculator { +public: + explicit SimpleCalculator(Implementation *method_) : Calculator(method_) {} + + inline std::string getName() const override { return method->getName();} + inline int doMath(const int &a, const int &b) const override { return method->math(a, b);} +}; + +// Verbose calculator that prints information on method performed and result +class VerboseCalculator : public Calculator { +public: + explicit VerboseCalculator(Implementation *method_) : Calculator(method_) {} + + inline std::string getName() const override { return method->getName();} + int doMath(const int &a, const int &b) const override; +}; + +#endif // ABSTRACTION_HPP diff --git a/cpp/patterns/bridge/implementation.cpp b/cpp/patterns/bridge/implementation.cpp new file mode 100644 index 0000000..9e5f1ec --- /dev/null +++ b/cpp/patterns/bridge/implementation.cpp @@ -0,0 +1,2 @@ + +#include "implementation.hpp" diff --git a/cpp/patterns/bridge/implementation.hpp b/cpp/patterns/bridge/implementation.hpp new file mode 100644 index 0000000..33ba667 --- /dev/null +++ b/cpp/patterns/bridge/implementation.hpp @@ -0,0 +1,38 @@ + +#ifndef IMPLEMENTATION_HPP +#define IMPLEMENTATION_HPP + +#include + +// Base class for abstract implementation +class Implementation { +public: + explicit Implementation(std::string name_) : name(std::move(name_)) {} + virtual ~Implementation() = default; + + inline std::string getName() const { return name;} + + virtual int math(const int &a, const int &b) const = 0; + +private: + std::string name; +}; + +// Concrete Add implementation +class Add : public Implementation { +public: + explicit Add(std::string name_="Add") : + Implementation(std::move(name_)) {} + + inline int math(const int &a, const int &b) const override { return a + b;} +}; + +// Concrete Subtract implementation +class Subtract : public Implementation { +public: + explicit Subtract(std::string name_="Subtract") : + Implementation(std::move(name_)) {} + inline int math(const int &a, const int &b) const override { return a - b;} +}; + +#endif // IMPLEMENTATION_HPP diff --git a/cpp/patterns/bridge/main.cpp b/cpp/patterns/bridge/main.cpp new file mode 100644 index 0000000..fd53c08 --- /dev/null +++ b/cpp/patterns/bridge/main.cpp @@ -0,0 +1,28 @@ + +#include +#include +#include + +#include "abstraction.hpp" +#include "implementation.hpp" + +int main(const int argc, const char * argv[]) { + Add *add = new Add; + SimpleCalculator adder(add); + const int a = 5; + const int b = 10; + std::cout << "A = " << a << "\nB = " << b << std::endl; + + std::cout << "\nTesting " << adder.getName() << ".doMath(a, b)...\n"; + std::cout << "Result: " << adder.doMath(a, b); + + auto *sub = new Subtract; + SimpleCalculator subtractor(sub); + std::cout << "\n\nTesting " << subtractor.getName() << ".doMath(a, b)...\n"; + std::cout << "Result: " << subtractor.doMath(a, b); + + // Testing extension of abstraction + std::cout << "\n\nTesting VerboseCalculator.doMath(a, b)...\n"; + VerboseCalculator verboseCalculator(add); + verboseCalculator.doMath(a, b); +}