Skip to content

Commit

Permalink
More patterns (#3)
Browse files Browse the repository at this point in the history
* more patterns

* typo
  • Loading branch information
TGWolf authored Jun 28, 2024
1 parent 0fbe2a2 commit 2ad340f
Show file tree
Hide file tree
Showing 11 changed files with 2,196 additions and 1 deletion.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@ which it occurs is essential for choosing the most appropriate design pattern, u

| Pattern | Description |
| ------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Abstract Factory Pattern](docs/Abstract-Factory.md) | The abstract factory pattern provides an interface for creating families of related or dependent objects without specifying their concrete classes. |
| [Adapter Pattern](docs/Adapter.md) | The adapter pattern allows incompatible interfaces to work together by converting the interface of one class into another expected by the client. |
| [Bridge Pattern](docs/Bridge.md) | The bridge pattern decouples an abstraction from its implementation so that the two can vary independently. |
| [Builder Pattern](docs/Builder.md) | The builder pattern simplifies the construction of complex objects by separating the construction process from the final representation. |
| [Chain of Responsibility Pattern](docs/Chain-of-Responsibility.md) | The chain of responsibility pattern delegates commands to a chain of processing objects, allowing multiple objects a chance to handle the request. |
| [Command Pattern](docs/Command.md) | The command pattern encapsulates a request as an object, allowing for parameterization, queuing, logging, and supporting undoable operations. |
Expand All @@ -64,11 +66,18 @@ which it occurs is essential for choosing the most appropriate design pattern, u
| [Facade Pattern](docs/Facade.md) | The facade pattern provides a simplified interface to a complex subsystem, making it easier for clients to interact with the system. |
| [Factory Pattern](docs/Factory.md) | The factory pattern defines an interface for creating objects but allows subclasses to alter the type of objects that will be created. |
| [Flyweight Pattern](docs/Flyweight.md) | The flyweight pattern reduces the cost of creating and managing a large number of similar objects by sharing as much data as possible. |
| [Interpreter Pattern](docs/Interpreter.md) | The interpreter pattern defines a grammatical representation for a language and provides an interpreter to deal with this grammar. |
| [Iterator Pattern](docs/Iterator.md) | The iterator pattern provides a way to access elements of an aggregate object sequentially without exposing its underlying representation. |
| [Mediator Pattern](docs/Mediator.md) | The mediator pattern defines an object that encapsulates how a set of objects interact, promoting loose coupling. |
| [Memento Pattern](docs/Memento.md) | The memento pattern captures and externalizes an object's internal state without violating encapsulation, so the object can be restored to this state later. |
| [Observer Pattern](docs/Observer.md) | The observer pattern defines a one-to-many dependency so that when one object changes state, all its dependents are notified and updated automatically. |
| [Prototype Pattern](docs/Prototype.md) | The prototype pattern creates new objects by copying an existing object, known as the prototype. |
| [Proxy Pattern](docs/Proxy.md) | The proxy pattern provides a surrogate or placeholder for another object to control access to it, enhancing control over the underlying object. |
| [Singleton Pattern](docs/Singleton.md) | The singleton pattern ensures a class has only one instance and provides a global point of access to it, managing shared resources efficiently. |
| [State Pattern](docs/State.md) | The state pattern allows an object to alter its behaviour when its internal state changes, appearing as if the object changed its class. |
| [Strategy Pattern](docs/Strategy.md) | The strategy pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable, allowing the algorithm to vary independently from the clients that use it. |
| [Template Method Pattern](docs/Template-Method.md) | The template method pattern defines the skeleton of an algorithm, deferring some steps to subclasses. |
| [Visitor Pattern](docs/Visitor.md) | The visitor pattern separates an algorithm from the objects on which it operates, allowing new operations to be added without modifying the objects. |

<br />
<p align="right"><a href="https://wolfsoftware.com/"><img src="https://img.shields.io/badge/Created%20by%20Wolf%20on%20behalf%20of%20Wolf%20Software-blue?style=for-the-badge" /></a></p>
262 changes: 262 additions & 0 deletions docs/Abstract-Factory.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,262 @@
## Abstract Factory Pattern

The abstract factory pattern is a creational design pattern that allows the creation of objects without specifying their exact class. It
provides an interface for creating families of related or dependent objects, ensuring that the created objects are compatible. This pattern
promotes consistency among products and is particularly useful when the system needs to be independent of how its products are created,
composed, and represented.

### Go Example

