程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> PHP綜合 >> PHP、Python和Javascript的裝飾器模式對比

PHP、Python和Javascript的裝飾器模式對比

編輯:PHP綜合

修飾模式(Decorator Pattern),又叫裝飾者模式,是面向對象編程領域中,一種動態地往一個類中添加新的行為的設計模式。就功能而言,修飾模式相比生成子類更為靈活,這樣可以給某個對象而不是整個類添加一些功能。裝飾模式非常適用於靈活擴展對象的功能,下面是裝飾模式的UML圖:

例如,有一個技術論壇,用戶通過留言進行溝通,由於剛開始論壇裡都是熟人,幾乎都不需要對留言的內容作出審核,接收留言的頁面可以是這樣:

class SaveMsg(){
 private $msg;
 public function __construct($msg){
 $this->msg=$msg;
 }
 public function __store(){
 //存入數據庫
 }
}

後來,隨著論壇逐漸出名,就有一些人在上面發鏈接,就需要對含有鏈接的消息進行過濾,論壇進一步發展,發現除開發垃圾鏈接的外,還有很多無用的灌水,到後來可能還有攻擊等等各種不正常的帖子,所以對論壇帖子的管理,可以單獨抽象出一個類進行管理,當需要擴充過濾規則時,可以進行動態擴充。

//基類
abstract class Filter{
 abstract public function isForbid();
}
//基礎過濾類
class MsgFilter extends Filter{
 public $content;
 public function __construct($msg){
 $this->content=$msg;
 }
 public function isForbid(){
 if(preg_match("/https?/i",$this->content)){
 return [true,"Not Allowed Urls"];
 }else{
 return [false];
 }
 }
}
//裝飾器,用來擴充功能
abstract class FilterDecorator extends Filter{
 protected $obj;
 public function __construct(Filter $obj){
 $this->obj=$obj;
 }
}
//新過濾器,判斷是否重復發帖
class repeat extends FilterDecorator{
 public function isForbid(){
 if($this->obj->isForbid()[0] === true){
 //判定是否包含url
 return $this->obj->isForbid();
 }else if($this->obj->content == "this is a test"){
 //判定是否重復發帖
 return [true,"Repeat Posts"];
 }else{
 return [false];
 }
 }
}
$test = new MsgFilter("httpsfdjoafdsajof");
print_r($test->isForbid());//被禁止
$test2 = new repeat(new MsgFilter("this is a test"));
print_r($test2->isForbid());//被禁止


在python中,不存在抽象類和方法,實現就更加簡單:

#!/usr/bin/env python
class Filter():
  pass
class MsgFilter(Filter):
  def __init__(self,msg):
    self.content=msg
  def isForbid(self):
    if('http' in self.content):
      return [True,"Not Allowed Urls"]
    else:
      return [False]
class FilterDecorator(Filter):
  def __init__(self,obj):
    self._obj=obj
class Repeat(FilterDecorator):
  def isForbid(self):
    if self._obj.isForbid()[0]:
      return self._obj.isForbid()
    elif self._obj.content == 'this is a test':
      return [True,"Repeat Posts"];
    else:
      return [False]
test = MsgFilter("this is a content have http urls")
print test.isForbid()
test2 = Repeat(MsgFilter('this is a test'))
print test2.isForbid()

Javascript中,沒有嚴格的類,所有繼承都基於原型,理解起來會稍費功夫:

function MsgFilter(msg){
 this.content=msg;
 this.isForbid=function(){
 if(this.content.match(/http/g)){
 return [true,"Not Allowed Urls"];
 }else {
 return [false];
 }
 }
}
function Repeat(obj){
 var _obj=obj;
 this.isForbid=function(){
 if(_obj.isForbid[0] === true){
 return _obj.isForbid();
 }else if(_obj.content=='this is a test'){
 return [true,"Repeat Posts"];
 }else{
 return [false];
 }
 }
}
var test = new MsgFilter("his is a content have http urls");
console.log(test.isForbid());
var test2 = new Repeat(new MsgFilter("this is a test"));
console.log(test2.isForbid());

由於Javascript缺少類的特性,繼承對於它來說就顯得有點雞肋了,上面的代碼看起來更像是對兩個函數的處理, 在python中,有更加簡單的添加裝飾器的方法,直接通過”@”給函數自動添加裝飾器,達到擴展功能的目的,如:

def Decorator(F):
  def newF(age):
    print "You Are Calling",F.__name__
    F(age)
  return newF
@Decorator
#通過@給函數showAge添加裝飾器Decorator
def showAge(age):
  print "hello , i am %d years old"%age
showAge(10)

裝飾模式的目的是解決動態擴展功能的難題,裝飾模式的本質是對對象的靈活處理,理解裝飾模式,不僅能深入了解面向對象的程序設計,更能提高編程的思維能力。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved