## 1. Project Overview & Quickstart (faif/python-patterns)

# python-patterns

A collection of design patterns and idioms in Python.

Remember that each pattern has its own trade-offs. And you need to pay attention more to why you're choosing a certain pattern than to how to implement it.

## Creational Patterns

> Patterns that deal with **object creation** — abstracting and controlling how instances are made.

```mermaid
graph LR
    Client -->|requests object| AbstractFactory
    AbstractFactory -->|delegates to| ConcreteFactory
    ConcreteFactory -->|produces| Product

    Builder -->|step-by-step| Director
    Director -->|returns| BuiltObject

    FactoryMethod -->|subclass decides| ConcreteProduct
    Pool -->|reuses| PooledInstance
```

| Pattern | Description |
|:-------:| ----------- |
| [abstract_factory](patterns/creational/abstract_factory.py) | use a generic function with specific factories |
| [borg](patterns/creational/borg.py) | a singleton with shared-state among instances |
| [builder](patterns/creational/builder.py) | instead of using multiple constructors, builder object receives parameters and returns constructed objects |
| [factory](patterns/creational/factory.py) | delegate a specialized function/method to create instances |
| [lazy_evaluation](patterns/creational/lazy_evaluation.py) | lazily-evaluated property pattern in Python |
| [pool](patterns/creational/pool.py) | preinstantiate and maintain a group of instances of the same type |
| [prototype](patterns/creational/prototype.py) | use a factory and clones of a prototype for new instances (if instantiation is expensive) |

## Structural Patterns

> Patterns that define **how classes and objects are composed** to form larger, flexible structures.

```mermaid
graph TD
    Client --> Facade
    Facade --> SubsystemA
    Facade --> SubsystemB
    Facade --> SubsystemC

    Client2 --> Adapter
    Adapter --> LegacyService

    Client3 --> Proxy
    Proxy -->|controls access to| RealSubject

    Component --> Composite
    Composite --> Leaf1
    Composite --> Leaf2
```

|                           Pattern                           | Description                                                                    |
|:-----------------------------------------------------------:|--------------------------------------------------------------------------------|
|           [3-tier](patterns/structural/3-tier.py)           | data<->business logic<->presentation separation (strict relationships)         |
|          [adapter](patterns/structural/adapter.py)          | adapt one interface to another using a white-list                              |
|           [bridge](patterns/structural/bridge.py)           | a client-provider middleman to soften interface changes                        |
|        [composite](patterns/structural/composite.py)        | lets clients treat individual objects and compositions uniformly               |
|        [decorator](patterns/structural/decorator.py)        | wrap functionality with other functionality in order to affect outputs         |
|           [facade](patterns/structural/facade.py)           | use one class as an API to a number of others                                  |
|        [flyweight](patterns/structural/flyweight.py)        | transparently reuse existing instances of objects with similar/identical state |
| [front_controller](patterns/structural/front_controller.py) | single handler requests coming to the application                              |
|              [mvc](patterns/structural/mvc.py)              | model<->view<->controller (non-strict relationships)                           |
|            [proxy](patterns/structural/proxy.py)            | an object funnels operations to something else                                 |

## Behavioral Patterns

> Patterns concerned with **communication and responsibility** between objects.

```mermaid
graph LR
    Sender -->|sends event| Observer1
    Sender -->|sends event| Observer2

    Request --> Handler1
    Handler1 -->|passes if unhandled| Handler2
    Handler2 -->|passes if unhandled| Handler3

    Context -->|delegates to| Strategy
    Strategy -->|executes| Algorithm

    Originator -->|saves state to| Memento
    Caretaker -->|holds| Memento
```

