第二章 面向对象的设计原则
2.1 面向对象设计的五大原则
单一职责原则
接口隔离原则
开放-封闭原则
替换原则
依赖倒置原则
2.1.1 单一职责原则SRP
单一职责有两个含义:一个是避免相同的职责分散到不同的类中,另一个是避免一个类承担太多的职责。
原因 1可以减少类之间的耦合 2提高类的复用性
代码语言:javascript复制class Config{
public $host="localhost";
static $port="3306";
static $user="root";
static $password="";
public $charset="utf8";
public $database="test";
public $file="";
}
interface Db_Adapter{
public function connect($config);
public function query($query,$handle);
}
class Db_Adapter_Mysql implements Db_Adapter{
private $_dbLink;
public function connect($config)
{
if($this->_dbLink=@mysql_connect($config->host.(empty($config->port)?'':':'.$config->port),$config->user,$config->password,true)){
if(@mysql_select_db($config->database,$this->_dbLink)){
if($config->charset){
mysql_query("SET NAMES '{$config->charset}'",$this->_dbLink);
}
return $this->_dbLink;
}
}
/**数据库异常**/
throw new Db_Exception(@mysql_error($this->_dbLink));
}
public function query($query,$handle){
if($resource=@mysql_query($query,$handle)){
return $resource;
}
}
}
class Db_Exception extends exception{
function __toString(){
return "<div style='color:red'>Exception{$this->getCode()}:{$this->getMessage()} in File:{$this->getFile()} on line:{$this->getLine()}</div>";
}
}
class Db_Adapter_sqlite implements Db_Adapter{
private $_dbLink;
public function connect($config){
if($this->_dbLink=sqlite_open($config->file,0666,$error)){
return $this->_dbLink;
}
throw new Db_Exception($error);
}
public function query($query,$handle){
if($resource=@sqlite_query($query,$handle)){
return $resource;
}
}
}
class sqlFactory{
public static function factory($type){
$classname='Db_adapter_'.$type;
return new $classname;
}
}
$config=new Config();
$connect=sqlFactory::factory("mysql")->connect($config);
$connect=sqlFactory::factory("SQLite")->connect($config);
代码语言:javascript复制class cook{
public function meal(){
echo "番茄炒蛋",PHP_EOL;
}
public function drink(){
echo "紫菜蛋花汤",PHP_EOL;
}
public function ok(){
echo '完毕',PHP_EOL;
}
}
interface Command{
public function execute();
}
class MealCommand implements Command{
private $cook;
public function __construct(cook $cook){
$this->cook=$cook;
}
public function execute(){
$this->cook->meal();
}
}
class DrinkCommand implements Command{
private $cook;
public function __construct(cook $cook){
$this->cook=$cook;
}
public function execute(){
$this->cook->drink();
}
}
class cookControl{
private $mealcommand;
private $drinkcommand;
public function addCommand(Command $mealcommand,Command $drinkcommand){
$this->mealcommand=$mealcommand;
$this->drinkcommand=$drinkcommand;
}
public function callmeal(){
$this->mealcommand->execute();
}
public function calldrink(){
$this->drinkcommand->execute();
}
}
$control=new cookControl;
$cook=new cook;
$mealcommand=new MealCommand($cook);
$drinkcommand=new DrinkCommand($cook);
$control->addCommand($mealcommand,$drinkcommand);
$control->callmeal();
$control->calldrink();
2.1.2 接口隔离原则 ISP
利用委托分离接口
利用多继承分离接口
2.1.3 开放-封闭原则 OCP
1.什么是开放-封闭原则 一个模块在扩展性方面应该是开放的而在更改性能方面应该是封闭的。
代码语言:javascript复制interface process{
public function process();
}
class playerencode implements process{
public function process(){
echo "encodern";
}
}
class playeroutput implements process{
public function process(){
echo "outputrn";
}
}
class playProcess{
private $message=null;
public function __construct(){
}
public function callback(event $event){
$this->message=$event->click();
if($this->message instanceof process){
$this->message->process();
}
}
}
class mp4{
public function work(){
$playProcess=new playProcess();
$playProcess->callback(new event('encode'));
$playProcess->callback(new event('output'));
}
}
class event{
private $m;
public function __construct($me){
$this->m=$me;
}
public function click(){
switch($this->m){
case 'encode':
return new playerencode();
break;
case 'output':
return new playeroutput();
break;
}
}
}
$mp4=new mp4;
$mp4->work();
2 如何遵守开放-封闭原则 1)在设计方面充分应用 “抽象”和“封装”的思想。 2)在系统功能编程实现方面应用面向接口的编程。
2.1.4 替换原则 LSP
子类必须能够替换掉它们的父类型,并且出现在父类型能够出现的任何地方。
2.1.5 依赖倒置原则 DIP
上层模块不应该依赖于下层模块,它们共同依赖于一个抽象(父类不能依赖子类,它们都要依赖抽象类) 抽象不能依赖于具体,具体应该依赖于抽象。
2.2 一个面向对象留言本的实例
代码语言:javascript复制class message{
public $name;
public $email;
public $content;
public function __set($name,$value){
$this->name=$value;
}
public function __get($name){
if(!isset($this->$name)){
$this->$name=NULL;
}
}
}
class gbookModel{
private $bookPath;
private $data;
public function setBookPath($bookPath){
$this->bookPath=$bookPath;
}
public function getBookPath(){
return $this->bookPath;
}
public function open(){
}
public function close(){
}
public function read(){
return file_get_contents($this->bookPath);
}
public function write($data){
$this->data=self::safe($data)->name."&".self::safe($data)->email."rnsaid:rn".self::safe($data)->content;
return file_put_contents($this->bookPath,$this->data,FILE_APPEND);
}
public static function safe($data){
$reflect=new ReflectionObject($data);
$props=$reflect->getProperties();
$messagebox=new stdClass();
foreach($props as $prop){
$ivar=$prop->getName();
$messagebox->$ivar=trim($prop->getValue($data));
}
return $messagebox;
}
public function delete(){
file_put_contents($this->bookPath,'it's empty now');
}
public function readByPage(){
$handle=file($this->bookPath);
$count=count($handle);
$page=isset($_GET['page'])? intval($_GET['page']):1;
if($page<1 || $page>$count) $page=1;
$pnum=9;
$begin=($page-1)*$pnum;
$end=($begin $pnum)>$count?$count:$begin $pnum;
for($i=$begin;$i<$end;$i ){
echo '<strong>',$i 1,'</strong>',$handle[$i],'<br/>';
}
for($i=1;$i<ceil($count/$pnum);$i ){
echo "<a href=?page=${i}>${i}</a>";
}
}
}
class leaveModel{
public function write(gbookModel $gb,$data){
$book=$gb->getBookPath();
$gb->write($data);
}
}
class authorControl{
public function message(leaveModel $l,gbookModel $g,message $data){
$l->write($g,$data);
}
public function view(gbookModel $g){
return $g->read();
}
public function viewByPage(gbookModel $g){
return $g->readByPage();
}
public function delete(gbookModel $g){
$g->delete();
echo self::view($g);
}
}
$message=new message;
$message->name='lilu';
$message->email='lilugirl2005@126.com';
$message->content='a crazy phper love php so much.';
$gb=new authorControl();
$pen=new leaveModel();
$book=new gbookModel();
$book->setBookPath("C:wamp2a.txt");
$gb->message($pen,$book,$message);
//echo $gb->view($book);
echo $gb->viewByPage($book);
//$gb->delete($book);