如何将链函数从一个类添加到另一个类?

Posted

技术标签:

【中文标题】如何将链函数从一个类添加到另一个类?【英文标题】:How to add chain functions from one class to another? 【发布时间】:2020-02-26 01:04:41 【问题描述】:

我正在尝试在 JS 中开发一个供个人使用的游戏引擎。我想让我的引擎能够使用不同类的元素。我试图解决的一个这样的问题是将方法从一个类(比如一个链接函数的数学类)链接到我的主函数。

这是我希望它看起来像的示例:

let game = new Engine()
game.operator(5).sum(3).divide(2)

这可能是我的代码中的内容,尽管我不确定该怎么做。

class Engine 
   constructor() 
    //Set up engine here
    /* This is where I am unsure how to link the following operator class to this one. 
    * Do I put it here in constructor or ...
    */

   
   /* ... do I put it here? (Or not in this class at all?)
   *
   * This is what I tried doing as a function
   *
   * operator(input) 
   *    let op = new Operator(input);
   * 
   */

class Operator 
    /*The following class is different than the one I am using, but follows similar syntax: 
    * Basic usage: operator(5).sum(3, 4) => Should output 12
    * How the class works is mostly irrelevant, just know it chains methods.
    */
    constructor(input) 
        this.input = input;
        this.answer = this.input;
    
    sum() 
        let a = arguments[0]
        for(var i = 1; i < arguments.length; i++) 
            a += arguments[i];
        
        this.answer += a;
        return this;
    
    divide() 
        let a = arguments[0];

        for(var i = 1; i < arguments.length; i++) 
            a *= arguments[i];
        
        this.answer /= a;
        return this;
    


如何让一个类能够链接不同类的方法?

【问题讨论】:

Engine 中的 operator 函数可以返回您在那里构建的 Operator 对象。很高兴您可以在单个语句中链接事物,但不要过度。 【参考方案1】:

链接模式是让实例保持链状态,并提供返回链状态的“值”方法。为了在两个类之间链接,我想我会包含一个特殊的 value 方法,它返回另一个类的实例。 (为了保持读者的导向,将其命名为表明类型更改的名称)...

class ObjectA 
  constructor(string) 
    this.chainValue = string
    this.string = string
  

  transformA() 
    this.chainValue = this.chainValue.toUpperCase()
    return this
  

  transformB() 
    this.chainValue = this.chainValue + "bar"
    return this
  

  // the regular value method
  get value() 
    return this.chainValue
  

  // like the value method, but named to explicitly return MyNumber
  get numberValue() 
    return new MyNumber(this.value.length)
  


class MyNumber 
  constructor(int) 
    this.chainValue = int
    this.int = int
  
  
  add(n) 
    this.chainValue += n
    return this
  
  
  get value() 
    return this.chainValue
  


let a = new ObjectA("foo")
console.log(
  a
  .transformB()   // append "bar"
  .transformA()   // convert to upper case
  .numberValue    // return a number (arbitrarily, the length of the chain state)
  .add(12)        // add 12
  .value          // expect 18
)

【讨论】:

这也很好用!这输出与其他答案相同,但不需要代​​理。【参考方案2】:

您可以为此目的使用代理。

    class Engine 
    operator() 
      // code
      console.log('call operator')
    
  
  class Operator 
    sum() 
      // code
      console.log('call sum')
    

    divide() 
      console.log('call divide')
    
  

  class SuperOperator 
    negate() 
      console.log('call negate')
    
  

  const operator = new Operator();
  const superOperator = new SuperOperator();
  const engine = new Engine();


  const objectsToChainFrom = [
    engine,
    operator,
    superOperator,
  ];

  // create helper function for proxy
  function wrapper(originalMethod, ctx) 
    return function () 
      originalMethod.apply(ctx, arguments);
      // return proxy;
      return this;
    
  

  var proxy1 = new Proxy(objectsToChainFrom, 
    get(target, methodToCall, receiver) 
      const objectWithMethod = target.find(el => el[methodToCall]);
      return wrapper(objectWithMethod[methodToCall], objectWithMethod)
    
  );

  proxy1
    .sum()
    .operator()
    .divide()
    .negate()

【讨论】:

以上是关于如何将链函数从一个类添加到另一个类?的主要内容,如果未能解决你的问题,请参考以下文章

在java中将一个链表添加到另一个链表

我如何将样式从一个类应用到另一个类,以及其间的所有项目

将对象从一个类添加到另一个类

如何在 PyQt5 / PySide2 中从一个类访问属性到另一个类

如何从另一个类调用方法函数?

我如何从一个班级获取信息到另一个班级