**Description**

Currently `BaseOperator` and `XComArgs` implements the same logic of `__lshift__`, `__rshift__` and others "chain" operations (`>>`, `<<`). It seems resonable to abstract this logic into `TaskMixin` to introduce some DRYness especially because the new concept of `TaskGroup` will also implement the same methods.

**Use case / motivation**

Limit duplication of logic.

**Related Issues**

https://github.com/apache/airflow/pull/10827#issuecomment-691927501
#10153 

airflow/models/xcom_arg.py
return (self.operator == other.operator
                and self.key == other.key)
    def __lshift__(self, other):
        """
        Implements XComArg << op
        """
        self.set_upstream(other)
        return other
    def __rshift__(self, other):
        """
        Implements XComArg >> op
        """
        self.set_downstream(other)
        return other
    def __rrshift__(self, other):
        """
        Called for XComArg >> [XComArg] because list don't have
        __rshift__ operators.
        """
        self.__lshift__(other)
        return self
    def __rlshift__(self, other):
        """
        Called for XComArg >> [XComArg] because list don't have
        __lshift__ operators.
        """
        self.__rshift__(other)
        return self
    def __getitem__(self, item):