我是Perl-OO初学者,我遇到了设计挑战。我希望你能给我一些提示,以获得一个优雅的解决方案。我在这里使用鼠标对象系统。
对于一个最小的例子,我想说我有一个用户对象。用户有一个名字。
package User;
use Mouse;
has "name" => (
is => "rw",
isa => "Str|Undef",
);
然后我有一个User-Cache-Object,它获取所有用户的列表(来自LDAP服务器)。您可以说这是用户缓存和用户之间的“有一个”关系。
package UserCache;
use Mouse;
has "users" => (
is => 'rw',
isa => 'ArrayRef|Undef',
default => sub { [] },
);
我将此用户列表存储为用户缓存的访问者中的用户对象数组。
my $cache = UserCache->new();
foreach my $entry ( $ldap->searchGetEntries() ) {
my $user = User->new();
$user->name($entry->get_value('userdn'));
push @{ $cache->users }, $user;
}
现在这就是我的问题所在。如果我想找到具有特定属性的用户对象(例如名为John的用户),我必须遍历整个用户对象数组并查询每个对象名称。当给出一个名单列表时,这会得到一个非常低效的过程。
foreach my $user ( @{ $cache->users } ) {
if ( $user->name eq 'John' ) {
#do something with John
}...
}
有没有办法以某种方式存储对象列表在其他对象中,我可以有效地搜索?喜欢 $ cache-> get_users-> get_name('John')并返回我需要的对象?
答案 0 :(得分:5)
你真的不必自己写UserCache
课程。而是使用CHI缓存要在要用于查找的密钥下缓存的用户。如果需要,可以将缓存类包装为从特定缓存实现中抽象出来。
另外,你有这个:
push @{ $cache->users }, $user;
泄漏实施细节的地方。相反,您的UserCache
对象需要类似save_user
方法的内容,因此它使用的代码不依赖于实现细节。
$cache->save_user( $user );
对于Moose物体,你得到Moose::Meta::Attribute::Native::Trait::Array;对于鼠标,您获得MouseX::NativeTraits::ArrayRef。
答案 1 :(得分:4)
否即可。至少不是普遍的。您当然可以为常见事物构建索引。或者你可以在完成搜索后缓存搜索。
查找最好实现为哈希。这些可以附加到UserCache对象。类似的东西:
my @users = $cache->find( name => 'John' );
这将在内部映射到带有搜索字段的hashref。
package UserCache;
#...
has _search_index => (
is => 'ro',
isa => 'HashRef',
default => sub { {} },
);
哈希引用看起来像这样:
{
name => {
John => [
User->new( name => 'John', last_name => 'Smith' ),
User->new( name => 'John', last_name => 'Wayne' ),
User->new( name => 'John', last_name => 'Bon Jovi' ),
],
James => [ ... ],
},
id => {
# ...
},
),
但同样,你必须建立那些。所以你需要进行一次查找。但我认为查找应该在UserCache中完成并存储在那里。
sub find {
my ($self, $key, $value) = @_;
# get operation
return @{ $self->_search_index->{$key}->{$value} }
if exists $self->_search_index->{$key}->{$value};
# set operation
foreach my $user ( @{ $self->users } ) {
push @{ $self->_search_index->{$key}->{$value} }, $user
if $user->$key eq $value
}
return @{ $self->_search_index->{$key}->{$value} }
}
这是一个非常天真的实现,它不支持多次查找,但它是一个开始。
请注意,如果您拥有大量用户和大量索引,则数据结构可能会变大。
为方便起见,Moose's built-in traits可能会有所帮助。如果您想要更强的缓存行为,请查看CHI。