PHPプログラミング開発モード - ファクトリモードの詳細説明
PHP ファクトリーモード:
①抽象基本クラス: クラス内にいくつかの抽象メソッドを定義し、サブクラスに実装します
②抽象基底クラスから継承したサブクラス:基底クラスに抽象メソッドを実装
③ファクトリクラス: オブジェクトのインスタンス化に使用されます
1 采用封装方式 2 3 <?php 4 class Calc{ 5 /** 6 * 计算结果 7 * 8 * @param int|float $num1 9 * @param int|float $num2 10 * @param string $operator 11 * @return int|float 12 */ 13 public function calculate($num1,$num2,$operator){ 14 try { 15 $result=0; 16 switch ($operator){ 17 case '+': 18 $result= $num1+$num2; 19 break; 20 case '-': 21 $result= $num1-$num2; 22 break; 23 case '*': 24 $result= $num1*$num2; 25 break; 26 case '/': 27 if ($num2==0) { 28 throw new Exception("除数不能为0"); 29 } 30 $result= $num1/$num2; 31 break; 32 } 33 return $result; 34 }catch (Exception $e){ 35 echo "您输入有误:".$e->getMessage(); 36 } 37 } 38 } 39 $test=new Calc(); 40 // echo $test->calculate(2,3,'+');//打印:5 41 echo $test->calculate(5,0,'/');//打印:您输入有误:除数不能为0 42 ?>
利点: 上記のコードはオブジェクト指向のカプセル化機能を使用しています。 include クラスが含まれている限り、他のページでも気軽に使用できます。
欠点: 柔軟な拡張と保守ができない
例: 「剰余」演算を追加する場合は、switch ステートメント ブロックに分岐ステートメントを追加する必要があり、コードを次のように変更する必要があります
1 添加分支语句 2 3 <?php 4 class Calc{ 5 public function calculate($num1,$num2,$operator){ 6 try { 7 $result=0; 8 switch ($operator){ 9 //......省略...... 10 case '%': 11 $result= $num1%$num2; 12 break; 13 //......省略...... 14 } 15 }catch (Exception $e){ 16 echo "您输入有误:".$e->getMessage(); 17 } 18 } 19 } 20 ?>
コード分析: 上記の方法を使用して新しい関数演算を電卓に追加すると、次のような欠点があります
① 元のコードブロックを変更する必要がある 「新しい機能を追加する」ために、誤って元のコードを変更する可能性があります。
② 「べき乗」、「平方根」、「対数」、「三角関数」、「統計」などの多くの関数を追加したい場合、または、And、Or、などのプログラマ固有の計算関数を追加したい場合。 Xor ではないので、switch ステートメントに N 個の分岐ステートメントを追加する必要があります。計算関数に 20 または 30 の case 分岐ステートメントがある場合、コードが 1 画面を超えることを想像してください。コードの可読性が大幅に低下するだけでなく、小さな関数を追加するには、関連しない他の関数も追加する必要があります。説明すると、これによりプログラムの実行効率が大幅に低下します
解決策: OOP 継承とポリモーフィックなアイデアを採用する
1 工厂模式的初步实现 2 <?php 3 /** 4 * 操作类 5 * 因为包含有抽象方法,所以类必须声明为抽象类 6 */ 7 abstract class Operation{ 8 //抽象方法不能包含函数体 9 abstract public function getValue($num1,$num2);//强烈要求子类必须实现该功能函数 10 } 11 /** 12 * 加法类 13 */ 14 class OperationAdd extends Operation { 15 public function getValue($num1,$num2){ 16 return $num1+$num2; 17 } 18 } 19 /** 20 * 减法类 21 */ 22 class OperationSub extends Operation { 23 public function getValue($num1,$num2){ 24 return $num1-$num2; 25 } 26 } 27 /** 28 * 乘法类 29 */ 30 class OperationMul extends Operation { 31 public function getValue($num1,$num2){ 32 return $num1*$num2; 33 } 34 } 35 /** 36 * 除法类 37 */ 38 class OperationDiv extends Operation { 39 public function getValue($num1,$num2){ 40 try { 41 if ($num2==0){ 42 throw new Exception("除数不能为0"); 43 }else { 44 return $num1/$num2; 45 } 46 }catch (Exception $e){ 47 echo "错误信息:".$e->getMessage(); 48 } 49 } 50 } 51 ?>
分析: オブジェクト指向の継承機能を使用すると、「べき乗」、「平方根」、「対数」、「三角関数」、「統計」など、元のプログラムを簡単に拡張できます。
別のクラスを作成し (このクラスは仮想基本クラスを継承します)、クラス内の対応する関数 (累乗の計算など) を完了し、結合度を大幅に減らすだけで、将来のメンテナンスと拡張が容易になります。
<?php /** * 求余类(remainder) * */ class OperationRem extends Operation { public function getValue($num1,$num2){ return $num1%$num12; } } ?>
まだ未解決の問題が残っています。それは、ユーザーが入力したオペレーターに従ってプログラムに対応するオブジェクトをインスタンス化させる方法です。
解決策: 別のクラスを使用してインスタンス化プロセスを実装します。このクラスはファクトリ です。
コードは次のとおりです:
1 <?php 2 /** 3 * 工程类,主要用来创建对象 4 * 功能:根据输入的运算符号,工厂就能实例化出合适的对象 5 * 6 */ 7 class Factory{ 8 public static function createObj($operate){ 9 switch ($operate){ 10 case '+': 11 return new OperationAdd(); 12 break; 13 case '-': 14 return new OperationSub(); 15 break; 16 case '*': 17 return new OperationSub(); 18 break; 19 case '/': 20 return new OperationDiv(); 21 break; 22 } 23 } 24 } 25 $test=Factory::createObj('/'); 26 $result=$test->getValue(23,0); 27 echo $result; 28 ?>