You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP开发房产广告平台:适配多类型房源与交易的设计模式选型

房产广告交易平台设计模式选型建议

核心问题拆解

你面临的是两个独立变化维度的扩展问题:

  • 房源维度:House/Flat/Garage等,各自有专属字段与行为
  • 交易维度:Buy/BuyNew/Rent/VacationRent/Colocation等,同样有独立的字段与逻辑

直接用继承会导致类爆炸(比如HouseRent/HouseVacationRent...),嵌套判断又会让代码难以维护,所以**桥接模式(Bridge)+ 工厂方法(Factory Method)**是最优组合。

模式选型理由

桥接模式

专门解决多维度独立扩展的耦合问题:

  • 将房源(抽象层)和交易类型(实现层)分离,各自独立演进
  • 每个房源类只需关联一个交易类型接口,无需关心具体交易逻辑
  • 新增房源或交易类型时,只需新增对应类,无需修改现有代码

工厂方法

用来封装具体广告对象的创建逻辑,避免业务代码中出现大量new语句:

  • 可以按房源+交易类型的组合,创建对应的广告实例
  • 后续扩展新组合时,只需修改工厂类(或新增工厂子类)

PHP代码示例

1. 定义交易类型接口与实现

// 交易类型接口
interface TransactionInterface {
    public function getDetails(): array;
    // 其他通用交易方法
}

// 购买交易
class Buy implements TransactionInterface {
    private $price;

    public function __construct(float $price) {
        $this->price = $price;
    }

    public function getDetails(): array {
        return ['type' => 'buy', 'price' => $this->price];
    }
}

// 租赁交易
class Rent implements TransactionInterface {
    private $monthlyRent;
    private $deposit;
    private $leaseTerm;

    public function __construct(float $monthlyRent, float $deposit, int $leaseTerm) {
        $this->monthlyRent = $monthlyRent;
        $this->deposit = $deposit;
        $this->leaseTerm = $leaseTerm;
    }

    public function getDetails(): array {
        return [
            'type' => 'rent',
            'monthly_rent' => $this->monthlyRent,
            'deposit' => $this->deposit,
            'lease_term' => $this->leaseTerm
        ];
    }
}

// 度假租赁(继承Rent扩展)
class VacationRent extends Rent {
    private $minStayDays;
    private $peakSeasonSurcharge;

    public function __construct(
        float $monthlyRent,
        float $deposit,
        int $leaseTerm,
        int $minStayDays,
        float $peakSeasonSurcharge
    ) {
        parent::__construct($monthlyRent, $deposit, $leaseTerm);
        $this->minStayDays = $minStayDays;
        $this->peakSeasonSurcharge = $peakSeasonSurcharge;
    }

    public function getDetails(): array {
        $baseDetails = parent::getDetails();
        $baseDetails['type'] = 'vacation_rent';
        $baseDetails['min_stay_days'] = $this->minStayDays;
        $baseDetails['peak_season_surcharge'] = $this->peakSeasonSurcharge;
        return $baseDetails;
    }
}

2. 定义房源抽象类与子类

// 房源抽象类(桥接的抽象层)
abstract class Property {
    protected $transaction;
    protected $basicInfo;

    public function __construct(TransactionInterface $transaction, array $basicInfo) {
        $this->transaction = $transaction;
        $this->basicInfo = $basicInfo;
    }

    // 获取完整广告信息
    public function getAdDetails(): array {
        return array_merge(
            $this->getPropertySpecificInfo(),
            $this->transaction->getDetails()
        );
    }

    // 子类实现专属房源信息
    abstract protected function getPropertySpecificInfo(): array;
}

// 住宅房源
class House extends Property {
    private $numberOfBedrooms;
    private $hasGarden;

    public function __construct(
        TransactionInterface $transaction,
        array $basicInfo,
        int $numberOfBedrooms,
        bool $hasGarden
    ) {
        parent::__construct($transaction, $basicInfo);
        $this->numberOfBedrooms = $numberOfBedrooms;
        $this->hasGarden = $hasGarden;
    }

    protected function getPropertySpecificInfo(): array {
        return array_merge(
            $this->basicInfo,
            [
                'property_type' => 'house',
                'bedrooms' => $this->numberOfBedrooms,
                'has_garden' => $this->hasGarden
            ]
        );
    }
}

// 公寓房源
class Flat extends Property {
    private $floorNumber;
    private $hasElevator;

    public function __construct(
        TransactionInterface $transaction,
        array $basicInfo,
        int $floorNumber,
        bool $hasElevator
    ) {
        parent::__construct($transaction, $basicInfo);
        $this->floorNumber = $floorNumber;
        $this->hasElevator = $hasElevator;
    }

    protected function getPropertySpecificInfo(): array {
        return array_merge(
            $this->basicInfo,
            [
                'property_type' => 'flat',
                'floor_number' => $this->floorNumber,
                'has_elevator' => $this->hasElevator
            ]
        );
    }
}

3. 工厂类创建广告实例

class PropertyAdFactory {
    public static function createAd(
        string $propertyType,
        string $transactionType,
        array $propertyParams,
        array $transactionParams
    ): Property {
        // 创建交易实例
        $transaction = self::createTransaction($transactionType, $transactionParams);
        // 创建房源实例
        return match($propertyType) {
            'house' => new House($transaction, ...$propertyParams),
            'flat' => new Flat($transaction, ...$propertyParams),
            // 新增房源类型时只需加case
            default => throw new InvalidArgumentException("Unknown property type: $propertyType")
        };
    }

    private static function createTransaction(string $type, array $params): TransactionInterface {
        return match($type) {
            'buy' => new Buy(...$params),
            'rent' => new Rent(...$params),
            'vacation_rent' => new VacationRent(...$params),
            // 新增交易类型时只需加case
            default => throw new InvalidArgumentException("Unknown transaction type: $type")
        };
    }
}

4. 业务代码调用示例

// 创建一个度假租赁的别墅广告
$vacationHouseAd = PropertyAdFactory::createAd(
    'house',
    'vacation_rent',
    [['address' => '123 Beach Rd'], 4, true],
    [1500.0, 3000.0, 6, 7, 0.2]
);

// 输出完整广告信息
print_r($vacationHouseAd->getAdDetails());

其他模式排除说明

  • 策略模式:更适合单一维度的算法替换,无法解决多维度扩展的类爆炸问题
  • 状态模式:用于对象状态转换场景,你的交易类型是固定的业务类型,不是状态变化
  • 单纯工厂方法:只能解决对象创建问题,无法解耦房源与交易的耦合关系

内容的提问来源于stack exchange,提问作者Adel taf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 04:42:51