Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
避免意大利面代码(gamestatemanager) 我正在编写一个游戏的状态机(我使用C++和SFML,但是我试图隐藏语言特定的元素,因为这是一个关于任何OOP语言的问题)。 我有一个状态管理器更新当前活动状态的设置。但是,状态必须能够更改活动状态(例如,在菜单中按“播放”将启动播放状态),因此我在状态类中保留对StateManager的引用_Oop_Coding Style - Fatal编程技术网

避免意大利面代码(gamestatemanager) 我正在编写一个游戏的状态机(我使用C++和SFML,但是我试图隐藏语言特定的元素,因为这是一个关于任何OOP语言的问题)。 我有一个状态管理器更新当前活动状态的设置。但是,状态必须能够更改活动状态(例如,在菜单中按“播放”将启动播放状态),因此我在状态类中保留对StateManager的引用

避免意大利面代码(gamestatemanager) 我正在编写一个游戏的状态机(我使用C++和SFML,但是我试图隐藏语言特定的元素,因为这是一个关于任何OOP语言的问题)。 我有一个状态管理器更新当前活动状态的设置。但是,状态必须能够更改活动状态(例如,在菜单中按“播放”将启动播放状态),因此我在状态类中保留对StateManager的引用,oop,coding-style,Oop,Coding Style,这里有一个UML图,让事情更清楚。 如您所见,StateManager和State都相互引用。 我怎样才能避免意大利面代码?我应该让StateManager成为一个单例类吗?当我们这样做的时候,游戏课应该是一个单人课吗?我可以很容易地做到这一点,但我真的不喜欢游戏中的其他类能够访问游戏类或statemanager类,即使我是唯一的程序员。双向引用没有错。查看QWidgets的Qt父/子模型。如果每个状态只能影响一个StateManager,请使每个状态在其构造中采用指向StateManager

这里有一个UML图,让事情更清楚。

如您所见,StateManager和State都相互引用。
我怎样才能避免意大利面代码?我应该让StateManager成为一个单例类吗?当我们这样做的时候,游戏课应该是一个单人课吗?我可以很容易地做到这一点,但我真的不喜欢游戏中的其他类能够访问游戏类或statemanager类,即使我是唯一的程序员。

双向引用没有错。查看QWidgets的Qt父/子模型。如果每个状态只能影响一个StateManager,请使每个状态在其构造中采用指向StateManager“父级”的指针,或稍后设置。StateManager可以跟踪集合中的“子项”,每个子项都知道其父项是谁,因此它可以将任何更改通知该父项

编辑:
我认为第一件要考虑的事情是打破你的国家等级。目前,它同时代表一个状态和一个要转换为该状态的操作。动作应该了解状态机,告诉它改变状态。状态应该是状态机的内部状态。

您需要在契约中设计,契约也称为接口。例如,状态(原则上)不需要访问状态机。不过,一个状态的实现可能需要访问权限。C#中的示例:

请注意,
IState
的任何实现都不知道任何
IStateMachine
实现,它们只处理合同。还要注意的是,
MenuState
并不关心“IStateMachine”来自何处(控制反转),它只是使用它

如果需要,您可以在
IStateMachine
中为
GetStates()
添加另一个函数


最终,您使用这些契约来避免耦合;这意味着您可以完全替换
IStateManager
的实现,并且(假设遵守合同),
MenuState
仍然可以正常工作

你能把州政府也需要访问的部分分开吗?i、 e.从更简单的合同(接口)组成StateManager?i、 e.可通过更新和渲染进行渲染。然后您只给StateManager的这一部分。此外,您还希望将此IRenderable注入状态(即,查看控制反转)。我不确定您的意思。你能举个例子吗?你的意思是说,例如,会有另一个类使用changeState方法,而该状态引用了该类,但没有引用StateManager吗?我认为它有问题,因为我们必须设计一个大学申请,他们告诉我们这是最糟糕的设计。好吧,理想情况下,你可以使用某种基于事件的系统,这样一个州就可以向全世界尖叫“嘿,我改变了一些东西!”,而州经理知道如何倾听这些事件并做出反应。这样一来,一个州就不需要了解州经理或外部世界。它只是说“嘿,任何关心的人,用户希望你现在就玩。只要说'。”就行了。如果合适的话,由其他班级来倾听和回应。我想这已经超出了你设计的范围。我知道这是一个好的系统。然而,它确实超出了我设计的范围。我希望StateManager尽可能小,因为可能只有几个州(可能3个或4个)。如果代码只使用了一次,而且没有太多功能,我不想让代码过于复杂。如果我有一个隐式契约(我是唯一的程序员,可能不会发布我的源代码),说StateManager应该有一个ChangeState方法,那也可以吗?在这种情况下,除了干净的设计之外,使用契约还有其他好处吗?许多人在评论中提到了这一点,但一句话:解耦。基本上,你想要它,这样你就可以代替合同的执行,而不会破坏任何东西;i、 e.
MenuState
IStateManager
合同的作用仍然有效。简而言之就是这样。
public interface IState
{
    void Render();
    void Update();
}

public interface IStateMachine
{
    void ChangeState(IState newState);
}

public class MenuState : IState
{
    private IStateMachine _stateMachine;

    public MenuState(IStateMachine stateMachine)
    {
        _stateMachine = stateMachine;
    }

    public void Render()
    {
    }

    public void Update()
    {
    }
}

public class StateMachineImplementation : IStateMachine
{
    public void ChangeState(IState newState)
    {
    }
}