So I have an Activity. The Activity hosts a ViewPager with tabs, each tab holding a Fragment in it. The Fragments themselves have a RecyclerView each. I need to communicate changes from the RecyclerView's adapter to the activity. 

Currently, I am using the listener pattern and communicating using interface between each of the components. i.e I have an interface between the RecyclerView's adapter and the Fragment holding it. Then an interface from the Fragment to the ViewPager's FragmentStatePagerAdapter which is creating all the Fragments. And 1 more interface between the ViewPager's adapter and the Activity hosting the ViewPager. I feel that there are too many interfaces for all the components because of how they are structured.

Currently I am not facing issues as such but I think the listener pattern is acting like an anti-pattern due to all the nested components. Instead of creating independent components I think the hierarchy will make it difficult for making code changes in future.

Am I doing it correctly or is there a better way to do it? Is this a case where I should use an Event Bus or Observer Pattern (If yes can you point me to some examples where someone overcame a similar problems using it)?

NOTE : If it matters, I need it to maintain a global object in the activity, something like a shopping cart where I can add or remove items and these items are present in RecyclerView's adapter from where I can add it to the cart and also increment or decrement the count for a particular item. The ViewPager and Tabs help segregate these items in various categories.

Edit 1 : Some code trying out @LucaNicoletti's approach -
I have skipped one level that is the level with the ViewPager's FragmentStatePagerAdapter. I guess that should not matter and stripped of some other code to keep it small.

MainActivity:

```
public class MainActivity extends AppCompatActivity implements View.OnClickListener, FoodAdapter.OnFoodItemCountChangeListener {

    @Override
    public void onFoodItemDecreased(FoodItemModel foodItemModel, int count) {
        Log.d("Test", "Dec");
    }

    @Override
    public void onFoodItemIncreased(FoodItemModel foodItemModel, int count) {
        Log.d("Test", "Inc");
    }
    // Other methods here
}

```

Fragment hosting the Adapter:

```
public class FoodCategoryListFragment extends Fragment implements FoodAdapter.OnFoodItemCountChangeListener {

    // Other boring variables like recyclerview and layout managers
    FoodAdapter foodAdapter;

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        // Other boring intializations for recyclerview and stuff

        // I set the click listener here directly on the adapter instance
        // I don't have this adapter instance in my activity
        foodAdapter.setOnFoodItemClickListener(this);
        rvFoodList.setAdapter(foodAdapter);
    }
}

```

The adapter class at the lowest level:

```
public class FoodAdapter extends RecyclerView.Adapter<FoodAdapter.FoodViewHolder> {

    private OnFoodItemCountChangeListener onFoodItemCountChangeListener;
    private List<FoodItemModel> foodItems;

    // The interface
    public interface OnFoodItemCountChangeListener {
        void onFoodItemIncreased(FoodItemModel foodItemModel, int count);

        void onFoodItemDecreased(FoodItemModel foodItemModel, int count);
    }

    // This is called from the fragment since I don't have the adapter instance 
    // in my activty
    public void setOnFoodItemClickListener(OnFoodItemCountChangeListener onFoodItemCountChangeListener) {
        this.onFoodItemCountChangeListener = onFoodItemCountChangeListener;
    }

    // Other boring adapter stuff here
@Override
        public void onClick(View view) {
            switch (view.getId()) {
                case R.id.bMinus:
                        onFoodItemCountChangeListener.onFoodItemDecreased(foodItems.get(getAdapterPosition()),
                                Integer.parseInt(etCounter.getText().toString()));
                    }
                    break;
                case R.id.bPlus:

                        onFoodItemCountChangeListener.onFoodItemIncreased(foodItems.get(getAdapterPosition()),
                                Integer.parseInt(etCounter.getText().toString()));
                    }
                    break;
            }
        }
}

```