多个枚举与一个枚举

时间:2015-05-11 06:56:40

标签: java enums reactive-streams

我正在查看反应流规范的Publisher(AsyncIterablePublisher.java)的示例实现,当我偶然发现了一些我不明白为什么会这样做的事情。

enum Signal {
  Cancel,
  Subscribe,
  Send;
}

说实话,我不是那么高级程序员,而是写这篇文章的人,我确信有理由这样做。但是我也无法解释为什么它会比这更好(这就是我要做的)。

package com.androidhub4you.multilevellistview;

import java.util.ArrayList;

import com.androidhub4you.multilevellistview.Product.SubCategory;
import com.androidhub4you.multilevellistview.Product.SubCategory.ItemList;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
/**
 * 
 * @author manish
 *
 */
public class MainActivity extends Activity {

    private ArrayList<Product>pProductArrayList;
    private ArrayList<SubCategory>pSubItemArrayList;
    private ArrayList<SubCategory>pSubItemArrayList2;
    private LinearLayout mLinearListView;
    boolean isFirstViewClick=false;
    boolean isSecondViewClick=false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mLinearListView = (LinearLayout) findViewById(R.id.linear_listview);

        /**
         * 
         */

        ArrayList<ItemList> mItemListArray=new ArrayList<ItemList>();
        mItemListArray.add(new ItemList("Red", "20"));
        mItemListArray.add(new ItemList("Blue", "50"));
        mItemListArray.add(new ItemList("Red", "20"));
        mItemListArray.add(new ItemList("Blue", "50"));

        ArrayList<ItemList> mItemListArray2=new ArrayList<ItemList>();
        mItemListArray2.add(new ItemList("Pant", "2000"));
        mItemListArray2.add(new ItemList("Shirt", "1000"));
        mItemListArray2.add(new ItemList("Pant", "2000"));
        mItemListArray2.add(new ItemList("Shirt", "1000"));
        mItemListArray2.add(new ItemList("Pant", "2000"));
        mItemListArray2.add(new ItemList("Shirt", "1000"));


        /**
         * 
         */
        pSubItemArrayList=new ArrayList<SubCategory>();
        pSubItemArrayList2=new ArrayList<SubCategory>();
        pSubItemArrayList.add(new SubCategory("Color", mItemListArray));
        pSubItemArrayList2.add(new SubCategory("Cloths", mItemListArray2));
        pSubItemArrayList.add(new SubCategory("Color", mItemListArray));
        pSubItemArrayList2.add(new SubCategory("Cloths", mItemListArray2));
        /**
         * 
         */

        pProductArrayList=new ArrayList<Product>();
        pProductArrayList.add(new Product("Emotions", pSubItemArrayList));
        pProductArrayList.add(new Product("Garments", pSubItemArrayList2));


