管理和加载属性的最佳实践

Posted

技术标签:

【中文标题】管理和加载属性的最佳实践【英文标题】:best practices to managing and loading properties 【发布时间】:2011-10-27 20:15:20 【问题描述】:

我期待了解一些管理属性文件的最佳方法。

我们有一组设备(比如 N 个)。这些设备中的每一个都具有某些属性。 例如 设备 A 具有属性

A.a11=值a11

A.a12=值a12

.

设备 B 具有属性

B.b11=值b11

B.b12=值b12 .

除此之外,它们还有一些适用于所有设备的通用属性。

X.x11=值x11

X.x12=值x12

我正在编写一个自动化程序,用于在这些设备上运行一些测试套件。一次,在单个设备上运行测试脚本。设备名称将作为参数传递。根据设备名称,代码将获取相应的属性和公共属性,并使用这些属性更新设备。例如对于设备 A,代码将获取 A.a11、A.a12(设备 A 特定)和 X.x11、X.x12(通用)属性,并在运行测试脚本之前将其上传到设备。

因此,在代码中,我需要管理这些属性,以便仅将设备特定和通用属性上传到设备,而忽略其余属性。我是这样管理的

if ($device eq 'A') then
    upload A's properties
elsif ($device eq 'B') then
    upload B's properties
endif

upload Common (X) properties.

随着设备数量的不断增加,以这种方式管理设备变得有点困难。

所以我期待其他一些管理这些属性的最佳方法。

【问题讨论】:

【参考方案1】:

这是一个很好的例子,v(广义 OOP 文献中的特征)将很有用。

与经典的对象是一个类不同,具有角色的对象 *执行 * 角色。

查看相应的 Moose 文档以获取更多信息。

例子:

package Device::ActLikeA;
use Moose::Role;

has 'attribute' => (
    isa => string,
    is  => 'rw',
    default => 'Apple',
);

sub an_a_like_method 
    my $self = shift;

    # foo


1;

所以现在我有了一个名为Device::ActLikeA 的角色,我该怎么处理它?

嗯,我可以将角色应用到一个类中,ActLikeA 中定义的代码和属性将在该类中可用:

package Device::USBButterChurn;
use Moose;

does 'Device::ActLikeA';

# now has an attribute 'attribute' and a method 'an_a_like_method'
1;

您还可以将角色应用于类的各个实例。

package Device;
use Moose;

has 'part_no' => (
  isa => 'Str',
  is  => 'ro',
  required => 1,
);

has 'serial' => 
  isa  => 'Str',
  is   => 'ro',
  lazy => 1,
  build => '_build_serial',
);

1;

然后是查看该部分并应用适当角色的主要代码:

my @PART_MATCH = (
    [ qr/Foo/,              'Device::MetaSyntacticVariable' ],
    [ qr/^...-[^_]*[A][^-], 'Device::ActLikeA; ],
    [ qr/^...-[^_]*[B][^-], 'Device::ActLikeB; ],
# etc
);

my $parts = load_parts($config_file);

for my $part ( @$parts ) 

    my $part_no = $part->part_number();

    for my $_ (@PART_MATCH) 
        my ($match, $role) = @$_;
        $part->apply_role($role)
           if $part_no =~ /$match/;
    


【讨论】:

【参考方案2】:

这是一个非常直接的方法。

首先,您需要一种方法来表明 A “is-a” X 和 B “is-a” X,即 X 是 A 和 B 的父项。

那么您的upload_device 例程将如下所示:

sub upload_properties 
  my $device = shift;
  ... upload the "specific" properties of $device ...
  for my $parent (parent's of $device) 
    upload_properties($parent);
  

一个实现:

用配置文件中的一行表示“is-a”关系,例如:

A.isa = X

(随意使用其他语法 - 您使用什么将取决于您要如何解析文件。)

从配置文件中,创建所有设备的哈希,如下所示:

$all_devices = 
  A =>  a11 => valuea11, a12 => valuea12, isa => [ 'X' ],
  B =>  b11 => valueb11, b12 => valueb12, isa => [ 'X' ] ,
  X =>  x11 => valuex11, x12 => valuex12, isa => [] ,

upload_properties 例程:

sub upload_properties 
  my ($device) = @_;
  for my $key (keys %$device) 
    next if $key eq "isa";
    ... upload property $key => $device->$key ...
  
  my $isa = $device->isa;  # this should be an array ref
  for my $parent_name (@$isa) 
  my $parent = $all_devices->$parent_name;
    upload_properties($parent);
  


# e.g. to upload device 'A':

upload_properties( $all_devices->'A' );

【讨论】:

【参考方案3】:

您可以通过将设备属性存储在哈希中来消除大型 if-else 链。 那么您只需要确保特定的 $device 出现在该哈希中。

#!/usr/bin/perl
use warnings;
use strict;

my %vals = (
    A => 
        a11 => 'valuea11',
        a12 => 'valuea12',
    ,
    B => 
        b11 => 'valueb11',
        b12 => 'valueb12',
    ,
);

foreach my $device qw(A B C) 
    if (exists $vals$device) 
        upload_properties($vals$device);
    
    else 
        warn "'$device' is not a valid device\n";
    


sub upload_properties 
    my($h) = @_;
    print "setting $_=$h->$_\n" for sort keys %$h; # simulate upload
    print "\n";

【讨论】:

以上是关于管理和加载属性的最佳实践的主要内容,如果未能解决你的问题,请参考以下文章

ios/iphone sdk 表单管理最佳实践

在查询组件之外显示 Apollo 客户端查询加载的最佳实践?

vue项目的一些最佳实践提炼和经验总结

无限滚动加载最佳实践

属性和实例变量的最佳实践

Mybatis-应用分析和最佳实践-核心配置