Skip to content

Commit 07d66ee

Browse files
committed
Added Flyweight Design Pattern
1 parent 183be6f commit 07d66ee

File tree

9 files changed

+306
-0
lines changed

9 files changed

+306
-0
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
namespace PhpDesignPatterns\Structural\Flyweight;
4+
5+
/**
6+
* Interface AccessoryFlyweightInterface
7+
* @package PhpDesignPatterns\Structural\Flyweight
8+
*/
9+
interface AccessoryFlyweightInterface
10+
{
11+
/**
12+
* Get item price.
13+
*
14+
* @return mixed
15+
*/
16+
public function getPrice();
17+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
namespace PhpDesignPatterns\Structural\Flyweight;
4+
5+
/**
6+
* Class HeadphonesFlyweight
7+
* @package PhpDesignPatterns\Structural\Flyweight
8+
*/
9+
class HeadphonesFlyweight implements AccessoryFlyweightInterface
10+
{
11+
/**
12+
* Get item price.
13+
*
14+
* @return float
15+
*/
16+
public function getPrice()
17+
{
18+
return 29.99;
19+
}
20+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
namespace PhpDesignPatterns\Structural\Flyweight;
4+
5+
/**
6+
* Interface PhoneInterface
7+
* @package PhpDesignPatterns\Structural\Flyweight
8+
*/
9+
interface PhoneInterface
10+
{
11+
/**
12+
* Get the basic item price.
13+
*
14+
* @return mixed
15+
*/
16+
public function getBasicPrice();
17+
18+
/**
19+
* Get total item + accessories price.
20+
*
21+
* @return mixed
22+
*/
23+
public function getTotalPrice();
24+
25+
/**
26+
* Add an accessory.
27+
*
28+
* @param AccessoryFlyweightInterface $accessory
29+
* @return PhoneInterface
30+
*/
31+
public function addAccessory(AccessoryFlyweightInterface $accessory);
32+
33+
/**
34+
* Get accessories price.
35+
*
36+
* @return mixed
37+
*/
38+
public function getAccessoriesPrice();
39+
}

Structural/Flyweight/README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Flyweight Design Pattern
2+
3+
## Intent
4+
5+
“Use sharing to support large numbers of fine-grained objects efficiently.”
6+
7+
Excerpt From: Erich Gamma. “Design Patterns: Elements of Reusable Object-Oriented Software.”
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
namespace PhpDesignPatterns\Structural\Flyweight;
4+
5+
/**
6+
* Class SecondaryBatteryFlyweight
7+
* @package PhpDesignPatterns\Structural\Flyweight
8+
*/
9+
class SecondaryBatteryFlyweight implements AccessoryFlyweightInterface
10+
{
11+
/**
12+
* Get item price.
13+
*
14+
* @return float
15+
*/
16+
public function getPrice()
17+
{
18+
return 14.99;
19+
}
20+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<?php
2+
3+
namespace PhpDesignPatterns\Structural\Flyweight;
4+
5+
/**
6+
* Class Smartphone
7+
* @package PhpDesignPatterns\Structural\Flyweight
8+
*/
9+
class Smartphone implements PhoneInterface
10+
{
11+
/**
12+
* Phone price.
13+
*
14+
* @var float
15+
*/
16+
const PHONE_PRICE = 399.90;
17+
18+
/**
19+
* Accessories default price.
20+
*
21+
* @var float
22+
*/
23+
const NO_ACCESSORIES_PRICE = 0.0;
24+
25+
/**
26+
* List of accessories.
27+
*
28+
* @var array
29+
*/
30+
private $accessories;
31+
32+
/**
33+
* Get phone basic price.
34+
*
35+
* @return float
36+
*/
37+
public function getBasicPrice()
38+
{
39+
return static::PHONE_PRICE;
40+
}
41+
42+
/**
43+
* Get accessories price.
44+
*
45+
* @return float
46+
*/
47+
public function getAccessoriesPrice()
48+
{
49+
$accessories_price = static::NO_ACCESSORIES_PRICE;
50+
if(empty($this->accessories)) {
51+
return $accessories_price;
52+
}
53+
foreach($this->accessories as $accessory) {
54+
$accessories_price += $accessory->getPrice();
55+
}
56+
return $accessories_price;
57+
}
58+
59+
/**
60+
* Add accessory.
61+
*
62+
* @param AccessoryFlyweightInterface $accessory
63+
* @return PhoneInterface
64+
*/
65+
public function addAccessory(AccessoryFlyweightInterface $accessory)
66+
{
67+
$this->accessories[] = $accessory;
68+
return $this;
69+
}
70+
71+
/**
72+
* Get total phone price.
73+
*
74+
* @return float
75+
*/
76+
public function getTotalPrice()
77+
{
78+
return $this->getBasicPrice() + $this->getAccessoriesPrice();
79+
}
80+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
namespace PhpDesignPatterns\Tests\Structural\Flyweight;
4+
5+
use PhpDesignPatterns\Structural\Flyweight\HeadphonesFlyweight;
6+
7+
/**
8+
* Class HeadphonesFlyweightTest
9+
* @package PhpDesignPatterns\Tests\Structural\Flyweight
10+
*/
11+
class HeadphonesFlyweightTest extends \PHPUnit_Framework_TestCase
12+
{
13+
/**
14+
* Testing getPrice.
15+
*/
16+
public function testGetPrice()
17+
{
18+
$expected = 29.99;
19+
$flyweight = new HeadphonesFlyweight;
20+
$this->assertEquals($expected, $flyweight->getPrice());
21+
}
22+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
namespace PhpDesignPatterns\Tests\Structural\Flyweight;
4+
5+
use PhpDesignPatterns\Structural\Flyweight\SecondaryBatteryFlyweight;
6+
7+
/**
8+
* Class SecondaryBatteryFlyweightTest
9+
* @package PhpDesignPatterns\Tests\Structural\Flyweight
10+
*/
11+
class SecondaryBatteryFlyweightTest extends \PHPUnit_Framework_TestCase
12+
{
13+
/**
14+
* Testing getPrice.
15+
*/
16+
public function testGetPrice()
17+
{
18+
$expected = 14.99;
19+
$flyweight = new SecondaryBatteryFlyweight;
20+
$this->assertEquals($expected, $flyweight->getPrice());
21+
}
22+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
<?php
2+
3+
namespace PhpDesignPatterns\Tests\Structural\Flyweight;
4+
5+
use PhpDesignPatterns\Structural\Flyweight\Smartphone;
6+
7+
class SmartphoneTest extends \PHPUnit_Framework_TestCase
8+
{
9+
/**
10+
* Instance of Smartphone.
11+
*
12+
* @var PhoneInterface
13+
*/
14+
private $phone;
15+
16+
/**
17+
* Setup each test case basic variables.
18+
*/
19+
public function setUp()
20+
{
21+
$this->phone = new Smartphone;
22+
}
23+
24+
/**
25+
* Destroy variables after each test case.
26+
*/
27+
public function tearDown()
28+
{
29+
$this->phone = null;
30+
}
31+
32+
/**
33+
* Test get basic phone price.
34+
*/
35+
public function testGetBasicPrice()
36+
{
37+
$this->assertEquals(Smartphone::PHONE_PRICE, $this->phone->getBasicPrice());
38+
}
39+
40+
/**
41+
* Test get accessories price when no accessories.
42+
*/
43+
public function testGetAccessoriesPriceWhenNoAccessories()
44+
{
45+
$this->assertEquals(0.0, $this->phone->getAccessoriesPrice());
46+
}
47+
48+
/**
49+
* Test get accessories price.
50+
*/
51+
public function testGetAccessoriesPrice()
52+
{
53+
$mock_accessory = $this->getMock('\\PhpDesignPatterns\\Structural\\Flyweight\\AccessoryFlyweightInterface', array('getPrice'));
54+
$mock_accessory
55+
->expects($this->exactly(2))
56+
->method('getPrice')
57+
->will($this->onConsecutiveCalls(20.00, 10.00))
58+
;
59+
$this->phone->addAccessory($mock_accessory);
60+
$this->phone->addAccessory($mock_accessory);
61+
$this->assertEquals(30.0, $this->phone->getAccessoriesPrice());
62+
}
63+
64+
/**
65+
* Test get total phone price.
66+
*/
67+
public function testGetTotalPrice()
68+
{
69+
$mock_accessory = $this->getMock('\\PhpDesignPatterns\\Structural\\Flyweight\\AccessoryFlyweightInterface', array('getPrice'));
70+
$mock_accessory
71+
->expects($this->exactly(2))
72+
->method('getPrice')
73+
->will($this->onConsecutiveCalls(20.00, 10.00))
74+
;
75+
$this->phone->addAccessory($mock_accessory);
76+
$this->phone->addAccessory($mock_accessory);
77+
$this->assertEquals(Smartphone::PHONE_PRICE+30.0, $this->phone->getTotalPrice());
78+
}
79+
}

0 commit comments

Comments
 (0)