代码之家  ›  专栏  ›  技术社区  ›  kaymcray

设计模式跟踪方法调用/调用方

  •  0
  • kaymcray  · 技术社区  · 7 年前

    我不知道在特定的软件设计情况下该怎么做。只是在网上搜索解决方案,但没有找到满意的答案。所以我只想知道你的专业知识和最好的做法是什么。 我有一个系统,从几个抽象层开始。向用户展示的API是一个简单的类,具有数量紧凑的方法。调用这些方法将在整个抽象过程中引发方法调用的雪崩。一路上会做出一些决定。通过这种方式,每个元素都可以通过消息系统将决定和决定的原因发送给想要阅读它的人。该系统还记录了所有的呼叫和决策,这非常重要——当然是最重要的。老实说,这是核心问题。

    问题是:我想知道世界卫生组织调用了某种方法。因此,我可以向下传递某种句柄,每个抽象都知道:“对,这家伙想要它。所以我可以记录:这家伙想要它。”

    我之所以相信我需要它,是因为其他不同的系统将能够使用该api。可能GUI想要删除命令,可能是HTTP驱动的远程控制器,可能是硬件触发器,可能是自动执行例程。

    现在我只是看不见树木。我只是给API一个类似票证的对象实例。系统正在使用id注册该票据。API用户在调用命令时必须提交票据,以便系统知道刚才调用的是谁。

    是否有一个好的模式来跟踪/识别方法的调用方?

    编辑: 虽然这是一个普遍的问题,但在这种情况下使用的语言是c!

    2 回复  |  直到 7 年前
        1
  •  0
  •   oerkelens    7 年前

    你可以使用 [CallerMemberName] 属性:

    public void SomeMethod(string name, [CallerMemberName] string callerName = null)
    {
        Console.Writeline($"SomeMethod was called from {callerName}");
        ...
    }
    
        2
  •  0
  •   kaymcray    7 年前

    我目前的解决方案很有魅力。。。目前为止但我想知道这是否会被视为不好的做法,或者你是否会从第一眼看到瓶颈jsut。

        //< API user will call this kind of method handing in their requested Accessor!
        public void Command( int a, int b, KomiAccessorBase accessor=null ){
            if( !AccessGranted( accessor ) ) return;
            this.SubController.CommandA( a, b , accessor );
        }
    
        //< Accessor is checked on validity
        private bool AccessGranted(KomiAccessorBase accessor, [CallerMemberName] string callerName = null ) {
            if (accessor == null) {
                log("KOMI - Access to ["+callerName+"] denied: No Accessor handed in!", MsgType.LOG);
                return false;
            }
            if ( !_kacc_inventory.ContainsKey(accessor.KACCHashId)) {
                log("KOMI - Access to [" + callerName + "] denied: Accessor not registered in KOMI!", MsgType.LOG);
                return false;
            }
            return true;
        }
    
        protected Dictionary<int, KomiAccessorBase> _kacc_inventory = new Dictionary<int, KomiAccessorBase>();
    
        //< The Accessor base class. API user have to derive from that!
        public abstract class KomiAccessorBase : RecieverBase, INameable {
            public int KACCHashId { get; private set; }
            private string _name;
            public string Name {
                get {
                    return _name;
                }
                private set {
    
                }
            }
            protected KomiAccessorBase(string name, KOMI komi) : base(komi.Office) {
                Name = name;
                KACCHashId = -1;
                KACCHashId = komi.RegisterAccessor(this); //Perform the real registration
            }
        }
    
        //< Registeres the Accessor on KOMI for access checking!
        public int RegisterAccessor(KomiAccessorBase acc) {
            if (acc.KACCHashId != -1) return -1; //Abbort registration if already registered!
            int salt = 1;
            int hashId = (salt + "#" + acc.Name).GetHashCode();
            while (_kacc_inventory.ContainsKey(hashId)) {
                salt++;
                hashId = (salt + "#" + acc.Name).GetHashCode();
            }
            _kacc_inventory.Add(hashId, acc);
            return hashId;
        }