Skip to content
This repository has been archived by the owner on Nov 7, 2024. It is now read-only.

A multi-language library containing implementations of common software design and architecture patterns

Notifications You must be signed in to change notification settings

nic-dgl104-winter-2024/pattern-library

Repository files navigation

DGL 104 Pattern Library

Design Patterns

Design patterns are like templates or solutions to common problems encountered in software design. They represent the best practices used by experienced object-oriented software developers. Design patterns are about reusing designs that have been proven effective, rather than reinventing the wheel. They help you solve specific problems in your code, making your software easier to understand, maintain, and scale.

Design templates work as a key to producing a perfect and functional framework and are helpful for developers in easily comprehending their code. In addition to solving common problems, they help to avoid duplication that would arise if the code was not moduled.

Here's a brief overview and a list of some fundamental design patterns, divided into three main categories:Β 

See the Design Patterns section

Documentation Table of Contents

Library Table of Contents

Definition of Observer Pattern

The observer pattern is a behavioral design pattern often used in software development.

The purpose of the observer pattern is to establish a one-to-many dependency between objects. An object known as the subject maintains a list of its dependents, called observers. The subject automatically notifies these observers of any state changes it undergoes, typically achieved by invoking one of their methods.

This pattern is often employed in software systems to ensure consistency among multiple components or to notify interested parties about specific events.

As an example, consider a scenario using the analogy of a publisher/subscriber relationship. In this analogy, the publisher acts as the subject, while the subscribers represent the observers. Whenever a significant event occurs to the publisher, it notifies the subscribers by invoking specific notification methods on their objects. This process ensures that subscribers are quickly informed of important updates.

References

Singleton Pattern

Definition of Singleton Pattern

Singleton is a creational design pattern that uses a single class that can only be instantiated once. This class allows you to easily access its single object from anywhere in the codebase without having to create new or additional instances of the class. This is because the goal is to have only one instance of a class throughout an application, which makes Singletons excel at managing global state in an application.

Take a class Calendar as an example. Multiple Calendar instances would introduce confusion and errors as each may have its own settings for time and date format and different time zone settings.

It is for this reason that Singletons provide the best design solution to the above scenario because with only one instance of class existing, there's only one source of truth that provides a centralized way to handle shared data, preventing conflicting updates or inconsistent data.

References

Design pattern - Singleton pattern. (n.d.). https://www.tutorialspoint.com/design_pattern/singleton_pattern.htm

Eduard Ghergu Software Architect. (2023, June 27). Singleton Design Pattern: definition, implementation, and benefits | Pentalog. Pentalog. https://www.pentalog.com/blog/design-patterns/singleton-design-pattern/

Rahman, S. (2023, April 3). The 3 Types of Design Patterns All Developers Should Know (with code examples of each). freeCodeCamp.org. https://www.freecodecamp.org/news/the-basic-design-patterns-all-developers-need-to-know/

Definition of Strategy pattern

Rather than statically selecting a single algorithm or behaviour, an object can select from a variety of them at runtime thanks to the Strategy pattern. Based on the idea of composition over inheritance, it defines a family of algorithms, encapsulates them all, and allows for runtime substitution. By separating the algorithms from the main object, this pattern enables the main object to assign the behaviour of the algorithm to one of its contained strategies. It encourages flexibility and reusability by separating the behaviour into distinct classes that can be added or removed at runtime, making it simple to add or alter different strategies without altering the object's core code. The Strategy pattern improves the flexibility and reusability of the calling code by postponing the choice of which algorithm to use until runtime.

Components of the Strategy Design Pattern

  • Context: This class may define an interface that allows the strategy to access its data and holds a reference to a strategy object. The strategy object receives the algorithm from the context class.

  • Strategy Interface: An interface or abstract class that defines a collection of methods to carry out a specific behaviour is called a strategy. Using a particular algorithm, each concrete method puts this interface into practice.

  • Concrete Strategies: These are the ways in which the strategy interface is put into practice. For every concrete strategy, there is a unique algorithm that the context can apply.

Benifits of using Strategy pattern

  • Flexibility and Extensibility
  • Promotes Reusability
  • Enhances Testability
  • Easy to maintain

References

Wikipedia page on Strategy pattern(10 May 2023).https://en.wikipedia.org/wiki/Strategy_pattern.

Ashutosh Krishna.(MAY 4, 2023).A Beginner's Guide to the Strategy Design Pattern.https://www.freecodecamp.org/news/a-beginners-guide-to-the-strategy-design-pattern/

Sulabh Kumar.(09 Feb, 2024).Strategy Design Pattern.https://www.geeksforgeeks.org/strategy-pattern-set-1/

Model View View-Model (MVVM) - Architectural Pattern

Overview of the Concept

Just like the Model View Controller (MVC) pattern, Model View View-Model (MVVM) is an architectural pattern in software development whose purpose is to provide a clear separation of concerns in applications, especially those with complex user interfaces and interactive features. In both patterns, the program logic of your application (the model) is kept separate from the user interface (the view). The View-Model acts as the mediator between the Model and View. This separation enhances the structure and maintainability of the code, making it easier to develop, test, and manage.

