【问题标题】:Use of instance variables vs passing data as a parameter使用实例变量与将数据作为参数传递
【发布时间】:2015-03-28 19:11:09
【问题描述】:

使用实例变量而不是将数据作为参数传递时有什么缺点。

使用实例变量对我来说似乎更具可读性,但是将它们提供给整个班级是否有缺点。我想这是从全局变量与局部变量的角度来看的。

使用实例变量

public class ChoicesFragment extends Fragment implements View.OnClickListener {
    private CharSequence[] mButtonTextData;
    private String mTitleTextData;  
    
    private View mUserChoiceView;
    
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        mUserChoiceView = inflater.inflate(R.layout.available_choices, container, false);

        getBundleData();

        setTitle();
        setButtons();        

        return  mUserChoiceView;
    }
    
    private void getBundleData() {
        //populate button text
        Bundle bundleData = getArguments();
        mTitleTextData = bundleData.getString(CardFragment.TITLE_TEXT_KEY);
        mButtonTextData = bundleData.getCharSequenceArray(CardFragment.BUTTON_TEXT_KEY);        
    }
    
    private void setTitle() {
        TextView title = (TextView) mUserChoiceView.findViewById(R.id.choicesTextView1);
        String genericTitle = getResources().getString(R.string.title_selection);
        title.setText(genericTitle + mTitleTextData);
    }

    //sets up button data
    public void setButtons() {
        TextView[] buttonsTextView = new TextView[4];
        buttonsTextView[0] = (TextView) mUserChoiceView.findViewById(R.id.choicesTextView2);
        buttonsTextView[1] = (TextView) mUserChoiceView.findViewById(R.id.choicesTextView3);
        buttonsTextView[2] = (TextView) mUserChoiceView.findViewById(R.id.choicesTextView4);
        buttonsTextView[3] = (TextView) mUserChoiceView.findViewById(R.id.choicesTextView5);

        for(int i = 0; i < buttons.length; i++) {
            buttonsTextView[i].setText(mButtonTextData[i]);
        }
    }   
}

第二个例子将数据作为参数传递

public class ChoicesFragment extends Fragment implements View.OnClickListener { 
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {                            
        View userChoiceView;
                             
        String titleTextData;
        CharSequence[] buttonTextData;
        
        mUserChoiceView = inflater.inflate(R.layout.available_choices, container, false);

        Bundle bundleData = getArguments();
        buttonTextData = bundleData.getString(CardFragment.TITLE_TEXT_KEY);
        titleTextData = bundleData.getCharSequenceArray(CardFragment.BUTTON_TEXT_KEY);

        setTitle(userChoiceView, titleTextData);
        setButtons(userChoiceView, buttonTextData);        

        return  mUserChoiceView;
    }
    
    private void setTitle(View userChoiceView, String titleText) {
        TextView title = (TextView) userChoiceView.findViewById(R.id.choicesTextView1);
        String genericTitle = getResources().getString(R.string.title_selection);
        title.setText(genericTitle + titleText);
    }

    //sets up button data
    public void setButtons(View userChoiceView, CharSequence[] buttonText) {
        TextView[] buttonsTextView = new TextView[4];
        buttonsTextView[0] = (TextView) userChoiceView.findViewById(R.id.choicesTextView2);
        buttonsTextView[1] = (TextView) userChoiceView.findViewById(R.id.choicesTextView3);
        buttonsTextView[2] = (TextView) userChoiceView.findViewById(R.id.choicesTextView4);
        buttonsTextView[3] = (TextView) userChoiceView.findViewById(R.id.choicesTextView5);

        for(int i = 0; i < buttons.length; i++) {
            buttonsTextView[i].setText(buttonText[i]);
        }
    }   
}

【问题讨论】:

  • 他们自己的类方法中传递实例变量是没有意义的,而且过度工程化IMO。
  • 你是对的,但在这个例子中没有这样做。问题是关于实例变量 vs 参数。这也是示例的内容。

标签: java android performance coding-style


【解决方案1】:

使用参数可以使方法自包含。您永远不必怀疑实例变量的值是多少,因为您将数据作为参数传递。

除了封装的非常有用的好处之外,参数化方法比依赖于实例变量值的方法更容易进行单元测试。

【讨论】:

  • 嗯,单元测试不应该是决定是否参数化的原因。您始终可以拥有适当的构造函数、设置器或通过其他方式注入数据,以便正确初始化这些实例变量。有很多方法可以做到这一点......而且没有真正的“一种正确的方法(tm)”:)
  • 这些实例变量和方法是同一类的成员。为什么要传递它们???封装是通过字段访问修饰符和使用公共方法来访问隐藏字段而不是通过将字段传递给它们自己的类方法来实现的。
  • @I.K.问题是实例与参数。这就是问题和答案的意义所在。在同一个实例中将实例成员作为参数传递是荒谬的。
  • @Mjoellnir 如果您只为单元测试创​​建构造函数和设置器,那么使用跨类使用并在逻辑上属于该类的变量用作方法参数,这不是一样糟糕吗?
  • @obesechicken13 如果这些构造函数/设置器仅用于单元测试,是的。这同样不受欢迎。如果我遇到在测试期间必须访问/初始化/验证某些东西的情况,我通常会在单元测试中使用反射,否则在生产使用中不能直接从外部或子类访问。
猜你喜欢
  • 2013-06-23
  • 1970-01-01
  • 2011-11-18
  • 2011-03-29
  • 1970-01-01
  • 1970-01-01
  • 2018-01-23
  • 2010-09-25
相关资源
最近更新 更多