Ruby类,参数是围绕方法传递的,实例变量?

时间:2017-12-03 19:50:35

标签: ruby oop

我遇到这个问题,我认为它可能是代码味道,我有一个类在其初始化器中接收一个参数,并包含一个公共和几个私有方法 - 一切正常。例如:

class Foo
  def initialize(a)
    @a = a
  end

  def apply?(examples)
    foo_1(examples)
  end

  private

  def foo_1(examples)
    foo_2(examples) ? 1 : 2
  end

  def foo_2(examples)
    examples.size > @a
  end
end

我的问题在于,'示例'公共方法通过私人方法一遍又一遍地接收,它看起来不漂亮,看起来像代码味道,这里最好的方法是什么?将它作为公共方法中的实例变量吗?

由于

4 个答案:

答案 0 :(得分:2)

是的,如果接受examples的私有方法的数量大于1-2,则可能会被视为代码气味。

要考虑的一件事是在这里提取一个代表rule的类。

例如:

class Foo
  def initialize(a)
    @a = a
  end

  def apply?(examples)
    size_rule_applies?(examples) ? 1 : 2
  end

  private

  def size_rule_applies?(examples)
    SizeRule.new(@a, examples).apply?
  end

  class SizeRule
    def initialize(a, examples)
      @a        = a
      @examples = examples
    end

    def apply?
      @examples.size > @a
    end
  end
end

我不会让examples成为Foo类的实例变量,因为在对该对象的调用之间存在内存的风险。我见过这样的错误。

答案 1 :(得分:0)

如果examples动态变化,那么使其成为实例变量不是一种选择。您需要为每个Foo实例化examples,否则您最终会变Foo examples本身正在发生变化,这也不是好。

您的代码看起来很好。我唯一关心的是一种方法取决于另一种方法。这通常不是什么大问题,但这对我来说会更好看:

  def apply?(examples)
    foo_1(examples) && foo_2(examples)
  end

答案 2 :(得分:0)

另一个选择是使用块:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.myproject</groupId>
    <artifactId>mydata</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>mydata</name>
    <url>http://maven.apache.orgurl>


    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
         <gmaven.version>1.5</gmaven.version>
    <groovy.version>2.1.8</groovy.version>
    </properties>

<dependencies>


        <dependency>
            <groupId>org.codehaus.groovy</groupId>
            <artifactId>groovy-all</artifactId>
            <version>2.4.11</version>
        </dependency>

</dependencies>
<build>
<!-- <pluginManagement> -->
<plugins>
   <plugin>
            <groupId>org.codehaus.gmaven</groupId>
            <artifactId>gmaven-plugin</artifactId>
            <version>${gmaven.version}</version>
            <configuration>
                <providerSelection>2.0</providerSelection>
            </configuration>
            <dependencies>

                <dependency>
                    <groupId>org.codehaus.gmaven.runtime</groupId>
                    <artifactId>gmaven-runtime-2.0</artifactId>
                    <version>${gmaven.version}</version>
                </dependency>
                <dependency>
                    <groupId>org.codehaus.groovy</groupId>
                    <artifactId>groovy-all</artifactId>
                    <version>${groovy.version}</version>
                </dependency>
            </dependencies>
           <!--  <executions>
                <execution>
                    <goals>
                        <goal>generateStubs</goal>
                        <goal>compile</goal>
                        <goal>generateTestStubs</goal>
                        <goal>testCompile</goal>
                    </goals>
                </execution>
            </executions> -->
        </plugin>
        </plugins>
<!--         </pluginManagement> -->
        </build>


</project>

答案 3 :(得分:0)

由于类Foo目前没有做任何其他事情而不仅仅评估.apply?(examples)我会建议将示例添加到初始化程序并创建一个实例变量。这更简单,更有效,更明显。

class Foo
  def initialize(a, examples)
   @a = a
   @examples = examples
  end

  def apply?
    foo_1
  end

  private

  def foo_1
    foo_2 ? 1 : 2
  end

  def foo_2
    @examples.size > @a
  end
end