【问题标题】:Assistance with factory pattern implementation协助工厂模式实施
【发布时间】:2013-07-15 16:42:59
【问题描述】:

我已经标记了这个问题PHP,但它更多的是关于设计模式的问题,即工厂模式; PHP 只是我正在使用的编程语言。

我正在建立一个房地产经纪人(美国表亲的“房地产”)网站。我有一个Property 类,但还有其他扩展它的类,即LettingPropertyCommercialProperty,它们具有特定于该类型属性的字段。

在我的控制器中,我想显示一个特定的属性。这很容易,因为我将属性 ID 作为参数传递。我的方法是创建一个工厂类,将属性作为相关类的实例返回。例如,如果 ID 为 1 的属性是出租属性,则返回 LettingProperty 的实例。如果它只是一个标准的“待售”属性,Property 的一个实例。

我该怎么办?我创建了一个PropertyFactory 类并实现了一个名为buildFromId() 的方法,但是在创建一个优雅的解决方案时遇到了麻烦:

  • 在我的properties数据库表中查找相关记录
  • 做任何LEFT JOINs(即,如果它是一个让属性左连接来自letting_properties的相关数据(外键:property_id
  • 返回结果数据,作为相应类的实例

工厂方法是这种场景的正确设计模式吗?如果是这样,我该怎么做?

【问题讨论】:

  • 看起来你的数据库问题比工厂模式多。那么你的数据库设计怎么样?为什么您在使用左连接时遇到问题?
  • @redreggae 他在发出查询时不知道要加入哪个表,因为 Property 可以是没有连接的 Raw Property,可以是连接到一个表的 LettingProperty,也可以是 CommercialProperty将加入不同的表。
  • @martinBean 根据property_type字段中包含的值发出两个查询可能更简单,一个用于属性,另一个用于属性子类型......以帮助性能缓存结果可能是适当的行动。
  • @martinbean 让工厂返回一个装饰(即装饰器模式)属性可能是一个很好的解决方案。
  • @Orangepill 没错。我不知道仅根据 ID 加入哪个表(如果有)。如果可能的话,我宁愿坚持一个数据库查询。我可以LEFT JOIN 表(如果连接表中不存在数据,它们将返回 null),但我想要一个干净的方法将此原始数据库结果转换为相关的模型类。

标签: php design-patterns factory factory-pattern


【解决方案1】:

如果您已经可以生成一个使用左连接可变地展平树的查询,那么您可以在 php 端执行类似的操作来创建您的对象模型。当然,您会希望在属性类型上填写更多的实现,以使它们真正有用。

 class Property {
    public function setPropertyValuesFromArray($array){
        foreach($array as $k=>$v){
            $this->$k = $v;
        }
    }
 }

 class CommercialProperty extends Property {}
 class LettingProperty extends Property {}

 class PropertyFactory {
    protected $db;

    public function __construct(DbConnection $db){
        $this->db = $db;
    }
    public function getPropertyById($id){
        $result = $this->db->fetchRow($queryToGetPropertyById);
        return $this->getPropertyFromArray($result);
    }
    public function getPropertyFromArray($result){
        switch($result["property_type"]){
            case "residential":
                $p = new Property();
                break;
            case "commericial":
                $p = new CommercialProperty();
                break;
            case "letting":
                $p = new LettingProperty();
                break;
            default:
                throw new Exception("Unknown Property Type ".$result["property_type"]);
                break;
        }
        $p->setPropertyValueFromArray($result);
        return $p;
    }
 }

【讨论】:

    猜你喜欢
    • 2012-08-31
    • 1970-01-01
    • 1970-01-01
    • 2011-07-23
    • 1970-01-01
    • 1970-01-01
    • 2016-02-01
    • 1970-01-01
    • 2021-12-20
    相关资源
    最近更新 更多