new 构建构建器。您想要一些其他方法来实际返回构建的对象。
这是一个例子:
class RepositoryBuilder {
has 'allow_network_repositories' => (
is => 'ro',
isa => 'Bool',
required => 1,
);
method build_repository(Uri $url) {
confess 'network access is not allowed'
if $url->is_network_url && !$self->allow_network_repositories;
my $class = $self->determine_class_for($url); # Repository::Whatever
return $class->new( url => $url );
}
}
role Repository { <whatever }
class Repository::File with Repository {}
class Repository::HTTP with Repository {}
在这里,建造者和建造的对象是不同的。建设者是一个
实物,完整的参数,可以定制构建
根据情况需要的对象。然后,“构建”的对象是
仅返回方法的值。这允许您构建其他
建设者视情况而定。 (建设者的问题
功能是它们非常不灵活——很难教它们
一个新的特例。构建器对象仍然存在此问题,
但至少你的应用程序可以创建一个子类,实例化它,
并将这个对象传递给任何需要创建对象的东西。但
在这种情况下,依赖注入是一种更好的方法。)
此外,您构建的存储库无需继承自
任何东西,它们只需要一个标签来表明它们是存储库。
这就是我们的Repository 角色所做的。 (您将要添加
这里的 API 代码,以及应该重用的任何方法。但小心点
关于强制重用——你确定所有标记为
存储库角色会想要那个代码吗?如果没有,只需将代码放入
另一个角色并将其应用于需要该角色的类
功能。)
以下是我们如何使用我们创建的构建器。如果,说,你不想
触摸网络:
my $b = RepositoryBuilder->new( allow_network_repositories => 0 );
$b->build_repository( 'http://google.com/' ); # error
$b->build_repository( 'file:///home/whatever' ); # returns a Repository::Foo
但如果你这样做:
my $b = RepositoryBuilder->new( allow_network_repositories => 1 );
$b->build_repository( 'http://google.com/' ); # Repository::HTTP
现在您有了一个可以按照您喜欢的方式构建对象的构建器,
您只需要在其他代码中使用这些对象。所以最后一块
在拼图中是指“任何”类型的 Repository 对象在其他
代码。很简单,你用does代替isa:
class SomethingThatHasARepository {
has 'repository' => (
is => 'ro',
does => 'Repository',
required => 1,
);
}
你已经完成了。