Skip to content

Commit f4f884e

Browse files
committed
Proposed pattern Limiton working.
1 parent 712209a commit f4f884e

File tree

3 files changed

+175
-1
lines changed

3 files changed

+175
-1
lines changed

README.md

+107-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,107 @@
1-
# tonton
1+
# TonTon PHP
2+
3+
Singleton patterns are amongst the most used structures in PHP. Together with that, some similar constructions, such as the Multiton, appear in almost every new PHP project. However, singletons could be much more. Initially, they don't really need to be inserted in any class, several times. Some people use abstracts, but does it make sense, extending a class which is just a support, by definition?
4+
5+
Also, some patterns could be deriving from the Singleton, beyond the Multiton, so that is what we are proposing here:
6+
7+
* First, use Singletons and similar as traits, to avoid duplicates and repetition while coding
8+
* Second, create new and different subpatterns that can elevate the initial purpose of a Singleton to something even more useful
9+
10+
# Installation
11+
12+
TonTon is available as PHP library, being installed through Composer.
13+
14+
# Usage
15+
16+
Well, for the first two traits, "using" them is pretty much what you need to do. As traits, once they are required with Composer, they can easily be added to any class through the `use` keyword inside the class. The usage is quite simple - let's consider a class named `EasyPeasy`:
17+
18+
```php
19+
20+
require __DIR__ . '/vendor/autoload.php';
21+
22+
class EasyPeasy {
23+
24+
use \TonTon\Singleton;
25+
26+
protected function construct() {
27+
28+
echo 'Easy Peasy!';
29+
}
30+
}
31+
32+
/* So, if we want to instantiate this class, then we need to use a
33+
static method. Any new attempts of instantiating the class will
34+
result in nothing (if we try to use the static method again) or
35+
a fatal error, if we try to create an instance through the "new"
36+
keyword.*/
37+
38+
$ep = EasyPeasy::instance(); // Valid instance
39+
$rt = EasyPeasy::instance(); // Nothing happens, as an instance already exists
40+
41+
$er = new EasyPeasy(); // Fatal error
42+
43+
44+
```
45+
But the Singleton here is just the tip of the iceberg. If you want, by any reason, to have multiple instances of your class, but all of them need to be flagged (let's say one for dealing with queries, and other for logging processes), you'd prefer to use a Multiton instead. The approach will be basically the same:
46+
47+
```php
48+
49+
require __DIR__ . '/vendor/autoload.php';
50+
51+
class EasyPeasy {
52+
53+
use \TonTon\Multiton;
54+
55+
protected function construct() {
56+
57+
echo 'Easy Peasy!';
58+
}
59+
}
60+
61+
/* So, if we want to instantiate this class, then we need to use a
62+
static method. Any new attempts of instantiating the class will
63+
work if using the static method instance(), with a $key as argument
64+
or a fatal error, if we try to create an instance through the "new"
65+
keyword.*/
66+
67+
$ep = EasyPeasy::instance('normal'); // Instance 1
68+
$rt = EasyPeasy::instance('log'); // Instance 2
69+
70+
$er = new EasyPeasy(); // Fatal error
71+
72+
73+
```
74+
But let's say, besides using many instances of that class, you want the number of instances to be limit, and you'd like to set this limit while creating your class. That can now be done using the Limiton:
75+
76+
77+
```php
78+
79+
require __DIR__ . '/vendor/autoload.php';
80+
81+
class EasyPeasy {
82+
83+
use \TonTon\Limiton;
84+
85+
protected function construct() {
86+
87+
$this->setLimit(1); // Limit set to 1, so it works like a Singleton,
88+
// but needs a $key for the new instance. Default
89+
// value is 2.
90+
echo 'Easy Peasy!';
91+
}
92+
}
93+
94+
/* So, if we want to instantiate this class, then we need to use a
95+
static method. Any new attempts of instantiating the class will
96+
work if using the static method instance(), with a $key as argument
97+
or a fatal error, if we try to create an instance through the "new"
98+
keyword.*/
99+
100+
$ep = EasyPeasy::instance('normal'); // Instance 1
101+
$rt = EasyPeasy::instance('log'); // Nothing happens, as we limited the max number
102+
// of instances in 1 for this class.
103+
104+
$er = new EasyPeasy(); // Fatal error
105+
106+
107+
```

src/Cacheton.php

Whitespace-only changes.

src/Limiton.php

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?php
2+
3+
namespace TonTon;
4+
5+
trait Limiton {
6+
7+
/**
8+
* @var reference to limiton array of instances
9+
*/
10+
private static $instances = [];
11+
12+
/**
13+
* @var limit of concurrent instances of the class
14+
*/
15+
public static $limit = 2;
16+
17+
/**
18+
* Creates a new instance of a limiton class flagged with a key.
19+
*
20+
* @param $key the key which the instance should be stored/retrieved
21+
*
22+
* @return self
23+
*/
24+
final public static function instance($key)
25+
{
26+
if(!array_key_exists($key, self::$instances)) {
27+
28+
if(count(self::$instances) < self::$limit) {
29+
self::$instances[$key] = new self;
30+
}
31+
32+
}
33+
34+
return self::$instances[$key];
35+
}
36+
37+
/**
38+
* Sets the maximum number of instances the class allows
39+
*
40+
* @param $number int number of instances allowed
41+
* @return void
42+
*/
43+
public function setLimit(int $number) {
44+
45+
self::$limit = $number;
46+
}
47+
48+
/**
49+
* Prevents calling the class using the new keyword, if the __construct is protected.
50+
*
51+
* @return void
52+
*/
53+
private function __construct() {}
54+
55+
/**
56+
* Prevents cloning the multiton instances.
57+
*
58+
* @return void
59+
*/
60+
final private function __clone() {}
61+
62+
/**
63+
* Prevents unserializing the multiton instances.
64+
*
65+
* @return void
66+
*/
67+
final private function __wakeup() {}
68+
}

0 commit comments

Comments
 (0)