3

我已经阅读了很多关于开发类的文章(我正在使用 php),其标语是:“可扩展、健壮、可维护和可扩展”。

但作为一个初学者,我一直在创建用我的话来说“只是抽象的”的类。这意味着我只是将一堆或重复的代码分开并将它们放在一个类中并提供访问常见任务的方法。

问题是,我找不到使我的类可扩展的方法(我知道抽象类等的概念,我什至正在使用它们,但只是为了定义我的其他类将遵循的方法)。问题是,我总是发现自己编辑核心类只是为了添加功能

关于使我的课程可扩展的任何提示?(我在谷歌上搜索过,弹出的所有内容都是对抽象类、接口和 OOP 的解释,没有讨论指针或制作可扩展类的一些技巧)。

哦,顺便说一句,放轻松,我在 9 个月前就开始了“实际” oop 编程(我所在的大学让我学习 OOP 的理论,但他们让我们按程序工作,因为它更快并且符合该死的项目截止日期,持续了 4 年,直到我毕业)。

4

2 回答 2

2

你应该看看这本书设计模式:可重用的面向对象软件的元素

正如您所发现的,制作可扩展类的问题在于将系统分解为有用且可重用的对象。

这项任务很困难,因为许多因素都在起作用:封装、粒度、依赖性、灵活性、性能、演进、可重用性等等。

您是在尝试模拟一些真实世界的场景,还是专注于应用程序内部的通信/协作和依赖关系?

这是一个我认为有点展示你正在寻找的例子的例子。当然还有更多更好的例子:

我想开发一个缓存系统,为我的开发人员提供一个简单、规范化的 API,无论他们在什么地方/在哪里缓存东西。我在缓存系统中想要什么(在基本级别)?

  • 我希望能够缓存一些东西(设置)
  • 我希望能够检索到那个东西(get)
  • 我希望能够使缓存无效(删除)

我想出了这个:

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_Apc并且MyNs_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) { ... }
 }

这是相当直截了当的。它根据文件系统实现缓存。它没有提供任何超出我原来的课程的东西。

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->Get('some_key') 就可以得到结果。

同样,我也可以访问特定于我当前正在尝试使用的功能。

于 2010-03-01T02:58:43.940 回答
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'
于 2010-03-01T02:45:48.130 回答