Skip to content

Commit 041e038

Browse files
committed
Update readmes
1 parent 6ca33f7 commit 041e038

File tree

8 files changed

+388
-6
lines changed

8 files changed

+388
-6
lines changed

adapter/README.md

+37-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,40 @@
1-
# Adapter Pattern
1+
## Adapter Pattern
22
An adapter allows two incompatible interfaces to work together. This is the real-world definition for an adapter. Interfaces may be incompatible, but the inner functionality should suit the need. The adapter design pattern allows otherwise incompatible classes to work together by converting the interface of one class into an interface expected by the clients.
33

44
[Wikipedia: Adapter Pattern](https://en.wikipedia.org/wiki/Adapter_pattern)
5+
6+
### Example
7+
8+
[View on GitHub](https://github.com/scottt2/design-patterns-in-dart/tree/master/adapter)
9+
10+
```dart
11+
const adapteeMessage = 'Adaptee#method was called';
12+
13+
class Adaptee {
14+
String method() {
15+
print('Adaptee#method is being called');
16+
17+
return adapteeMessage;
18+
}
19+
}
20+
21+
abstract class Target {
22+
String call();
23+
}
24+
25+
class Adapter implements Target {
26+
String call() {
27+
var adaptee = Adaptee();
28+
print('Adapter#call is being called');
29+
30+
return adaptee.method();
31+
}
32+
}
33+
34+
void main() {
35+
var adapter = Adapter();
36+
var result = adapter.call();
37+
38+
assert(result == adapteeMessage);
39+
}
40+
```

builder/README.md

+93-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,96 @@
1-
# Builder Pattern
1+
## Builder Pattern
22
The intent of the Builder design pattern is to separate the construction of a complex object from its representation. By doing so the same construction process can create different representations.
33

44
[Wikipedia: Builder Pattern](https://en.wikipedia.org/wiki/Builder_pattern)
5+
6+
### Example
7+
8+
[View on GitHub](https://github.com/scottt2/design-patterns-in-dart/tree/master/builder)
9+
10+
```dart
11+
class PizzaBuilder {
12+
String _crust;
13+
int _diameter;
14+
Set<String> _toppings;
15+
16+
PizzaBuilder(this._diameter);
17+
18+
String get crust => _crust;
19+
set crust(String newCrust) {
20+
_crust = newCrust;
21+
}
22+
23+
int get diameter => _diameter;
24+
set diameter(int newDiameter) {
25+
_diameter = newDiameter;
26+
}
27+
28+
Set<String> get toppings => _toppings;
29+
set toppings(Set<String> newToppings) {
30+
_toppings = newToppings;
31+
_ensureCheese();
32+
}
33+
34+
void _ensureCheese() {
35+
_toppings.add("cheese");
36+
}
37+
38+
Pizza build() {
39+
return Pizza(this);
40+
}
41+
}
42+
43+
class Pizza {
44+
String _crust;
45+
int _diameter;
46+
Set<String> _toppings;
47+
48+
Pizza(PizzaBuilder builder) {
49+
_crust = builder.crust;
50+
_diameter = builder.diameter;
51+
_toppings = builder.toppings;
52+
}
53+
54+
String get crust => _crust;
55+
int get diameter => _diameter;
56+
String get toppings => _stringifiedToppings();
57+
String _stringifiedToppings() {
58+
var stringToppings = _toppings.join(", ");
59+
var lastComma = stringToppings.lastIndexOf(",");
60+
var replacement = ",".allMatches(stringToppings).length > 1 ? ", and" : " and";
61+
62+
return stringToppings.replaceRange(lastComma, lastComma + 1, replacement);
63+
}
64+
65+
@override
66+
String toString() {
67+
return "A delicous $_diameter\" pizza with $_crust crust covered in $toppings";
68+
}
69+
}
70+
71+
void main() {
72+
// Create a handy PizzaBuilder with an 8" diameter.
73+
var pizzaBuilder = PizzaBuilder(8);
74+
75+
// Add some attributes to the builder.
76+
pizzaBuilder.crust = "deep dish";
77+
pizzaBuilder.toppings = Set.from(["pepperoni"]);
78+
79+
// Let's make a pizza!
80+
var plainPizza = Pizza(pizzaBuilder);
81+
print("Behold! $plainPizza.");
82+
assert(plainPizza.toString() == "Behold! A delicous 8\" pizza with deep dish crust covered in pepperoni and cheese.");
83+
84+
// Now to adjust some things for the next pizza...
85+
pizzaBuilder.crust = "gold plated";
86+
pizzaBuilder.diameter = 72;
87+
pizzaBuilder.toppings = Set.from(["anchovies", "caviar", "diamonds"]);
88+
89+
// The beauty of the build is you can quickly iterate and produce instances of a class.
90+
// For example, we have an early employee of the latest unicorn in line. So much disposable income!
91+
// Also note, we use the .build() function of the builder this time.
92+
var luxuriousPizza = pizzaBuilder.build();
93+
print("Wow! $luxuriousPizza? Someone is rich!");
94+
assert(luxuriousPizza.toString() == "Wow! A delicous 72\" pizza with gold plated crust covered in anchovies, caviar, diamonds, and cheese? Someone is rich!");
95+
}
96+
```

composite/README.md

+83-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,87 @@
1-
# Composite Pattern
1+
## Composite Pattern
22
In software engineering, the composite pattern is a partitioning design pattern. The composite pattern describes a group of objects that is treated the same way as a single instance of the same type of object. The intent of a composite is to "compose" objects into tree structures to represent part-whole hierarchies. Implementing the composite pattern lets clients treat individual objects and compositions uniformly.
33

44
[Wikipedia: Composite Pattern](https://en.wikipedia.org/wiki/Composite_pattern)
55

6+
### Example
7+
8+
[View on GitHub](https://github.com/scottt2/design-patterns-in-dart/tree/master/composite)
9+
10+
```dart
11+
abstract class Thing {
12+
String name;
13+
void doSomething();
14+
}
15+
16+
class CompositeThing implements Thing {
17+
String name;
18+
Set<Thing> _childThings = Set();
19+
20+
CompositeThing(this.name);
21+
22+
void addChild(Thing child) {
23+
_childThings.add(child);
24+
}
25+
26+
void doSomething() {
27+
print("\r\n** $name is doing something! ** \r\n");
28+
_childThings.forEach((thing) => thing.doSomething());
29+
print("\r\n** $name is all done. ** \r\n");
30+
}
31+
}
32+
33+
class LeafThing implements Thing {
34+
String name;
35+
36+
LeafThing(this.name);
37+
38+
void doSomething() {
39+
print("* $name!");
40+
}
41+
}
42+
43+
void main() {
44+
var compositeParent = CompositeThing("Cat in the Hat");
45+
var compositeChild1 = CompositeThing("Thing 1");
46+
var compositeChild2 = CompositeThing("Thing 2");
47+
48+
var leaf1_1 = LeafThing("Frustrate fish");
49+
var leaf1_2 = LeafThing("Knock down vases");
50+
var leaf2_1 = LeafThing("Ruin mom's dress");
51+
var leaf2_2 = LeafThing("Clean up");
52+
53+
compositeChild1.addChild(leaf1_1);
54+
compositeChild1.addChild(leaf1_2);
55+
56+
compositeChild2.addChild(leaf2_1);
57+
compositeChild2.addChild(leaf2_2);
58+
59+
compositeParent.addChild(compositeChild1);
60+
compositeParent.addChild(compositeChild2);
61+
62+
compositeParent.doSomething();
63+
64+
/*
65+
** Cat in the Hat is doing something! **
66+
67+
68+
** Thing 1 is doing something! **
69+
70+
* Frustrate fish!
71+
* Knock down vases!
72+
73+
** Thing 1 is all done. **
74+
75+
76+
** Thing 2 is doing something! **
77+
78+
* Ruin mom's dress!
79+
* Clean up!
80+
81+
** Thing 2 is all done. **
82+
83+
84+
** Cat in the Hat is all done. **
85+
*/
86+
}
87+
```

factory_method/README.md

+63-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,66 @@
1-
# Factory Method Pattern
1+
## Factory Method Pattern
22
The factory method pattern is a creational pattern that uses factory methods to deal with the problem of creating objects without having to specify the exact class of the object that will be created. This is done by creating objects by calling a factory method—either specified in an interface and implemented by child classes, or implemented in a base class and optionally overridden by derived classes—rather than by calling a constructor.
33

44
[Wikipedia: Factory Method](https://en.wikipedia.org/wiki/Factory_method_pattern)
5+
6+
### Example
7+
8+
[View on GitHub](https://github.com/scottt2/design-patterns-in-dart/tree/master/factor_method)
9+
10+
```dart
11+
class Volume {
12+
final int quantity;
13+
final String unit;
14+
15+
Volume(this.quantity, this.unit);
16+
String toString() => "$quantity $unit";
17+
}
18+
19+
abstract class Vessel {
20+
Volume volume;
21+
String liquid;
22+
}
23+
24+
class Bucket extends Vessel {
25+
final Volume volume;
26+
27+
Bucket(int q, String u) : volume = Volume(q, u);
28+
String toString() => "a $volume bucket full of $liquid";
29+
}
30+
31+
class Cup extends Vessel {
32+
final Volume volume;
33+
34+
Cup(int q, String u) : volume = Volume(q, u);
35+
String toString() => "a $volume cup full of $liquid";
36+
}
37+
38+
enum Tiredness {
39+
rested, sleepy, barelyAlive, hasChildren
40+
}
41+
42+
class CoffeeVesselFactory {
43+
static Vessel vesselFor(Tiredness howTired) {
44+
Vessel vessel;
45+
switch(howTired) {
46+
case Tiredness.rested: vessel = Cup(100, "milliliter"); break;
47+
case Tiredness.sleepy:
48+
case Tiredness.barelyAlive: vessel = Cup(500, "milliliter"); break;
49+
case Tiredness.hasChildren: vessel = Bucket(5, "liter"); break;
50+
default: vessel = Cup(200, "milliliter"); break;
51+
}
52+
vessel.liquid = "coffee";
53+
return vessel;
54+
}
55+
}
56+
57+
void main() {
58+
var sleepyVessel = CoffeeVesselFactory.vesselFor(Tiredness.sleepy);
59+
var kidVessel = CoffeeVesselFactory.vesselFor(Tiredness.hasChildren);
60+
61+
// A sleepy person would like a 500 milliliter cup full of coffee.
62+
print("A sleepy person would like $sleepyVessel.");
63+
// A person with children NEEDS a 5 liter bucket full of coffee.
64+
print("A person with children NEEDS $kidVessel.");
65+
}
66+
```

proxy/README.md

+50-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,53 @@
1-
# Proxy Pattern
1+
## Proxy Pattern
22
A proxy, in its most general form, is a class functioning as an interface to something else. The proxy could interface to anything: a network connection, a large object in memory, a file, or some other resource that is expensive or impossible to duplicate. In short, a proxy is a wrapper or agent object that is being called by the client to access the real serving object behind the scenes.
33

44
[Wikipedia: Proxy Pattern](https://en.wikipedia.org/wiki/Proxy_pattern)
5+
6+
### Example
7+
8+
[View on GitHub](https://github.com/scottt2/design-patterns-in-dart/tree/master/proxy)
9+
10+
```dart
11+
abstract class Subject {
12+
void someMethod();
13+
}
14+
15+
class ExpensiveClass implements Subject {
16+
String name;
17+
18+
ExpensiveClass(this.name);
19+
20+
void someMethod() {
21+
print("someMethod of $name (an ExpensiveClass) is being called");
22+
}
23+
}
24+
25+
class Proxy implements Subject {
26+
String _name;
27+
ExpensiveClass _sub;
28+
29+
Proxy(this._name);
30+
31+
void someMethod() {
32+
print("someMethod of $_name (a Proxy) is being called");
33+
_subject().someMethod();
34+
}
35+
36+
ExpensiveClass _subject() {
37+
if (_sub != null) return _sub;
38+
print("Creating an instance of ExpensiveClass for the proxy...");
39+
_sub = ExpensiveClass(_name);
40+
return _sub;
41+
}
42+
}
43+
44+
void main() {
45+
var proxy = Proxy("yay");
46+
print("With our handy proxy, we call someMethod...\r\n");
47+
proxy.someMethod();
48+
print("\r\nNotice that the proxy did not have an instance of ExpensiveClass, so it made one when required.");
49+
print("Now if we call someMethod again...\r\n");
50+
proxy.someMethod();
51+
print("\r\nWe reuse the instance we made above!");
52+
}
53+
```

0 commit comments

Comments
 (0)