技术设计决策咨询:支持标识应存于DTO还是专用服务?
多租户平台国家/货币支持标记方案决策讨论
背景
我们有一个多租户平台,每个租户关联一个国家,系统支持多个国家和货币。现有数据对象如下:
readonly class CountryInfoDto { public function __construct( public string $displayName, public TimezonesEnum $timeZone, public CurrenciesEnum $currency, public CountryCodesEnum $countryCode, public Bcp47Enum $bcp47, public array $taxRates = [], public array $guestLocales = [], ) {} }
该对象存储国家固有信息(货币、时区、BCP47、税率等),由PHP Enum(如EuropeCountryEnum::SWEDEN->info())生成。
同时存在两个业务服务:
- SupportedCountryService:负责回答“哪些国家可创建新店铺?”
- SupportedCurrencyService:负责回答“货币切换器中展示哪些货币?”
这些属于产品特定的业务策略问题,国家/货币是否支持取决于运营决策,而非国家本身的固有属性。
两种方案对比
方案A:在DTO中添加支持标识(当前采用方案)
在CountryInfoDto的构造函数中新增布尔标识字段:
public function __construct( // ...原有国家固有字段... public bool $supportedCountry, public bool $supportedCurrency, ) {}
服务通过遍历所有Enum实例,依据这些标识筛选出支持的国家/货币。
优点:新增国家时仅需在一处编辑,所有信息集中管理。
方案B:在服务中维护支持列表
保持CountryInfoDto为纯“国家固有信息”对象,由服务单独维护支持列表:
class SupportedCountryService { private static function supported(): array { return [EuropeCountryEnum::SWEDEN, EuropeCountryEnum::NORWAY, /* ...*/]; } }
服务明确管控自身业务策略。
优点:分离“国家固有属性”与“业务策略”,避免策略信息意外泄露到JSON响应中,新增Enum实例不会自动开启对应国家的支持。
双方倾向
- 我支持方案B:SupportedCountryService的职责就是处理这类业务策略问题,把业务逻辑嵌入
CountryInfoDto会混淆关注点——一个国家本身的属性和我们是否支持它是完全独立的两件事。 - 同事支持方案A:认为集中管理更务实,新增国家时只需调用一次构造函数完成配置。
内容的提问来源于stack exchange,提问作者nahoj
相关产品推荐
相关产品推荐