MVVM Diagram

(Mastering Xamarin UI Development - Second Edition, n.d.)

Which Problems Does it Solve?

MVVM was developed to address several problems in the development of graphical user interfaces (GUIs), particularly those related to separation of concerns, testability, and maintainability. Here are two key issues MVVM aims to solve:

  1. Tight coupling between UI and backend logic: in traditional GUI development approaches, UI code often becomes intertwined with backend program logic, which makes it hard to test, maintain, and scale. Solution: MVVM introduces a ViewModel layer that acts as an intermediary between the View (UI) and the Model (backend logic and data). This separation ensures that changes to the View don't directly impact the program logic, and vice versa. The key benefits of decoupling the UI from the backend logic include: UI and backend code can be tested separately; it promotes code reusability (the Model and ViewModel logic can be reused or easily adapted for different interfaces); and frequent design changes don't impact the underlying program logic.

  2. Complexity in managing Stateful UIs and Data Binding: managing synchronization between the UI and underlying data models can be complex and error-prone, especially in dynamic applications where the UI needs to reflect changes in real-time. Solution: By leveraging data-binding mechanisms, MVVM automates View-ViewModel synchronization. Changes in the data layer are reflected in the UI automatically, and user interactions with the UI are propagated back to the model via the ViewModel. This simplifies the development of complex, stateful user interfaces.

Key benefits:

  • Reduces dependencies and conflicts
  • Facilitates testability
  • Improves maintainability
  • Data binding reduces the need for boilerplate code
  • Enhanced UI responsiveness
  • Simplifies UI state management
  • Facilitates rich and interactive UIs
  • Enhanced security

Enhancements over MVC

MVVM evolves from MVC but introduces two crucial distinctions:

  • Data-binding: Unlike MVC, MVVM's View is fully decoupled from the Model, heavily relying on data binding for synchronization, thus minimizing direct UI-program logic interaction and facilitating dynamic UI responsiveness.
  • ViewModel's role: the ViewModel is primarily concerned with preparing data for display, while the Controller in MVC directly manages application flow, deciding which content to display and reacting to user inputs by updating the Model or selecting a different view.

Data Binding Explained

Data binding in MVVM is a foundational concept that establishes a two-way connection between the application's UI (the View) and the data it displays (represented by the ViewModel). This connection allows for automatic synchronization of data between the ViewModel and the View, meaning that when the data in the ViewModel changes, the UI automatically updates to reflect these changes and vice versa.

How Data Binding Works in MVVM

From ViewModel to View: When a property in the ViewModel changes (for instance, due to program logic operations or user input processed by the ViewModel), data binding ensures that these changes are automatically reflected in the View. For example, if the ViewModel holds a userName property and this property is updated, any UI element bound to userName will display the updated value.