```go
package main

import "fmt"

// AbstractFactory
type ShoeFactory interface {
MakeShoe() Shoe
}

// ConcreteFactory1
type NikeFactory struct{}

func (n *NikeFactory) MakeShoe() Shoe {
return &NikeShoe{}
}

// ConcreteFactory2
type AdidasFactory struct{}

func (a *AdidasFactory) MakeShoe() Shoe {
return &AdidasShoe{}
}

// AbstractProduct
type Shoe interface {
GetLogo() string
}

// ConcreteProduct1
type NikeShoe struct{}

func (n *NikeShoe) GetLogo() string {
return "Nike"
}

// ConcreteProduct2
type AdidasShoe struct{}

func (a *AdidasShoe) GetLogo() string {
return "Adidas"
}

func main() {
nikeFactory := &NikeFactory{}
adidasFactory := &AdidasFactory{}

nikeShoe := nikeFactory.MakeShoe()
adidasShoe := adidasFactory.MakeShoe()

fmt.Println(nikeShoe.GetLogo()) // Output: Nike
fmt.Println(adidasShoe.GetLogo()) // Output: Adidas
}
```

### Perl Example

```perl
package ShoeFactory;

use strict;
use warnings;

sub make_shoe { die "Abstract method" }

package NikeFactory;
use parent 'ShoeFactory';

sub make_shoe {
return NikeShoe->new();
}

package AdidasFactory;
use parent 'ShoeFactory';

sub make_shoe {
return AdidasShoe->new();
}

package Shoe;

sub get_logo { die "Abstract method" }

package NikeShoe;
use parent 'Shoe';

sub new { bless {}, shift }

sub get_logo { return "Nike" }

package AdidasShoe;
use parent 'Shoe';

sub new { bless {}, shift }

sub get_logo { return "Adidas" }

package main;

my $nike_factory = NikeFactory->new();
my $adidas_factory = AdidasFactory->new();

my $nike_shoe = $nike_factory->make_shoe();
my $adidas_shoe = $adidas_factory->make_shoe();

print $nike_shoe->get_logo(), "\n"; # Output: Nike
print $adidas_shoe->get_logo(), "\n"; # Output: Adidas
```

### Python Example

```python
from abc import ABC, abstractmethod

class Shoe(ABC):
@abstractmethod
def get_logo(self):
pass

class NikeShoe(Shoe):
def get_logo(self):
return "Nike"

class AdidasShoe(Shoe):
def get_logo(self):
return "Adidas"

class ShoeFactory(ABC):
@abstractmethod
def make_shoe(self):
pass

class NikeFactory(ShoeFactory):
def make_shoe(self):
return NikeShoe()

class AdidasFactory(ShoeFactory):
def make_shoe(self):
return AdidasShoe()

nike_factory = NikeFactory()
adidas_factory = AdidasFactory()

nike_shoe = nike_factory.make_shoe()
adidas_shoe = adidas_factory.make_shoe()

print(nike_shoe.get_logo()) # Output: Nike
print(adidas_shoe.get_logo()) # Output: Adidas
```

### Ruby Example

```ruby
class Shoe
def get_logo
raise 'Abstract method'
end
end

class NikeShoe < Shoe
def get_logo
'Nike'
end
end

class AdidasShoe < Shoe
def get_logo
'Adidas'
end
end

class ShoeFactory
def make_shoe
raise 'Abstract method'
end
end

class NikeFactory < ShoeFactory
def make_shoe
NikeShoe.new
end
end

class AdidasFactory < ShoeFactory
def make_shoe
AdidasShoe.new
end
end

nike_factory = NikeFactory.new
adidas_factory = AdidasFactory.new

nike_shoe = nike_factory.make_shoe
adidas_shoe = adidas_factory.make_shoe

puts nike_shoe.get_logo # Output: Nike
puts adidas_shoe.get_logo # Output: Adidas
```

### Rust Example

```rust
trait Shoe {
fn get_logo(&self) -> &str;
}

struct NikeShoe;

impl Shoe for NikeShoe {
fn get_logo(&self) -> &str {
"Nike"
}
}

struct AdidasShoe;

impl Shoe for AdidasShoe {
fn get_logo(&self) -> &str {
"Adidas"
}
}

trait ShoeFactory {
fn make_shoe(&self) -> Box<dyn Shoe>;
}

struct NikeFactory;

impl ShoeFactory for NikeFactory {
fn make_shoe(&self) -> Box<dyn Shoe> {
Box::new(NikeShoe)
}
}

struct AdidasFactory;

impl ShoeFactory for AdidasFactory {
fn make_shoe(&self) -> Box<dyn Shoe> {
Box::new(AdidasShoe)
}
}

fn main() {
let nike_factory = NikeFactory;
let adidas_factory = AdidasFactory;

let nike_shoe = nike_factory.make_shoe();
let adidas_shoe = adidas_factory.make_shoe();

println!("{}", nike_shoe.get_logo()); // Output: Nike
println!("{}", adidas_shoe.get_logo()); // Output: Adidas
}
```
Loading

0 comments on commit 2ad340f

Please sign in to comment.