มือใหม่คงมีความสับสนมากมายเกี่ยวกับรูปแบบการออกแบบ วันนี้เป็นสุดสัปดาห์ ดังนั้นฉันจึงใช้เวลาเขียนบทความเกี่ยวกับโหมดชิ้นเดียวรวมกับโหมดลูกโซ่คำสั่งเพื่อสร้างเนื้อหาหลักของระบบ บทความนี้เรียบง่ายเกินไปครับ นี่เป็นบทช่วยสอนสำหรับมือใหม่เพราะเวลามีจำกัด (ผมต้องไปชอปปิ้งกับภรรยา 555) มีความผิดปกติในการออกแบบ การเขียนโค้ดผิดปกติ มีข้อบกพร่อง ฯลฯ ผมหวังว่าทุกคน ฮีโร่สามารถชี้ให้เห็นได้สะดวก มาสร้างความก้าวหน้าด้วยกันนะ เลเวลของฉันมีจำกัด^_^
ฉันเชื่อว่าใครๆ ก็อ่านหนังสือหรือบทความเกี่ยวกับการปรับใช้รูปแบบการออกแบบใน PHP กันมาแล้ว แต่มีเพียงไม่กี่คนที่ให้ตัวอย่างโดยตรง อ่านแล้วสับสน ฉันรู้สึกว่าหากไม่มีการฝึกปฏิบัติโครงการ เป็นการยากที่จะเข้าใจส่วนรูปแบบการออกแบบ
เพื่อหลีกเลี่ยงไม่ให้โค้ดซับซ้อนเกินไป การจัดการข้อยกเว้นและเนื้อหาอื่นๆ จะไม่ถูกเพิ่มเข้าไป
สำหรับความรู้พื้นฐานของโหมดซิงเกิลตันและโหมดลูกโซ่คำสั่ง คุณสามารถ google ด้วยตัวเอง ฉันจะไม่ลงรายละเอียดในตัวอย่างโดยตรง:
<?php
-
*@author:NoAngels
*@เวลา: 30 สิงหาคม 2551
-
อินเทอร์เฟซ IRunAction{
//รับวิธีการที่กำหนดไว้ในคลาสที่สามารถเรียกใช้ในแอปได้
ฟังก์ชั่นคงที่ LoadActions();
//ฟังก์ชันรายการในคลาสใช้เพื่อเรียกใช้ฟังก์ชันอื่นๆ ในคลาส
ฟังก์ชั่น runAction($action, $args);
-
-
*ส่วนหลักของระบบ APP
-
คลาส APP{
ส่วนตัวคงที่ $__instance = null;
คำสั่ง $__ ส่วนตัวแบบคงที่ = array ();
ส่วนตัวคงที่ $__flag = 1;
ฟังก์ชั่นส่วนตัว __construct(){}
//การออกแบบโหมดชิ้นเดียวได้รับอินสแตนซ์เดียวของคลาสนี้
โหลดฟังก์ชันคงที่ () {
if(self::$__instance == null) self::$__instance = แอปใหม่;
กลับตัวเอง::$__อินสแตนซ์;
-
//เพิ่มการตั้งชื่อให้กับ $__instance ของ APP ทุกครั้งที่คุณเพิ่มคำสั่งใหม่ ให้ตรวจสอบว่ามีการเพิ่มอินสแตนซ์ของคลาสนี้มาก่อนหรือไม่
//ถ้ามีก็ไม่ต้องสนใจการดำเนินการนี้ ถ้าไม่มี ให้เพิ่มเข้าไป
ฟังก์ชั่นสาธารณะ addCommand($cmdName){
foreach (ตัวเอง :: $__ คำสั่งเป็น $ cmd) {
ถ้า(strtolower(get_class($cmd)) == strtolower(get_class($cmdName))){
ตนเอง::$__ธง = 0;
หยุดพัก;
-
-
ถ้า (ตนเอง::$__flag == 1) ตนเอง::$__commands[] = $cmdName;
ตนเอง::$__ธง = 1;
-
//ส่วนหลักของการออกแบบโหมดลูกโซ่คำสั่งเรียกใช้ฟังก์ชันรายการของอินสแตนซ์
//ขั้นแรกให้ตรวจสอบว่าการเรียกการดำเนินการนี้ได้รับอนุญาตในชั้นเรียนหรือไม่ ถ้าไม่เช่นนั้น ระบบจะแจ้งการดำเนินการที่ไม่ได้กำหนดไว้และออก
ฟังก์ชั่นสาธารณะ runCommand($action, $args){
ตัวเอง::$__ธง = 0;
foreach (ตัวเอง :: $__ คำสั่งเป็น $ cmd) {
if(in_array($action, $cmd->LoadActions())){
ตัวเอง::$__ธง = 1;
$cmd->runAction($การกระทำ, $args);
-
-
ถ้า (ตัวเอง :: $__ ธง == 0) {
ตนเอง::$__ธง = 1;
exit("การกระทำที่ไม่ได้กำหนดโดยการกระทำ : $action");
-
-
//หากต้องการลบอินสแตนซ์ของคลาส เพียงระบุชื่อของคลาส
ฟังก์ชั่นสาธารณะ RemoveCommand($className){
foreach(ตนเอง::$__คำสั่งเป็น $key=>$cmd){
ถ้า(strtolower(get_class($cmd)) == strtolower($className)){
ไม่ได้ตั้งค่า (ตนเอง::$__commands[$key]);
-
-
-
//สำหรับการทดสอบของทุกคนเพื่อดูว่าการเพิ่มและการลบสำเร็จหรือไม่
viewCommands ฟังก์ชั่นสาธารณะ () {
echo(นับ(ตัวเอง::$__คำสั่ง));
-
-
//ผู้ใช้คลาสใช้อินเทอร์เฟซ IRunAction
ผู้ใช้คลาสใช้ IRunAction{
//กำหนดการดำเนินการที่สามารถเรียกได้
$__actions ส่วนตัวแบบคงที่ = array('addUser', 'modifyUser', 'removeUser');
//รับการดำเนินการที่สามารถเรียกได้ ในกระบวนการจริง ไม่ใช่แค่รักคุณโดยตรง $__actions ได้รับการออกแบบให้เป็นการโทรสาธารณะ
//คุณควรออกแบบฟังก์ชัน LoadActions เพื่อรับค่า $__actions
LoadActions ฟังก์ชั่นสาธารณะแบบคงที่ () {
คืนตัวเอง::$__actions;
-
//เรียกใช้ฟังก์ชันที่ระบุ
ฟังก์ชั่นสาธารณะ runAction($action, $args){
//หากคุณไม่เข้าใจวิธีใช้ฟังก์ชันนี้ โปรดดูคู่มือ
call_user_func(อาร์เรย์($นี่,$การกระทำ), $args);
-
//เป็นเพียงฟังก์ชันทดสอบ
ฟังก์ชั่นที่ได้รับการป้องกัน addUser($name){
เสียงสะท้อน($ชื่อ);
-
-
//ผู้ใช้ที่เหมือนการทดสอบ
การทดสอบคลาสใช้ IRunAction{
$__actions ส่วนตัวแบบคงที่ = array('addTest', 'modifyTest', 'removeTest');
LoadActions ฟังก์ชั่นสาธารณะแบบคงที่ () {
คืนตัวเอง::$__actions;
-
ฟังก์ชั่นสาธารณะ runAction($action, $args){
call_user_func(อาร์เรย์($นี่,$การกระทำ), $args);
-
ฟังก์ชั่นที่ได้รับการป้องกัน addTest ($ ชื่อ) {
เสียงสะท้อน($ชื่อ);
-
-
//ต่อไปนี้เป็นโค้ดทดสอบ
APP::Load()->addCommand(ผู้ใช้ใหม่);
APP::Load()->addCommand(ผู้ใช้ใหม่);
APP::Load()->addCommand(ผู้ใช้ใหม่);
APP::Load()->addCommand(ผู้ใช้ใหม่);
APP::Load()->runCommand('addUser', 'NoAngels');
APP::Load()->addCommand(การทดสอบใหม่);
APP::Load()->runCommand('addTest', null);
คลาส APP ได้รับการออกแบบในโหมดซิงเกิลซึ่งเป็นส่วนหลักของระบบ ฉันเชื่อว่าคุณจะรู้ได้โดยดูจากโค้ดที่วิธี Load คือ เพื่อโหลดอินสแตนซ์คลาส APP ซึ่งเทียบเท่ากับวิธี getInstance static ในหนังสือบางเล่มมีวิธีการสาธารณะสามวิธี: addCommand, runCommand และ RemoveCommand นอกจากนี้ runCommand ยังเป็นโปรแกรมเริ่มต้นหลักของโหมดลูกโซ่คำสั่งด้วย ดูซอร์สโค้ดสำหรับการใช้งานเฉพาะ โค้ดนี้เขียนไว้อย่างชัดเจน ฉันจะไม่ลงรายละเอียดที่นี่
ผู้ใช้คลาสและการทดสอบใช้อินเทอร์เฟซ IRunAction ทั้งสองคลาสกำหนดตัวแปรส่วนตัวแบบคงที่ $__actions ซึ่งเป็นอาร์เรย์ที่มีการดำเนินการที่สามารถเรียกได้โดยฟังก์ชัน runCommand ของ APP
ต่อไปนี้เป็นกระบวนการทำงานของระบบ:
การเริ่มต้น APP
-------addCommand เพิ่มคลาสที่การดำเนินการที่จะรันเป็นของ APP หากคลาสที่เพิ่มได้รับการออกแบบโดยใช้โหมดซิงเกิลตัน คุณสามารถเพิ่ม addCommand(SingletonClass::Load()) ได้ดังนี้ มิฉะนั้นคุณสามารถเพิ่มได้ดังนี้ โทร
addCommand(new someClass)
-------runCommand เรียกใช้การดำเนินการ ตัวอย่างเช่น มีการดำเนินการ addUser ในคลาส User ฉันสามารถเปิดใช้งาน runCommand($acttion, $args) ได้โดยตรง เป็นอินสแตนซ์ของคลาสใดคลาสหนึ่ง หากคุณมีการดำเนินการนี้ ให้เรียกใช้ฟังก์ชัน runAction ของอินสแตนซ์ หากคุณไม่ได้เพิ่มอินสแตนซ์ของคลาสใดคลาสหนึ่งโดยใช้ addCommand คุณจะได้รับพร้อมท์สำหรับการดำเนินการที่ไม่ได้กำหนดและออก
runAction ในคลาส User และคลาส Test เรียก call_user_func ซึ่งเป็นฟังก์ชันที่ใช้กันทั่วไปในคลาสนี้เรียกว่า
เคล็ดลับ: นี่คือจุดสิ้นสุดของคำอธิบายและตัวอย่าง วิธีใช้แนวคิดนี้ แค่ดูว่ามันเป็นความเข้าใจของคุณเองที่คุณต้องทำทุกอย่างด้วยตัวเอง (ปล.: สามารถทำเป็นไฟล์รายการเดียวในเฟรมเวิร์กได้ การใช้ MVC หรือไม่นั้นขึ้นอยู่กับสิ่งที่คุณคิด)