TheRedEye Ответов: 2

Лучшая практика OO - передача ссылки вызывающего абонента на методы интерфейса


У меня есть ситуация, когда мне нужно вызвать методы, которые находятся в классе вызывающего абонента. Должен ли я передать " это " в качестве параметра, как я сделал ниже, или я должен вызывать события обратно вызывающему абоненту? Или есть другой способ, которым это обычно делается?

Что я уже пробовал:

Приведенный ниже пример работает, но кажется немного грязным. Я чувствую, что должен быть лучший способ.

void Main()
{
	var stack = new Stack();
	stack.Push(1);
	stack.Push(2);
	stack.Push(3);
	stack.Push(4);
	
	var specialStack = new SpecialStack(stack, new TriplePopper());
	specialStack.SpecialPop();
	// stack now only has a count of 1
}

public class SpecialStack
{
	IPopper _popper;
	Stack _stack;

	public SpecialStack(Stack stack, IPopper popper)
	{
		_stack = stack;
		_popper = popper;
	}

	public void SpecialPop()
	{
		_popper.SpecialPop(this);
	}

	public void PopOnce()
	{
		_stack.Pop();
	}

}

public interface IPopper
{
	void SpecialPop(SpecialStack stack);
}

public class DoublePopper : IPopper
{
	public void SpecialPop(SpecialStack stack)
	{
		stack.PopOnce();
		stack.PopOnce();
	}
}

public class TriplePopper : IPopper
{
	public void SpecialPop(SpecialStack stack)
	{
		stack.PopOnce();
		stack.PopOnce();
		stack.PopOnce();
	}
}

2 Ответов

Рейтинг:
12

OriginalGriff

Поднимите события обратно к вызывающему объекту: класс никогда не должен знать, кто или что его вызвало, поэтому он не должен обращаться к методам в них. Если вы это сделаете, вы заблокируете дизайн вместе, так что вы не сможете изменить один без учета влияния на другой, и вы не сможете повторно использовать классы независимо.


Рейтинг:
1

BillWoodruff

Я думаю, что то, что вы хотите сделать здесь, может быть сделано гораздо проще. расширяющий В 'класса стек :

using System.Collections.Generic;
using System.IO;

namespace WFTemplate_Aug2020
{
    public class StackPopEx<T> : Stack<T>
    {
        public StackPopEx(params T[] values)
        {
            foreach(T itm in values) Push(itm);
        }

        public void PopEx(int npops)
        {
            if (npops <= 0)
            {
                throw new InvalidDataException($"npops = {npops}  <= 0");
            }

            if (npops > Count)
            {
                throw new InvalidDataException($"npops = {npops} greater than stack count: {Count}");
            }

            for (int i = 0; i < npops; i++)
            {
                Pop();
            }
        }
    }
}