38

我刚读了工厂方法。我知道它提供了一种将实例化委托给子类的方法。但我无法理解在现实世界场景中的可能用途。

谁能举一个典型的例子来说明如何使用工厂方法模式,以便我可以与我所读的内容联系起来。

哪个工厂方法模式是最佳解决方案的问题陈述足以说明问题。

4

5 回答 5

54

实现工厂设计模式的类充当多个类之间的桥梁。考虑一个使用多个数据库服务器(如 SQL Server 和 Oracle)的示例。如果您正在使用 SQL Server 数据库作为后端开发应用程序,但将来需要将后端数据库更改为 oracle,如果您尚未按照工厂设计模式编写代码,则需要修改所有代码。

在工厂设计模式中,您只需要做很少的工作即可实现这一目标。实现工厂设计模式的类会照顾您并减轻您的负担。从数据库服务器切换根本不会打扰您。您只需要在配置文件中进行一些小的更改。

于 2010-03-05T10:54:05.617 回答
9

具有静态创建的示例 php 代码:

interface DbTable
{
    public function doSomething(): void;
}

class MySqlTable implements DbTable
{
    public function doSomething(): void
    { }
}

class OracleTable implements DbTable
{
    public function doSomething(): void
    { }
}

class TableFactory
{
    public static function createTable(string $type = null): DbTable
    {
        if ($type === 'oracle') {
            return new OracleTable();
        }
        return new MySqlTable(); // default is mysql
    }
}

// client
$oracleTable = TableFactory::createTable('oracle');
$oracleTable->doSomething();

为了使其更具动态性(稍后修改较少):

interface DbTable
{
    public function doSomething(): void;
}

class MySqlTable implements DbTable
{
    public function doSomething(): void
    { }
}

class OracleTable implements DbTable
{
    public function doSomething(): void
    { }
}

class TableFactory
{
    public static function createTable(string $tableName = null): DbTable
    {
        $className = __NAMESPACE__ . $tableName . 'Table';
        if (class_exists($className)) {
            $table = new $className();
            if ($table instanceof DbTable) {
               return $table;
            }
        }
        throw new \Exception("Class $className doesn't exists or it's not implementing DbTable interface");
    }
}

$tbl = TableFactory::createTable('Oracle');
$tbl->doSomething();
于 2014-12-31T21:33:32.183 回答
3

从我现在正在开发的API:

WebGalleryFactory factory = WebGalleryFactory.newInstance (WebGalleryType.PICASA);
WebAlbum album = factory.createAlbum (title, description);

在此示例中,我使用工厂方法创建某种类型的抽象工厂(示例中为 PICASA)。

这两种模式经常一起使用。

于 2010-03-05T10:54:58.193 回答
3

Zend_Db 在它的Zend_Db_Adapter类中使用它来允许基于从配置对象传递的数据库设置创建不同类型的数据库对象。

于 2010-03-05T10:56:01.393 回答
2

.NET基类库(BCL) 中的一个示例是Control.CreateControlsInstance,它被 (Windows 窗体) Control 类的许多其他成员使用。

您可以覆盖此受保护的方法以提供您自己的控件集合,例如当您实现自定义控件时。

于 2010-03-05T10:59:04.417 回答