我如何创建一个公共的全局数据对象,任何其他对象可以读取,但只有某些对象可以设置

本文关键字:对象 其他 任何 读取 设置 全局 创建 何创建 一个 数据 | 更新日期: 2023-09-27 18:02:10

这是一个难题。我有一组特定的状态变量,它们几乎在我拥有的所有支持对象中使用,我希望这些变量能够被任何需要读取它们的对象读取,但我想保护它们,以便只有一个对象能够设置它们。

例如,假设我正在制作一款扑克游戏。变量:-最低投入-最大投注-最大玩家数-当前游戏状态(下注,洗牌,发牌,支付等)

就我个人而言,我更喜欢小型紧凑的组件类,所以假设我在一个控制器类中拥有大部分扑克游戏逻辑,但我有50个支持对象来处理扑克游戏逻辑本身以外的所有内容,例如PlayerInterface,图形控制器,处理洗牌和发牌逻辑的"the Deck"等。我的许多较小的支持类需要看到最小赌注是什么,我目前使用的方法是控制器类将这些变量作为参数传递给支持类。

这样做的明显缺点是,我有50个支持对象,它们都持有自己的局部变量,以保存我从控制器传递给它们的相同信息。如果这些变量中的任何一个不同步,就会浪费参数、内存和打开大量的风险。

那么,我如何使这些变量全局,使每个人都可以访问和读取它们?本能反应的答案是一些公共静态变量,然而这带来的问题是任何人都可以对它们进行编写。我不仅不希望我的支持对象有能力在控制器不知情的情况下改变最小赌注,而且我也不希望持有扑克游戏的客户端shell能够在没有首先通过控制器中包含的适当检查的情况下改变它们。

我该怎么做?有人曾经向我提到过单身的想法,但经过大量的研究,其中大部分是几年前或更长时间,我发现在社区中,认为单身是一个好主意的人和认为单身不是一个好主意的人大约各占一半。

如果不是单例或静态,那是什么?我愿意接受任何研究和尝试的想法。

请记住,我希望任何对象,任何时间,任何地点都能够获得它需要的数据,但只有一个非常特定的对象能够在需要更改时设置数据,以便它能够通过适当的检查进行过滤。我所说的适当检查是指,例如在扑克游戏中,如果玩家有能力改变桌子上的最小赌注,他应该只能在两手之间或比赛开始之前这样做。我不希望他在玩的时候摆弄这些东西。

提前感谢您的输入

我如何创建一个公共的全局数据对象,任何其他对象可以读取,但只有某些对象可以设置

您可以在这里使用接口方法。

声明两个接口为

public interface IReadOnlyAccess
{
     int Property{get;}
}
public interface IFullAccess
{
     int Property{get;set;}
}

那么你的类将实现两个接口,如

public interface MyClass: IReadOnlyAccess, IFullAccess
{
     public int Property{get;set;}
}

然后无论你需要完全访问你得到它通过IFullAccess,否则-通过IReadOnlyAccess。

创建一个内部类,它可以访问主类的私有变量:

public class OuterClass
{
    public string StringProperty { get; private set; }
    public  InnerClass CreateInnerClass()
    {
        InnerClass ic = new InnerClass(this);
        return ic;
    }
    public class InnerClass
    {
        private OuterClass _outer;
        public InnerClass(OuterClass oc)
        {
            _outer = oc;
        }
        public string Prop
        {
            get
            {
                return _outer.StringProperty ;
            }
            set
            {
                _outer.StringProperty = value;
            }
        }
    }
}

创建大多数人都有只读访问权限的主类:

var oc = new OuterClass();
oc.StringProperty = "123";   <-- not allowed, is `readonly`

要写属性,创建内部类实例:

var oc = new OuterClass();
var ic = oc.CreateInnerClass();
ic.StringProperty = "123";

似乎最干净,最简单的解决方案是在控制器类中完成所有操作。

我们这样写:

AS3:

//adding the final keyword, locks this class so others can't extent/inherit from it
public final class MyController {
    //create a privately scoped var (it can only be accessed in this class)
    private var minBet:Number = 0;
    //create a public getter that can be read by any class/object
    public function get minimumBet():Number {
        return minBet;
    }
    private function set minimumBet(value:Number):void {
        //do you checks etc
        minBet = value;
    }
}
c#

//sealed in C# is the same as final in AS3
public sealed class MyController
{
    private float minBet = 0;
    public float minimumBet
    {
        get { return minBet; }
    }
}

instanceOfMyController.minBet //will throw an error
instanceOfMyController.minimumBet = 10; //will throw an error
instanceOfMyController.minimumBet //will supply the value of the minBet var

如果你正在编写许多跨语言代码,可以考虑使用Haxe之类的工具,它可以用相同的代码编译成AS3或c#。