        /***
         * adding item into listview
         */
        for (int i = 0; i < pProductArrayList.size(); i++) {

            LayoutInflater inflater = null;
            inflater = (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            View mLinearView = inflater.inflate(R.layout.row_first, null);

            final TextView mProductName = (TextView) mLinearView.findViewById(R.id.textViewName);
            final RelativeLayout mLinearFirstArrow=(RelativeLayout)mLinearView.findViewById(R.id.linearFirst);
            final ImageView mImageArrowFirst=(ImageView)mLinearView.findViewById(R.id.imageFirstArrow);
            final LinearLayout mLinearScrollSecond=(LinearLayout)mLinearView.findViewById(R.id.linear_scroll);

            if(isFirstViewClick==false){
            mLinearScrollSecond.setVisibility(View.GONE);
            mImageArrowFirst.setBackgroundResource(R.drawable.arw_lt);
            }
            else{
                mLinearScrollSecond.setVisibility(View.VISIBLE);
                mImageArrowFirst.setBackgroundResource(R.drawable.arw_down);
            }

            mLinearFirstArrow.setOnTouchListener(new OnTouchListener() {

                @Override
                public boolean onTouch(View v, MotionEvent event) {

                    if(isFirstViewClick==false){
                        isFirstViewClick=true;
                        mImageArrowFirst.setBackgroundResource(R.drawable.arw_down);
                        mLinearScrollSecond.setVisibility(View.VISIBLE);

                    }else{
                        isFirstViewClick=false;
                        mImageArrowFirst.setBackgroundResource(R.drawable.arw_lt);
                        mLinearScrollSecond.setVisibility(View.GONE);   
                    }
                    return false;
                } 
            });


            final String name = pProductArrayList.get(i).getpName();
            mProductName.setText(name);

            /**
             * 
             */
            for (int j = 0; j < pProductArrayList.get(i).getmSubCategoryList().size(); j++) {

                LayoutInflater inflater2 = null;
                inflater2 = (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                View mLinearView2 = inflater2.inflate(R.layout.row_second, null);

                TextView mSubItemName = (TextView) mLinearView2.findViewById(R.id.textViewTitle);
                final RelativeLayout mLinearSecondArrow=(RelativeLayout)mLinearView2.findViewById(R.id.linearSecond);
                final ImageView mImageArrowSecond=(ImageView)mLinearView2.findViewById(R.id.imageSecondArrow);
                final LinearLayout mLinearScrollThird=(LinearLayout)mLinearView2.findViewById(R.id.linear_scroll_third);

                if(isSecondViewClick==false){
                    mLinearScrollThird.setVisibility(View.GONE);
                    mImageArrowSecond.setBackgroundResource(R.drawable.arw_lt);
                    }
                    else{
                        mLinearScrollThird.setVisibility(View.VISIBLE);
                        mImageArrowSecond.setBackgroundResource(R.drawable.arw_down);
                    }

                mLinearSecondArrow.setOnTouchListener(new OnTouchListener() {

                        @Override
                        public boolean onTouch(View v, MotionEvent event) {

                            if(isSecondViewClick==false){
                                isSecondViewClick=true;
                                mImageArrowSecond.setBackgroundResource(R.drawable.arw_down);
                                mLinearScrollThird.setVisibility(View.VISIBLE);

                            }else{
                                isSecondViewClick=false;
                                mImageArrowSecond.setBackgroundResource(R.drawable.arw_lt);
                                mLinearScrollThird.setVisibility(View.GONE);    
                            }
                            return false;
                        } 
                    });


                final String catName = pProductArrayList.get(i).getmSubCategoryList().get(j).getpSubCatName();
                mSubItemName.setText(catName);
                /**
                 * 
                 */
                  for (int k = 0; k < pProductArrayList.get(i).getmSubCategoryList().get(j).getmItemListArray().size(); k++) {

                        LayoutInflater inflater3 = null;
                        inflater3 = (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                        View mLinearView3 = inflater3.inflate(R.layout.row_third, null);

                        TextView mItemName = (TextView) mLinearView3.findViewById(R.id.textViewItemName);
                        TextView mItemPrice = (TextView) mLinearView3.findViewById(R.id.textViewItemPrice);
                        final String itemName = pProductArrayList.get(i).getmSubCategoryList().get(j).getmItemListArray().get(k).getItemName();
                        final String itemPrice = pProductArrayList.get(i).getmSubCategoryList().get(j).getmItemListArray().get(k).getItemPrice();
                        mItemName.setText(itemName);
                        mItemPrice.setText(itemPrice);

                        mLinearScrollThird.addView(mLinearView3);
                  }

                mLinearScrollSecond.addView(mLinearView2);

            }

            mLinearListView.addView(mLinearView);
        }       
    }

}

有人可以向我解释为什么会更好吗?优点/缺点?

5 个答案:

答案 0 :(得分:2)

不要太严格,这里是我对这段代码的解释。让我们称之为反应流Roland的所有者。

首先,Roland需要一个适用于所有inboundSignals

的通用接口
static interface Signal {};

ConcurrentLinkedQueue<Signal> inboundSignals = new ConcurrentLinkedQueue<Signal>();

CancelSubscribeSend之类的信号始终具有相同的目的是不可变的并经常发生,因此将它们实现为Joshua Bloch's Singleton是一个好主意:< / p>

enum Cancel    implements Signal { Instance; };
enum Subscribe implements Signal { Instance; };
enum Send      implements Signal { Instance; };

另一种做同样的方式与你的建议和我最喜欢的方式类似:

enum CommonSignals implements Signal{

    Cancel {
        @Override
        void debug() {
            System.out.println("Cancel");
        }
    },

    Subscribe {
        @Override
        void debug() {
            System.out.println("Subscribe");
        }
    },

    Send {
        @Override
        void debug() {
            System.out.println("Send");
        }
    };

    abstract void debug();

    [...] some other methods I could need in the future
}

如您所见,这是一个不同的实现。但这个想法是一样的 - 信号为单身

我们继续找到这段代码:

static final class Request implements Signal {
    final long n;
    Request(final long n) { // every Request has different value of n
        this.n = n;
    }
};

由于inboundSignals可以包含多个Request个对象,因此无法将此类型的信号实现为Singleton。因此,它不能是CommonSignals的成员或实施为enum

<强>结论

Roland使用了许多可能性之一来实现单身人士。我认为这更像是一种品味如何去做。

答案 1 :(得分:1)

对于AsyncIterablePublisher中的用法类型,两种形式是等价的,可以说后者,一个带有多个常量的枚举,更自然。

实际上,前一种形式非常罕见。我可以看到一个支持使用它的论点(但是很少见,这意味着这一点通常不那么重要):当你在自己的枚举中定义每个常量时,你有机会定义不同的方法/字段,例如:

enum Cancel implements Signal { Instance; };
enum Send implements Signal { 
  Instance; 
  public void someSendSpecificMethod() { ... }
}

所以你现在可以做Send.Instance.someSendSpecificMethod()。非常尴尬,非常罕见。

答案 2 :(得分:1)

不同之处在于您可以在不更改原始枚举的情况下添加另一个Signal实例。您的代码可以使用Signal实例,并且可以提供不同的类型。与类的接口相同 - 为您提供了灵活性,但仅在您需要它时才有用。在你的情况下,我没有看到太多用途,因为界面是空的,实现它的枚举没有任何内容。

您可以查看此站点以获取包含接口的枚举的一个很好的示例:

http://www.selikoff.net/2011/06/15/java-enums-can-implement-interfaces/

答案 3 :(得分:0)

因为我不知道批准哪个答案,所以我邮寄了这段代码的作者并询问了他对此的看法。这是对话(块是来自他。普通文本是我的):

  

嗨,迈克尔,

那么只有一个枚举有什么区别?你不会有三个单身,但仍然有三个唯一定义的对象。:

  

当然,那可以做到,但是我必须为它创造一个名字   (比如ConcreteSignal),我选择的编码避免了:)

enum Signal {
  Cancel, Subscribe, Send;
}

我认为这也是线程安全的,如果你真的想要拥有共享接口,例如你可以与对象共享,你可以这样做:

enum ConcreteSignal implements Signal {
  Cancel,
  Subscribe,
  Send;
}
  

你绝对可以像上面那样做,但我认为   他们[取消,订阅,发送]并不比请求更具体   (这也是一个信号):   https://github.com/reactive-streams/reactive-streams-jvm/blob/v1.0.0/examples/src/main/java/org/reactivestreams/example/unicast/AsyncIterablePublisher.java#L49

     

此外,这也可以鼓励使用Enum的方法   枚举所有可能的信号,它不能,因为请求是   不是信号。有意义吗?

确实在Scala中你更愿意使用Object,但在Java中很少见到类似你的实现。我很好奇我在Java中缺少一些简洁的功能。但是,如果我理解正确,那是因为你更接近Scala,因为它更接近你的首选语言Scala?

  

我想这有一点,但单身作为枚举模式   在Java中是众所周知的,所以唯一“奇怪”的事情就是   每个取消,订阅和发送都有一个独特的“枚举”,但是   我之前解释过,因为请求不能像我那样编码   选择了更多“Scala-y”版本。

     

因此,如果“请求”不需要任何参数,我就像你一样   建议:枚举信号{取消,请求,订阅,发送}

神秘解决了: - )。

答案 4 :(得分:0)

我认为使用enum接口的唯一原因是,某些信号的数据与其他信号不同,因此需要扩展枚举类型以将数据附加到其中。