【问题标题】: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.

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

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

【问题讨论】:

    标签: java perl oop design-patterns 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";
        }
        

        【讨论】:

          猜你喜欢
          • 2021-08-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多