2010-03-01 19 views
3

我已經閱讀了很多關於開發類(我正在使用php)的文章,標記行爲: '可擴展,健壯,可維護和可擴展'。如何創建一個「真正可擴展的」類

但是作爲一個初學者,我一直在創建類,就我而言,「只是抽象」。意思是我分開了一堆或重複的代碼,並將它們放在一個類中,並提供訪問常見任務的方法。我無法找到讓我的類可擴展的方法(我知道抽象類等的概念,我甚至使用它們,但只是定義其他類將遵循的方法)。事情是,我總是發現自己編輯核心類只是爲了添加功能

使我的課程具有可擴展性的任何提示? (我在這裏搜索了一切,彈出的所有內容都是對抽象類,接口和OOP的解釋,沒有關於指針的討論,或者有關製作可擴展類的一些技巧)。我很早就開始了「實際」oop編程(我來自的大學讓我繼續關於OOP的理論,但是他們讓我們在程序上工作,因爲它更快,它符合該死的項目截止日期,並且在我畢業前持續了4年)。

回答

2

你應該看看這本書Design Patterns: Elements of Reusable Object-Oriented Software

的問題正如你發現的那樣,使可擴展類將系統分解爲有用的和可重用的對象。

由於許多因素起作用:封裝,粒度,依賴性,靈活性,性能,進化,可重用性等等,這項任務很困難。

您是試圖模擬一些真實世界的場景,還是您專注於應用程序內的通信/協作和依賴關係?

這裏有一個例子,我認爲有點演示你在找什麼。當然還有更好的例子:

我想開發一個緩存系統,爲我的開發人員提供一個簡單的,規範化的API,無論他們在什麼地方緩存什麼東西。我想在緩存系統中(基本級別)做什麼?

  • 我希望能夠緩存的東西(套)
  • 我希望能夠取回的東西(獲取)
  • 我希望能夠緩存失效(刪除)

我想出了這一點:

abstract class MyNs_Cache 
{ 
    abstract public function Set($key, $data, $ttl); 
    abstract public function Get($key); 
    abstract public function Delete($key, $ttl); 
} 

有我的可擴展基類。然後我有三個緩存類MyNs_Cache_FsMyNs_Cache_ApcMyNs_Cache_Memcache

class MyNs_Cache_Fs 
{ 
    ... 

    public function Set($key, $data, $ttl) 
    { 
     // here I use fopen/fwrite/etc. to create the cached data 
    } 

    public function Get($key) 
    { 
     // here I retrieve the file from the filesystem (if it exists) 
    } 

    public function Delete($key) { ... } 
} 

這是相當直截了當。它根據FileSystem實現緩存。它不會提供任何超過我原來的課程的東西。

class MyNs_Cache_Apc 
{ 
    ... 

    public function Set($key, $data, $ttl) 
    { 
     return apc_add($key, $data, $ttl); // NOT A FILESYSTEM CALL 
    } 

    public function Get($key) { ... } // you get the idea. 

    // This is specific to APC, so I add the functionality HERE 
    // NOT in my main Caching class. 
    public function PurgeCache() 
    { 
     return apc_clear_cache(); 
    } 
} 

我的APC緩存做的一切,我想在緩存系統(設置/獲取/刪除),但它同時也提供清除整個緩存(東西是不適合我的文件系統緩存有用,並與memcached的是不可能的)的能力

class MyNs_Cache_Memcache 
{ 
    // Memcached needs a pool of servers. APC and filesystem don't. 
    private $servers = array(..); 

    // It also uses a memcached object. 
    private $conn; 

    public function __construct() 
    { 
     $this->conn = new Memcached; 

     foreach ($this->$servers as $server) 
      $this->AddServer($server); 
    } 
    ... // we do all the standard stuff using memcached methods 

    // We also want to be able to manage our connection pool 
    public function AddServer($server) 
    { 
     $this->conn->addServer(...); 
    } 

    // And in some cases, we use inc/dec from memcached 
    // APC doesn't have this, and it makes little sense in a filesystem 
    public function Increment($key) { ... } 
} 

現在我知道,我總是可以得到我的緩存中的對象之一,只是在$ obj->獲取(「some_key」),我將永遠得到一個結果。

同樣,我也可以訪問我目前正在嘗試使用的功能。

1

你並不需要修改的核心類添加功能,您可以覆蓋在子類中的方法,如:

class A { 
public function filter_string($str){ 
    return str_replace ('foo', 'bar', $str); 
} 
} 

class B extends A { 
public function filter_string($str){ 
    return str_replace ('machin', 'chose', parent::filter_string ($str)); 
} 
} 

$a = new A; 
echo $a->filter_string('foo machin'); // echoes 'bar machin' 

$b = new B; 
echo $b->filter_string('foo machin'); // echoes 'bar chose'