Предоставление C# класса модульных функций - PullRequest
0 голосов
/ 15 января 2020

У меня есть класс 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 узла, а затем регулярно обновляет его.

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

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

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

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

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

1 Ответ

0 голосов
/ 15 января 2020

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

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)
 {
     .....
 }   
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...