5

我有一个部署到多个客户站点的现有 Perl 应用程序。不幸的是,该代码已被多次克隆,以便为个别客户定制。所以现在有几个完整的代码副本,它们都有细微(或主要)的差异。

我的任务是通过创建一个单一的通用代码库来解决这个混乱,并为不同的客户在他们自己的库中进行定制。

该应用程序已经有一个类层次结构(大约有 120 个类),如下所示:

Control.pm
  \__ BaseJob.pm
           \___Job1.pm
           |
           |__ Job2.pm
           |
           |__ Job3.pm

我的目标是能够通过仅修改特定客户的库来自定义特定的类或方法。

我的第一直觉是为需要为特定客户定制的任何东西创建子类。这些子类将存在于客户特定的 lib 目录中(每个客户一个)。然后,要为客户定制一个类或方法,我只需将一个新的子类添加到客户库中。

例如,如果Job2.pm需要自定义一个方法,我可能会创建一个子类,该子类CustomJob2继承自Job2并仅包含要自定义的方法。

然后在主程序中,这个:

Job2->some_method();

变成:

CustomJob2->some_method();

问题是这会破坏所有其他客户的代码,因为他们的库中没有CustomJob2该类。看来我必须CustomJob2为每个客户在库中添加一个空类。

有没有更好的办法?

我考虑过的另一种可能性是使用覆盖而不是子类。主程序只需要use lib包含客户库,任何要定制的方法都将在库中重新定义。然而,这可能是危险的,不被认为是最佳实践。

我寻求 StackOverflow 大师的智慧来寻找解决这个问题的最佳方法。

4

2 回答 2

4

我强烈建议您将尽可能多的自定义设置到配置中,而不是代码中。

在配置对象中查找值的代码比实例化子类要简单得多。

您还可以通过将类名放在配置文件中并根据这些名称实例化类来混合两者。这也让您可以更轻松地在两个或更多客户之间共享自定义设置。

于 2009-04-06T14:34:12.507 回答
4

你对方向的大部分想法都是可靠的。当您调用Job2->some_method()而不是$job->some_method()时,问题就出现了。也就是说,您的类方法调用只是一个问题,因为它们首先是一个坏主意——您看到这是因为它们干扰了您利用 OOP。

在您的情况下,我会做的是编写我的代码,以便我使用对象方法调用而不是类方法调用,并为每个项目安装一个配置散列,该散列可用于告诉它它想为给定目的使用哪个类。所以它看起来像:

my $job2_class = $project->conf->{job2_class} || 'Job2';
my $job2 = new $job2_class;
$job2->some_method();
于 2009-04-06T06:31:30.360 回答