練習 smart contract 的時候,看到 function modifiers 很有趣,所以又稱為 condition orientated programming,其精神在於讓 condition 可以重用,而且讓你的 function 內不會有太多的 if statement

所以後來思考了一下, php 應該也可以做到像是這樣的事情,所以才有了下面的 sample code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
<?php
interface Condition
{
public function assert(...$rule);
}

trait Operator
{
public function greatThan($left, $right)
{
return $left > $right;
}
}

class Vip implements Condition
{
public function assert(...$rule)
{
list($isVip) = $rule;
return ('yes' == $isVip) ? true : false;
}
}

class Money implements Condition
{
use Operator;

public function assert(...$rule)
{
list($money, $operator, $integer) = $rule;
return call_user_func([$this, $operator], $money, $integer);
}
}

class Judgement
{
public $conditionList = [];
public $status;

public function condition(Condition $condition)
{
$reflect = new ReflectionClass($condition);
$instanceName = $reflect->getShortName();
$this->conditionList[$instanceName] = $condition;
}

public function judge(Array $rules)
{
$result = true;

foreach ($this->conditionList as $instance) {
$reflect = new ReflectionClass($instance);
$instanceName = $reflect->getShortName();
$parameters = $rules[$instanceName];

$result = $result && call_user_func([$instance, 'assert'], ...$parameters);
}
$this->status = $result;
return $this;
}

public function then(Closure $callback)
{
return (true === $this->status) ? $callback() : false;
}
}


class User
{
public $money = 10;
public $isVip = 'yes';
}

// start your code
$user = new User;

$vipUserRule = new Judgement;
$vipUserRule->condition(new Vip);
$vipUserRule->condition(new Money);

$bonus = $vipUserRule
->judge([
'Vip' => [$user->isVip],
'Money' => [$user->money, 'greatThan', '50']
])
->then(function () use ($user) {
return $bonus = $user->money * 0.9 + 99;
});

var_export($bonus);
echo PHP_EOL;

其實還蠻有趣的,雖然上面的程式碼等價下面的程式碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class User
{
public $money = 10;
public $isVip = 'yes';
}

// start your code
$user = new User;
$bonus = false;
if ($user->isVip && $user->money > 50) {
$bonus = $user->money * 0.9 + 99;
}

var_export($bonus);
echo PHP_EOL;

那為什麼要寫得這麼複雜呢?其實不外乎有:

  1. condition 的重用
    這些 condition 是可以重複使用的,而且直覺,可以輕易的修改 condition 的內容
  2. 專注 function
    在你的 anonymous function 裡不會有任何 if statement,這樣就可以更容易知道這個 function 到底要做什麼事情

so, 就是個練習 :p