Предоставление модульных функций класса C #

У меня есть класс Node, который управляет экземплярами моего класса Person. Базовый класс с минимальными функциональными возможностями выглядит следующим образом:

public class Node
{
    //attributes
    protected readonly int steps;
    protected readonly int angleDeltaQ;

    //constructor
    public Node(int steps, int angleDeltaQ)
    {
        this.steps = steps;
        this.angleDeltaQ = angleDeltaQ;
    }

    //methods
    public virtual int UpdateMe(Person me)
    {
        me.angleQ = QMath.RadLimitQ(me.angleQ + angleDeltaQ);
        me.xQ += QMath.CosQ(me.angleQ, me.speedRev);
        me.zQ += QMath.SinQ(me.angleQ, me.speedRev);
        me.steps--;
        if (me.steps == 0) return (int)NodeFeedback.targetReached;                
        else return (int)NodeFeedback.notFinished;
    }
    public virtual void AssignMe(Person me)
    {
        me.steps = steps << me.speedRev;
    }
}

Я оставляю класс Person отсюда, поскольку не важно описать мою проблему. Нужно только знать, что Person имеет атрибут Node и вызывает метод Assign узла один раз, а затем регулярно обновляется.

Теперь есть много дополнительных вещей, которые может сделать узел.

Например, в методе Update также следует изменить значение me.yQ. Для этого ему нужны дополнительные атрибуты и дополнительный код в методе Update.

Для экземпляра Person не должно иметь значения, что именно происходит с его атрибутом Node, поскольку он может вызывать два метода.

Моя проблема сейчас, у меня есть 8 дополнительных функций для класса Node. Если бы я создал подкласс Node для каждой комбинации, он стал бы ужасно большим.

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

Всего 1 ответ


Вы должны использовать шаблон посетителя

public abstract class Node
{
    //attributes
    protected readonly int steps;
    public readonly int angleDeltaQ;
    private IUpdateVisitor updateVisitor;

    protected  Node():this(new DefaultUpdateVisitor())
    {

    }
    protected  Node(IUpdateVisitor visiter)
    {
        updateVisiter = visiter;
    }
    //constructor
    public Node(int steps, int angleDeltaQ)
    {
        this.steps = steps;
        this.angleDeltaQ = angleDeltaQ;
    }

    //methods
    public virtual int UpdateMe(Person me)
    {
            updateVisitor.UpdateMe(this,me);
    }
    public virtual void AssignMe(Person me)
    {
        me.steps = steps << me.speedRev;
    }
}



public interface IUpdateVisitor
{
     int UpdateMe(Person me);
}


public class DefaultUpdateVisitor : IUpdateVisitor
{
    public  int UpdateMe(Node node, Person me)
    {
        me.angleQ = QMath.RadLimitQ(me.angleQ + node.angleDeltaQ);
        me.xQ += QMath.CosQ(me.angleQ, me.speedRev);
        me.zQ += QMath.SinQ(me.angleQ, me.speedRev);
        me.steps--;
        if (me.steps == 0) return (int)node.NodeFeedback.targetReached;                
        else return (int)node.NodeFeedback.notFinished;
    }
}


public class AotherUpdateVisitor: IUpdateVisitor
{
 public  int UpdateMe(Node node, Person me)
 {
     .....
 }   
}

Есть идеи?

10000