|                                  Pattern                                  | Description                                                                                                  |
|:-------------------------------------------------------------------------:|--------------------------------------------------------------------------------------------------------------|
| [chain_of_responsibility](patterns/behavioral/chain_of_responsibility.py) | apply a chain of successive handlers to try and process the data                                             |
|                 [catalog](patterns/behavioral/catalog.py)                 | general methods will call different specialized methods based on construction parameter                      |
|         [chaining_method](patterns/behavioral/chaining_method.py)         | continue callback next object method                                                                         |
|                 [command](patterns/behavioral/command.py)                 | bundle a command and arguments to call later                                                                 |
|             [interpreter](patterns/behavioral/interpreter.py)             | define a grammar for a language and use it to interpret statements                                           |
|                [iterator](patterns/behavioral/iterator.py)                | traverse a container and access the container's elements                                                     |
|       [iterator](patterns/behavioral/iterator_alt.py) (alt. impl.)        | traverse a container and access the container's elements                                                     |
|                [mediator](patterns/behavioral/mediator.py)                | an object that knows how to connect other objects and act as a proxy                                         |
|                 [memento](patterns/behavioral/memento.py)                 | generate an opaque token that can be used to go back to a previous state                                     |
|                [observer](patterns/behavioral/observer.py)                | provide a callback for notification of events/changes to data                                                |
|       [publish_subscribe](patterns/behavioral/publish_subscribe.py)       | a source syndicates events/data to 0+ registered listeners                                                   |
|                [registry](patterns/behavioral/registry.py)                | keep track of all subclasses of a given class                                                                |
|                 [servant](patterns/behavioral/servant.py)                 | provide common functionality to a group of classes without using inheritance                                 |
|           [specification](patterns/behavioral/specification.py)           | business rules can be recombined by chaining the business rules together using boolean logic                 |
|                   [state](patterns/behavioral/state.py)                   | logic is organized into a discrete number of potential states and the next state that can be transitioned to |
|                [strategy](patterns/behavioral/strategy.py)                | selectable operations over the same data                                                                     |
|                [template](patterns/behavioral/template.py)                | an object imposes a structure but takes pluggable components                                                 |
|                 [visitor](patterns/behavioral/visitor.py)                 | invoke a callback for all items of a collection                                                              |

## Design for Testability Patterns

|                         Pattern                          | Description                        |
|:--------------------------------------------------------:|------------------------------------|
| [dependency_injection](patterns/dependency_injection.py) | 3 variants of dependency injection |

## Fundamental Patterns

|                             Pattern                              | Description                                                                 |
|:----------------------------------------------------------------:|-----------------------------------------------------------------------------|
| [delegation_pattern](patterns/fundamental/delegation_pattern.py) | an object handles a request by delegating to a second object (the delegate) |

## Others

|                    Pattern                     | Description                                                                                                              |
|:----------------------------------------------:|--------------------------------------------------------------------------------------------------------------------------|
|   [blackboard](patterns/other/blackboard.py)   | architectural model, assemble different sub-system knowledge to build a solution, AI approach - non gang of four pattern |
| [graph_search](patterns/other/graph_search.py) | graphing algorithms - non gang of four pattern                                                                           |
|        [hsm](patterns/other/hsm/hsm.py)        | hierarchical state machine - non gang of four pattern                                                                    |

## 🚫 Anti-Patterns

This section lists some common design patterns that are **not recommended** in Python and explains why.

### 🧱 Singleton
**Why not:**
- Python modules are already singletons — every module is imported only once.
- Explicit singleton classes add unnecessary complexity.
- Better alternatives: use module-level variables or dependency injection.

### 🌀 God Object
**Why not:**
- Centralizes too much logic in a single class.
- Makes code harder to test and maintain.
- Better alternative: split functionality into smaller, cohesive classes.

### 🔁 Inheritance overuse
**Why not:**
- Deep inheritance trees make code brittle.
- Prefer composition and delegation.
- “Favor composition over inheritance.”

## Videos

