PHP 中的二级构造函数:探索实现多参数构造方法的技术

admin 2024-06-22 71 阅读 0评论

为什么我们需要二次构造函数?

辅助(或称为“多个”)构造函数在新对象的创建过程中发挥着至关重要的作用,它们为这一过程增添了额外的逻辑层次。这些构造函数不仅为代码注入了新的功能性逻辑,还允许我们根据实际需求灵活调整或扩展初始参数的数量,从而确保对象创建的灵活性和可维护性。

遗憾的是,PHP 语言本身并不支持辅助构造函数的概念。相比之下,Kotlin 语言则提供了这一特性。

为了更好地理解,我将向您展示一个简单的示例,说明次级构造函数如何简化您的生活。

假设您需要为您的客户创建一份 KYC 问卷,并且该问卷中必填字段组可能因用户的就业状况而异: 就业:

  • 状态:就业;
  • 收入来源;
  • 年收入范围; 自雇:
  • 状态:自雇;
  • 年收入范围; 退休:
  • 状态:退休;
  • 年收入范围; 失业:
  • 状态:失业;

当然,您可以依赖经典的对象创建方式并在任何所需的状态下实现模型,只需使用一些默认参数跳过不可用的参数:

final class Questionnaire 
{
  public function __construct(
    private QuestionnaireId $questionnaireId,
    private EmploymentStatus $employmentStatus,
    private ?string $incomeSource,
    private ?array $annualIncomeRange,
  ){
  }

  // ... 其他方法 ... //
}

$employed = new Questionnaire(EmploymentStatus::EMPLOYED, 'Company Name', [60000, 80000]);
$selfEmployed = new Questionnaire(EmploymentStatus::SELF_EMPLOYED, null, [50000, 60000]);
$retired = new Questionnaire(EmploymentStatus::RETIRED, null, [20000, 30000]);
$unemployed = new Questionnaire(EmploymentStatus::UNEMPLOYED, null, null);

但这种方法也允许我们打破规则,创造出有收入的失业人员、有公司信息的退休人员和没有收入和公司信息的就业人员。

$unemployed = new Questionnaire(EmploymentStatus::UNEMPLOYED, null, [20000, 30000]);
$retired = new Questionnaire(EmploymentStatus::RETIRED, 'Company name', null);
$employed = new Questionnaire(EmploymentStatus::EMPLOYED, null, null);

是的,当然,您可以在构造函数中创建额外的规则来涵盖所有情况并根据 EmploymentStatus 验证输入,但这会使构造函数因额外的业务逻辑而超载,并在一堆条件和“if”语句下隐藏要求。使用更简单的方法可以避免这种复杂性。

次要构造函数。

最简单的方法是使用私有构造函数和公共静态方法来控制如何创建该对象:

final class Questionnaire 
{
  private function __construct(
    private EmploymentStatus $employmentStatus,
    private ?string $incomeSource,
    private ?array $annualIncomeRange,
  ){
  }

  public static function asEmployed(string $incomeSource, array $annualIncomeRange): self
  {
    return new self(
      EmployementStatus::EMPLOYED,
      $incomeSource,
      $annualIncomeRange
    );
  }

  public static function asSelfEmployed(array $annualIncomeRange): self
  {
    return new self(
      EmployementStatus::SELF_EMPLOYED,
      null,
      $annualIncomeRange
    );
  }

  public static function asRetired(array $annualIncomeRange): self
  {
    return new self(
      EmployementStatus::RETIRED,
      null,
      $annualIncomeRange
    );
  }

  public static function asUnemployed(): self
  {
    return new self(
      EmployementStatus::UNEMPLOYED,
      null,
      null
    );
  }

  // ... 其他方法 ... //
}


$employed = Questionnaire::asEmployed('Company name', [50000, 80000]);
$selfEmployed = Questionnaire::asSelfEmployed([40000, 60000]);
$retired = Questionnaire::asRetired([30000, 50000]);
$unemployed = Questionnaire::asUnemployed();

因此,开发人员不得不遵循既定规则,针对每个业务逻辑案例精心构建具备精确数据集的一致性模型。这种严谨的做法不仅显著降低了出错的可能性,更将问卷相关的其他业务信息巧妙地融入代码之中。如今,您无需在冗长的代码中费力搜寻条件逻辑,只需浏览方法名称及所需参数,即可轻松洞悉业务上下文,极大地提升了代码的可读性和维护性。

发表评论

快捷回复: 表情:
Addoil Applause Badlaugh Bomb Coffee Fabulous Facepalm Feces Frown Heyha Insidious KeepFighting NoProb PigHead Shocked Sinistersmile Slap Social Sweat Tolaugh Watermelon Witty Wow Yeah Yellowdog
提交
评论列表 (有 0 条评论, 71人围观)