From View to ViewModel: Data binding also works in the opposite direction. If a user interacts with the UI in a way that modifies a bound data element (like editing a text field that's bound to the userName property), the new value is automatically propagated back to the ViewModel. This keeps the underlying data model in sync with the user interface.

Benefits of Data Binding in MVVM

  • Reducing boilerplate code by eliminating the need for manual UI updates
  • Helps maintain clean separation between the View and ViewModel
  • Simplifies state management and enhances maintainability

Use Cases

MVVM is a desirable architectural pattern in scenarios requiring complex UIs, dynamic data presentation, and sophisticated interaction logic, such as:

  • Rich Desktop and Web Application: offers a seamless user experience with dynamic UI updates.
  • Mobile Applications: support cross-platform development with shared UI logic.
  • Interactive content and games: facilitates complex game logic and UI separation
  • UI prototyping: accelerates prototyping with parallel design and development

Examples of tools, frameworks and programming languages that implement the MVVM pattern:

References

Gallardo, E. (2023, January 9). What is MVVM Architecture? Built In. https://builtin.com/software-engineering-perspectives/mvvm-architecture Mastering Xamarin UI Development - Second Edition. (n.d.). https://subscription.packtpub.com/book/mobile/9781788995511/5/ch05lvl1sec41/understanding-the-mvvm-architectural-pattern Michaelstonis. (2022, November 4). Model-View-ViewModel - .NET. Microsoft Learn. https://learn.microsoft.com/en-us/dotnet/architecture/maui/mvvm Ramotion. (2023, May 1). Understanding MVVM: Model-View-ViewModel Architecture explained. Web Design, UI/UX, Branding, and App Development Blog. https://www.ramotion.com/blog/what-is-mvvm/

Functional Patterns vs. OOP Design Patterns in JavaScript

Introduction:

In traditional Object-Oriented Programming (OOP), design patterns are widely used to solve common problems by providing structured approaches to design and development. However, with the rise of Functional Programming (FP), there's a shift towards different paradigms and patterns. In this section, we'll explore the contrast between OOP design patterns and functional patterns in JavaScript.

OOP Design Patterns

OOP design patterns like Singleton, Factory, Observer, and others are well-established concepts in JavaScript development. They focus on class hierarchies, encapsulation, and inheritance to achieve modularity and extensibility.

For example, the Singleton pattern ensures that a class has only one instance and provides a global point of access to it. In JavaScript:

Please see the example for Singleton pattern in JavaScript

Functional Patterns

Functional programming emphasizes immutable data and pure functions without side effects. While traditional OOP design patterns may not directly translate, functional programming offers its own set of patterns to address similar concerns.

One common pattern in FP is the Higher-Order Function pattern. Higher-order functions take other functions as arguments or return them, enabling composition and abstraction.

// Example of map, a higher-order function

const numbers = [1, 2, 3, 4, 5];
// Using the map method, which is a higher-order function,
// to apply the arrow function to each element of the numbers array.
// The arrow function takes an argument 'x' and returns 'x * 2'.
const doubled = numbers.map(x => x * 2);
console.log(doubled); // [2, 4, 6, 8, 10]

Definitions

Aspect Definition
Immutability "An immutable value is one whose content cannot be changed without creating an entirely new value" (Developer Mozilla).
Composition "Object composition refers to the logical or conceptual structure of the information, not the implementation or physical data structure used to represent it" (Wikipedia).
Inheritance "In object-oriented programming, inheritance is the mechanism of basing an object or class upon another object (prototype-based inheritance) or class (class-based inheritance), retaining similar implementation" (Wikipedia).
Pattern Matching "Pattern matching is a mechanism for checking a value against a pattern and, based on the match, performing some kind of action" (Dev Community).

Contrast and Comparison

Aspect Functional Programming (FP) Object-Oriented Programming (OOP)
Immutability Favors immutable data to reduce unintended state changes. Supports immutability but often relies on mutable state within objects.
Composition vs. Inheritance Emphasizes composition over inheritance, using functions for complex behaviors. Often relies on class hierarchies and inheritance for code organization.
Pattern Matching Offers pattern matching for elegant handling of different cases. Relies on traditional switch-case or if-else statements for conditional logic.

Conclusion

While OOP design patterns are specific to class-based systems, functional programming offers alternative patterns that address similar concerns. Functional patterns emphasize immutability, higher-order functions, and composition, leading to concise and expressive code. While the transition from OOP to FP may require a mindset shift, understanding both paradigms equips developers with a broader toolkit for solving problems.

References

Articles / Websites

Contributions

All Contributors

A multi-language library containing implementations of common software design and architecture patterns

Contributors ✨

Thanks goes to these wonderful people (emoji key):

Yogesh Manni
Yogesh Manni

πŸ’» πŸ“–
Aawofeso
Aawofeso

πŸ’»
Ting Yu Chen
Ting Yu Chen

πŸ’» πŸ“– 🎨 πŸ€” 🚧 πŸ’¬ πŸ‘€
Katrina
Katrina

πŸ’» πŸ“– πŸ€” πŸ‘€
Lara Graves
Lara Graves

πŸ’» πŸ“– πŸ€” πŸ‘€
John
John

πŸ’» πŸ“– 🎨 πŸ€” 🚧 πŸ’¬ πŸ‘€
sam
sam

πŸ’» πŸ“–
kuljit95
kuljit95

πŸ’» πŸ“–
Kai Kitching
Kai Kitching

πŸ’» πŸ“– 🎨 πŸ€” πŸ’¬ πŸ‘€
nazrinzuwair
nazrinzuwair

πŸ’» πŸ“– πŸ’¬ πŸ‘€
monika
monika

πŸ’»
mijuanmontalvo
mijuanmontalvo

πŸ’» πŸ“– 🎨 πŸ€” πŸ’¬ πŸ‘€
Bhoomi3637
Bhoomi3637

πŸ’» πŸ“–
Himanshu Punia
Himanshu Punia

πŸ“–
sabrina01031997
sabrina01031997

πŸ“–
AditiVatish
AditiVatish

πŸ’» πŸ“–
manasvi111
manasvi111

πŸ’» πŸ“–
Dhuds1
Dhuds1

πŸ’» πŸ“– 🎨 πŸ€” 🚧 πŸ’¬ πŸ‘€
BasranS
BasranS

πŸ’» πŸ“– πŸ‘€
alinaghale88
alinaghale88

πŸ’» πŸ“– πŸ‘€
Tharindu
Tharindu

πŸ‘€ πŸ€”
sumit joshi
sumit joshi

πŸ’» πŸ“– πŸ‘€
Anjitha-94
Anjitha-94

πŸ“– πŸ‘€
jaskaransingh9990
jaskaransingh9990

πŸ“–
Jessica-Pelletier
Jessica-Pelletier

πŸ’» πŸ“–
BALJITSINGH23
BALJITSINGH23

πŸ’» πŸ“–
Suhail0206327
Suhail0206327

πŸ’» πŸ“– πŸ‘€
Abhiram
Abhiram

πŸ’» πŸ“– πŸ‘€
Add your contributions

This project follows the all-contributors specification. Contributions of any kind welcome!

About

A multi-language library containing implementations of common software design and architecture patterns

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published