Rumah > Artikel > pangkalan data > 实战技巧:用Enum(枚举类型)取代整数集
在Android的API中可以发现有很多用整数集来作为参数的地方,先来看一下实例。 LinearLayout是大家所熟知的一个UI基本元素,它里面有一个方向的属性,可以通过以下方法来设置: LinearLayout.setOrientation(int); 使用的时候,通常都是这样: LinearLayout.s
在Android的API中可以发现有很多用整数集来作为参数的地方,先来看一下实例。LinearLayout.setOrientation(int);使用的时候,通常都是这样:
LinearLayout.setOrientation(LinearLayout.HORIZONTAL); LinearLayout.setOrientation(LinearLayout.VERTICAL);但也可以这样使用:
LinearLayout.setOrientation(0); // LinearLayout.HORIZONTAL = 0 LinearLayout.setOrientation(1); // LinearLayout.VERTICAL = 0x01甚至可以这样:
LinearLayout.setOrientation(Integer.MAX_VALUE); LinearLayout.setOrientation(Integer.MIN_VALUE); LinearLayout.setOrientation(2012);因为方法setOrientation接收的参数是一个整数,所以你可以传任意合法的整数---至少这在编译时不会有任何问题。它只会在运行时可能引发问题,但如你所知,开发者只关注程序能否编译成功,至于运行时,那是用户关心的事儿,因为开发者不一定使用他们所开发出的程序。
LinearLayout.setOrientation(0); LinearLayout.setOrientation(1);这完全没有错,但是代码的阅读者和维护者通常都会蛋疼的。
<linearlayout android:orientation="vertical" android:gravity="center"></linearlayout>
因为XML布局会在编译时被处理,如果有非法的值,会有编译错误的。我想这也就是Android特别鼓励开发者用XML来制作所有的布局的一个原因吧。
实例,三个没有设置指向的线性布局,默认是水平放置,在代码中设置了几个离谱的值,发现它们还是水平的,也就是说设置离谱的值不会出错,但也不起作用:
运行结果如下:
代码如下:
<?xml version="1.0" encoding="utf-8"?> <linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center"> <linearlayout android:id="@+id/linearlayout_test_1" android:layout_width="fill_parent" android:layout_height="wrap_content"> <textview android:layout_width="wrap_content" android:layout_height="wrap_content" android:textcolor="#ff00ff00" android:background="#aa331155" android:layout_weight="1" android:textsize="18sp" android:text="Microsoft"></textview> <textview android:layout_width="wrap_content" android:layout_height="wrap_content" android:textcolor="#ffff0000" android:background="#aa117711" android:layout_weight="1" android:textsize="18sp" android:text="Apple"></textview> <textview android:layout_width="wrap_content" android:layout_height="wrap_content" android:textcolor="#ff0000ff" android:background="#aa774411" android:layout_weight="1" android:textsize="18sp" android:text="Google"></textview> </linearlayout> <linearlayout android:id="@+id/linearlayout_test_2" android:layout_width="fill_parent" android:layout_height="wrap_content"> <textview android:layout_width="wrap_content" android:layout_height="wrap_content" android:textcolor="#ff00ff00" android:background="#aa331155" android:layout_weight="1" android:textsize="18sp" android:text="Microsoft"></textview> <textview android:layout_width="wrap_content" android:layout_height="wrap_content" android:textcolor="#ffff0000" android:background="#aa117711" android:layout_weight="1" android:textsize="18sp" android:text="Apple"></textview> <textview android:layout_width="wrap_content" android:layout_height="wrap_content" android:textcolor="#ff0000ff" android:background="#aa774411" android:layout_weight="1" android:textsize="18sp" android:text="Google"></textview> </linearlayout> <linearlayout android:id="@+id/linearlayout_test_3" android:layout_width="fill_parent" android:layout_height="wrap_content"> <textview android:layout_width="wrap_content" android:layout_height="wrap_content" android:textcolor="#ff00ff00" android:background="#aa331155" android:layout_weight="1" android:textsize="18sp" android:text="Microsoft"></textview> <textview android:layout_width="wrap_content" android:layout_height="wrap_content" android:textcolor="#ffff0000" android:background="#aa117711" android:layout_weight="1" android:textsize="18sp" android:text="Apple"></textview> <textview android:layout_width="wrap_content" android:layout_height="wrap_content" android:textcolor="#ff0000ff" android:background="#aa774411" android:layout_weight="1" android:textsize="18sp" android:text="Google"></textview> </linearlayout> </linearlayout>和:
package com.android.explorer; import android.app.Activity; import android.os.Bundle; import android.widget.LinearLayout; public class LinearLayoutTest extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.linearlayout_test); LinearLayout one = (LinearLayout) findViewById(R.id.linearlayout_test_1); one.setOrientation(2012); LinearLayout two = (LinearLayout) findViewById(R.id.linearlayout_test_2); two.setOrientation(Integer.MAX_VALUE); LinearLayout three = (LinearLayout) findViewById(R.id.linearlayout_test_3); three.setOrientation(Integer.MIN_VALUE); } }
public class LinearLayout extends ViewGroup { private Orientation mOrientation; public enum Orientation { HORIZONTAL, VERTICAL }; public void setOrientation(Orientation dir) { mOrientation = dir; } }然后这样使用:
import android.widget.LinearLayout; LinearLayout.setOrientation(Orientation.HORIZONTAL); LinearLayout.setOrientation(Orientation.VERTICAL);那么,开发者就不会用错了,因为首先,它看到setOrientation所需要的参数是一个Orientation的枚举类型,就会自然的传送Orientation中定义的类型;另外,如果传其他的值,比如0或者1,编译器也不会答应的。
Button.setEnabled(true); // enable the button Button.setEnabled(false); // disable the button但对于某些情况,当方法的名字不能体现Boolean参数的作用时,或是多于一个参数时,而方法的主要目的又不能体现Boolean参数的作用时,就很不清楚,比如:
// com/android/mms/data/ContactList.java public String[] getNumbers(boolean);您能猜出来这个boolean变量是决定是否要为彩信对联系人做特殊的处理吗?您在使用这个API的时候能很快知道该传True还是该传False吗?当读到这些语句的时候:
String[] mms = getNumbers(true); String[] sms = getNumbers(false);您能知道True和False的含义与作用吗?至少我看到这样的代码时,如果不去跟踪它的实现,是猜不出来的。
Button.setEnabled(true); // enable the button Button.setEnabled(false); // disable the button可以改成:
Button.enable(); Button.disable();这是简单的情况,对于稍复杂的情况,比如后一个例子,可以添加另外的接口,而不是用重载方法,但内部的实现,可能还是需要重载,但是这就把问题缩小了,起码对使用者来说是隐藏的:
// com/android/mms/data/ContactList.java public String[] getNumbersForSms(); public String[] getNumbersForMms();这样一来,对外来讲就是良好的封装。内部实现可能还是需要一个类似这样的私有方法:
// com/android/mms/data/ContactList.java public String[] getNumbersForSms() { return getNumbers(false); } public String[] getNumbersForMms() { return getNumbers(true); } private String[] getNumbers(boolean) { // implementation }但至少把问题缩小化了,也可以加上注释来说明。就不必导致使用者来猜方法的用法和含义了。