Artikel ini membawakan anda pengetahuan yang berkaitan tentang PHP, yang terutamanya memperkenalkan beberapa model pembangunan biasa Mari kita lihat bersama-sama saya harap ia akan membantu semua orang.
Enam Prinsip Corak Reka Bentuk
Prinsip Terbuka dan Tertutup: Entiti perisian seperti kelas, modul dan fungsi harus terbuka kepada sambungan dan tertutup kepada pengubahsuaian.
Prinsip Penggantian Lebih Kaya: Semua rujukan kepada kelas asas mesti boleh menggunakan objek subkelasnya dengan telus
Prinsip Penyongsangan Kebergantungan: Modul peringkat tinggi tidak boleh bergantung pada modul peringkat rendah. kedua-duanya harus Bergantung pada abstraksinya tidak harus bergantung pada butiran;
Prinsip Tanggungjawab Tunggal: Jangan mempunyai lebih daripada satu sebab untuk pertukaran kelas. Dalam istilah orang awam, kelas hanya bertanggungjawab untuk satu tanggungjawab.
Prinsip pengasingan antara muka: Pelanggan tidak seharusnya bergantung pada antara muka yang tidak diperlukannya;
Hukum Demeter: Objek harus menyimpan pengetahuan yang paling sedikit tentang objek lain.
Ciri: Menggunakan mod singleton, anda boleh mengelakkan sejumlah besar sumber digunakan oleh operasi baharu
Kelas Singleton It tidak boleh dibuat secara langsung dengan instantiasi, tetapi hanya boleh dibuat instantiation oleh kelas itu sendiri. Oleh itu, untuk mendapatkan kesan sekatan sedemikian, pembina mesti ditandakan secara peribadi, dengan itu menghalang kelas daripada dijadikan instantiated.
Memerlukan pembolehubah ahli statik peribadi untuk menyimpan tika kelas dan mendedahkan kaedah statik awam yang boleh mengakses tika itu.
Dalam PHP, untuk menghalang orang lain daripada mengklon contoh kelas tunggal, kaedah __clone() persendirian kosong biasanya disediakan untuknya.
$_instance mesti diisytiharkan sebagai pembolehubah persendirian statik
Pembina dan pemusnah mesti diisytiharkan sebagai persendirian untuk mengelakkan program luaran daripada menggunakan yang baharu kelas. Kehilangan makna mod tunggal
Kaedah getInstance() mesti ditetapkan kepada awam, dan kaedah ini mesti dipanggil untuk mengembalikan rujukan kepada contoh
::Operator hanya boleh mengakses pembolehubah statik dan fungsi statik
objek baharu akan menggunakan memori
Senario penggunaan: Tempat yang paling biasa digunakan ialah sambungan pangkalan data.
Selepas menggunakan corak tunggal untuk menjana objek, objek itu boleh digunakan oleh banyak objek lain.
Kaedah __clone() persendirian menghalang pengklonan objek
<?php class Singleton{ //私有属性,用于保存实例 private static $instance; //构造方法私有化,防止外部创建实例 private function __construct(){}//公有方法,用于获取实例 public static function getInstance(){ //判断实例有无创建,没有的话创建实例并返回,有的话直接返回 if(!(self::$instance instanceof self)){ self::$instance = new self(); } return self::$instance; } //克隆方法私有化,防止复制实例 private function __clone(){}}
Gunakan kaedah baharu untuk membuat instantiasi kelas. Setiap instantiasi hanya perlu memanggil kaedah dalam kelas kilang untuk membuat instantiat.
Kelebihan: Memandangkan kelas boleh dibuat seketika di banyak tempat. Apabila nama kelas atau parameter berubah, mod kilang boleh diubah suai dengan mudah dan cepat sekali dalam kaedah di bawah kelas kilang, mengelakkan keperluan untuk mengubah suai objek yang diinstantiate satu demi satu
Test1.php
Sebagai contoh, dengan mengandaikan bahawa segi empat tepat dan bulatan mempunyai kaedah yang sama, maka apabila kami menggunakan API yang disediakan oleh kelas asas untuk mencipta tika, kami akan secara automatik mencipta tika kelas yang sepadan dengan menghantar parameter panjang dan luas<?php class Test1 { static function test() { echo FILE; } }Factory.php <?php class Factory { /** *如果某个类在很多的文件中都new ClassName(),那么万一这个类的名字 *发生变更或者参数发生变化,如果不使用工厂模式,就需要修改每一个PHP *代码,使用了工厂模式之后,只需要修改工厂类或者方法就可以了。 */ static function createDatabase() { $test = new Test1(); return $test; } } Test.php <?php spl_autoload_register('autoload1'); $test = Factory::createDatabase(); $test->test();function autoload1($class) { $dir = __DIR__; $requireFile = $dir."\".$class.".php"; require $requireFile; }} Test1.php <?php class Test1 { protected static tt) { echo "对象已经创建<br>"; return self::tt = new Test1(); echo "创建对象<br>"; return self::$tt; } }function echoHello() { echo "Hello<br>"; }} Test.php <?php spl_autoload_register('autoload1'); $test = Test1::getInstance(); $test->echoHello(); $test = Test1::getInstance(); $test->echoHello(); $test = Test1::getInstance(); $test->echoHello(); $test = Test1::getInstance(); $test->echoHello();function autoload1($class) { $dir = __DIR__; $requireFile = $dir."\".$class.".php"; require $requireFile; }}
<?php interface InterfaceShape { function getArea(); function getCircumference(); }/** • 矩形 */ class Rectangle implements InterfaceShape { private $width; private $height; public function __construct($width, $height) { $this->width = $width; $this->height = $height; } public function getArea() { return $this->width* $this->height; } public function getCircumference() { return 2 * $this->width + 2 * $this->height; } }/** • 圆形 */ class Circle implements InterfaceShape { private $radius; function __construct($radius) { $this->radius = $radius; } public function getArea() { return M_PI * pow($this->radius, 2); } public function getCircumference() { return 2 * M_PI * $this->radius; } }/** • 形状工厂类 */ class FactoryShape { public static function create() { switch (func_num_args()) { case1: return newCircle(func_get_arg(0)); case2: return newRectangle(func_get_arg(0), func_get_arg(1)); default: # code... break; } } }rect); echo "<br>";// object(Circle)#2 (1) { ["radius":"Circle":private]=> int(4) } circle);
<?php class Register { protected static $objects;//将对象注册到全局的树上 function set($alias,$object) { self::$objects[$alias] = $object;//将对象放到树上 } static function get($name) { return self::$objects[$name];//获取某个注册到树上的对象 } function _unset($alias) { unset(self::$objects[$alias]);//移除某个注册到树上的对象。 }}
Mula-mula mengisytiharkan fail antara muka strategi dan tetapkan gelagat strategi yang disertakan. Kemudian, tentukan setiap kelas pelaksanaan strategi khusus.
UserStrategy.php
<?php /*• 声明策略文件的接口,约定策略包含的行为 */interface UserStrategy { function showAd(); function showCategory(); }FemaleUser.php <?phprequire_once 'Loader.php'; class FemaleUser implements UserStrategy { function showAd() { echo "2016冬季女装"; }function showCategory(){ echo "女装"; }} MaleUser.php <?phprequire_once 'Loader.php'; class MaleUser implements UserStrategy { function showAd(){ echo "IPhone6s"; }function showCategory(){ echo "电子产品"; }} Page.php//执行文件 <?php require_once 'Loader.php'; class Page { protected $strategy;function index(){ echo "AD"; $this->strategy->showAd(); echo "<br>"; echo "Category"; $this->strategy->showCategory(); echo "<br>"; } function setStrategy(UserStrategy $strategy){ $this->strategy = $strategy; }} $page = new Page(); if(isset($_GET['male'])){ $strategy = new MaleUser(); }else { $strategy = new FemaleUser(); }strategy); $page->index();
Melalui kaedah di atas, anda boleh mendapati kandungan berbeza dipaparkan apabila pengguna berbeza log masuk, tetapi pengekodan keras semasa paparan diselesaikan soalan . Jika anda ingin menambah strategi, anda hanya perlu menambah kelas pelaksanaan strategi, kemudian lakukan pertimbangan dalam fail kemasukan dan lulus dalam kelas ini. Mencapai decoupling. Laksanakan penyongsangan pergantungan dan penyongsangan kawalan (untuk difahami melalui antara muka, tidak ada pergantungan langsung antara kelas. Apabila menggunakan kelas ini, kelas pelaksanaan antara muka dihantar secara dinamik. Jika anda ingin menggantikan kelas, anda hanya perlu menyediakan kelas pelaksanaan yang melaksanakan antara muka, dan penggantian boleh diselesaikan dengan mengubah suai satu baris kod.
观察者模式(Observer),当一个对象状态发生变化时,依赖它的对象全部会收到通知,并自动更新(一个对象通过提供方法允许另一个对象即观察者 注册自己)使本身变得可观察。当可观察的对象更改时,它会将消息发送到已注册的观察者)
场景1:一个事件发生后,要执行一连串更新操作。传统的编程方式,就是在事件的代码之后直接加入处理的逻辑。当更新的逻辑增多之后,代码会变得难以维护。这种方式是耦合的,侵入式的,增加新的逻辑需要修改事件的主体代码。
场景2: 用户登录,需要写日志,送积分,参与活动等;使用消息队列,把用户和日志,积分,活动之间解耦合
观察者模式实现了低耦合,非侵入式的通知与更新机制。
<?php /* 观察者接口 */ interface InterfaceObserver { function onListen($sender, $args); function getObserverName(); }// 可被观察者接口 interface InterfaceObservable { function addObserver(observer_name); }// 观察者抽象类 abstract class Observer implements InterfaceObserver { protected $observer_name;function getObserverName() { return $this->observer_name; }function onListen($sender, $args) {} }// 可被观察类 abstract class Observable implements InterfaceObservable { protected $observers = array();public function addObserver(observerinstanceofInterfaceObserver) { $this->observers[] = $observer; } }public function removeObserver(this->observersas $index => observer->getObserverName() === this->observers, $index, 1); return; } } } }// 模拟一个可以被观察的类 class A extends Observable { public function addListener(this->observersas $observer) { this, $listener); } } }// 模拟一个观察者类 class B extends Observer { protected $observer_name = 'B';public function onListen($sender, sender); echo "<br>"; var_dump($args); echo "<br>"; } }// 模拟另外一个观察者类 class C extends Observer { protected $observer_name = 'C';public function onListen($sender, sender); echo "<br>"; var_dump($args); echo "<br>"; } }a->addObserver(new B()); $a->addObserver(new C());// 可以看到观察到的信息 $a->addListener('D');// 移除观察者 $a->removeObserver('B');// 打印的信息: // object(A)#1 (1) { ["observers":protected]=> array(2) { [0]=> object(B)#2 (1) { ["observer_name":protected]=> string(1) "B" } [1]=> object(C)#3 (1) { ["observer_name":protected]=> string(1) "C" } } } // string(1) "D" // object(A)#1 (1) { ["observers":protected]=> array(2) { [0]=> object(B)#2 (1) { ["observer_name":protected]=> string(1) "B" } [1]=> object(C)#3 (1) { ["observer_name":protected]=> string(1) "C" } } } // string(1) "D"
装饰器模式, 根据运行时不同的情景动态地为某个对象调用前后添加不同的行
一个类提供了一项功能,如果要在修改并添加额外的功能,传统的编程模式,需要写一个子类继承它,并重写实现类的方法,使用装饰器模式,仅需要在运行时添加一个装饰器对象即可实现,可以实现最大额灵活性
场景:
1.symfony 控制器中beforepost afterpost 中post提交前和提交后,对数据处理
2.当某一功能或方法draw,要满足不同的功能需求时,可以使用装饰器模式
/** • 输出一个字符串 • 装饰器动态添加功能 • Class EchoText */ class EchoText { protected $decorator = []; public function Index() { //调用装饰器前置操作 $this->beforeEcho(); echo "你好,我是装饰器。"; //调用装饰器后置操作 $this->afterEcho(); } //增加装饰器 public function addDecorator(Decorator $decorator) { $this->decorator[] = $decorator; } //执行装饰器前置操作 先进先出原则 protected function beforeEcho() { foreach ($this->decorator as $decorator) $decorator->before(); } //执行装饰器后置操作 先进后出原则 protected function afterEcho() { this->decorator); foreach ($tmp as $decorator) $decorator->after(); } }/** • 装饰器接口 • Class Decorator */ interface Decorator { public function before(); public function after(); }/** • 颜色装饰器实现 • Class ColorDecorator */ class ColorDecorator implements Decorator { protected $color; public function __construct($color) { $this->color = $color; } public function before() { echo "<dis style='color: {$this->color}'>"; } public function after() { echo "</div>"; } }/** • 字体大小装饰器实现 • Class SizeDecorator */ class SizeDecorator implements Decorator { protected $size; public function __construct($size) { $this->size = $size; } public function before() { echo "<dis style='font-size: {$this->size}px'>"; } public function after() { echo "</div>"; } }//实例化输出类 echo->addDecorator(new ColorDecorator('red')); //增加装饰器 echo->Index(); //输出<dis style='color: red'><dis style='font-size: 22px'>你好,我是装饰器。</div></div>
将一个类的接口转换成客户希望的另一个接口,适配器模式使得原本的由于接口不兼容而不能一起工作的那些类可以一起工作。
场景:老代码接口不适应新的接口需求,或者代码很多很乱不便于继续修改,或者使用第三方类库。例如:php连接数据库的方法:mysql,,mysqli,pdo,可以用适配器统一
//老的代码 class User {private $name; function __construct($name) { $this->name = $name; } public function getName() { return $this->name; }} //新代码,开放平台标准接口 interface UserInterface { function getUserName(); }class UserInfo implements UserInterface { protected $user; function __construct($user) { $this->user = $user; } public function getUserName() { return $this->user->getName(); }} $olduser = new User('张三'); echo $olduser->getName()."n";olduser); echo $newuser->getUserName()."n";
推荐学习:《PHP视频教程》
Atas ialah kandungan terperinci Beberapa corak pembangunan biasa dalam PHP. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!