* [Design Patterns in Python by Peter Ullrich](https://www.youtube.com/watch?v=bsyjSW46TDg)
* [Sebastian Buczyński - Why you don't need design patterns in Python?](https://www.youtube.com/watch?v=G5OeYHCJuv0)
* [You Don't Need That!](https://www.youtube.com/watch?v=imW-trt0i9I)
* [Pluggable Libs Through Design Patterns](https://www.youtube.com/watch?v=PfgEU3W0kyU)

## Contributing

When an implementation is added or modified, please review the following guidelines:

##### Docstrings
Add module level description in form of a docstring with links to corresponding references or other useful information. 
Add "Examples in Python ecosystem" section if you know some. It shows how patterns could be applied to real-world problems.
[facade.py](patterns/structural/facade.py) has a good example of detailed description, but sometimes the shorter one as in [template.py](patterns/behavioral/template.py) would suffice.

##### Python 2 compatibility
To see Python 2 compatible versions of some patterns please check-out the [legacy](https://github.com/faif/python-patterns/tree/legacy) tag.

##### Update README
When everything else is done - update corresponding part of README.

##### Travis CI
Please run the following before submitting a patch:
- If you have a bash-compatible shell, use `./lint.sh` to run formatting,
  linting, type checking, and tests.

Development dependencies are pinned in `Pipfile.lock`. After changing
`Pipfile`, activate a Python 3.10 virtual environment and run `make lock` to
regenerate it.

## Contributing via issue triage [](https://www.codetriage.com/faif/python-patterns)
You can triage issues and pull requests on [CodeTriage](https://www.codetriage.com/faif/python-patterns).

## 2. Official Technical Reference & Guides (faif/docs)

# The Things Network Documentation [](https://travis-ci.org/TheThingsNetwork/docs)

This is a [Jekyll](https://jekyllrb.com) site which [Travis](https://travis-ci.org/TheThingsNetwork/docs) automatically tests and builds to the [gh-pages](https://github.com/TheThingsNetwork/docs/tree/gh-pages) branch to be served via [GitHub Pages](https://help.github.com/articles/what-is-github-pages/).

## Update content
If you do a lot of edits please use a local build to preview and test.

* The homepage for the site is [index.html](index.html).
* The guides are a Jekyll collection in the [_content](_content) folder.
* Store assets in the same folder as the markdown file you need it in and include them by their filename. You can also use relative paths to re-use images from other guides.
* To link to another child guide, use the relative markdown path (e.g. `../devices/registration.md`) and Jekyll will make it `.html`.
* To link to another parent guide, use the relative markdown path (e.g. `../devices/index.md`) or the directory path, ending with a slash (`../devices/`).
* Guides are sorted on descending `zindex` first, then `title` ascending and if those are equal `label` descending.
* Use blockquotes (`>`) to create callouts for important notes.
* To set an image to use on Facebook and Twitter use `image:/absolute/path/to/image.png` in your frontmatter.
* You can use most of the [icons](http://ionicons.com/cheatsheet.html) we use in the console. Simply use `` in the Markdown and we'll style it as a button.

## Build local for preview and design

1. [Install Ruby 2.0.0 or higher](https://www.ruby-lang.org/en/downloads/)
2. Install [Bundler](http://bundler.io/):
	
	```bash
	$ gem install bundler
	```

3. Install [Jekyll](https://jekyllrb.com/) using Bundler:

	```bash
	$ bundle install
	```

4. Install [Node.js and NPM](https://nodejs.org/).

5. Install front-end and development dependencies:

  ```basg
  $ npm install
  ```
  
    > This will also overwrite any local git pre-commit hook to execute [npm run webpack](package.json#L12), [npm test](package.json#L15) and [npm run add](package.json#L16) to append the webpack build.

4. Run [Webpack](http://webpack.github.io/), build the local Jekyll site and watch for changes:

	```bash
	$ npm run dev
	```
	
	> Be aware that this will use Jekyll's experimental incremental mode. Only the file you edit will be regenerated. So a change in a guide's title will not cause the navigation on all other pages to be updated. Just kill the proces and run it again.
	
### Guidance

* Require and use any JS libraries you need in [assets/js/_main.js](assets/js/_main.js) and [_page.js](assets/js/_page.js).
* Import any Sass files you need in [assets/css/main.scss](assets/css/main.scss).
* Override Bootstrap variables in [_sass/_variables.scss](_sass/_variables.scss).
* Edit styles in [_sass/_base.scss](_sass/_base.scss) or break out to additional Sass files to keep it organized.
* Store layout assets in [assets](assets) folder.
* Edit layouts in the [_layouts](_layouts) folder.
* All layouts should inherit the [default](_layouts/default.html) layout.

## Build and upload a preview

If you do some major refactoring and would like to upload a build somewhere for preview, then you can use:

```
npm run scp user@host:/path
```

This will create a build in `_scp`, upload it with `scp` and then delete the directory. Make sure the server has your public key or it will prompt for a password and cause the script to fail.

Alternatively, you can set the `SCP_TARGET` environment variable or [dotenv](https://www.npmjs.com/package/dotenv).

## Test [](https://travis-ci.org/TheThingsNetwork/docs)

Pull Requests and Pushes will be tested automatically by Travis. It will let Jekyll try to build the site and then run [HTMLProofer](https://github.com/gjtorikian/html-proofer) to test for broken links etc.

The test will also run automatically before every commit. To run the test manually, follow *Build local* to install the dependencies and then run:

```
npm test
```

## Automatic updates

Some content we source directly from elsewhere, e.g. the [MQTT API Reference](https://github.com/TheThingsNetwork/ttn/blob/refactor/mqtt/README.md).

### Update

1.  Follow the previous section to install NPM and dependencies.
    
3.  Run the pull script:

    ```bash
    npm run pull
    ```
    
### Source

To source more content from elsewhere edit [_scripts/pull.js](_scripts/pull.js).