【问题标题】:forcing definition of a function based on interface implemented基于实现的接口强制定义函数
【发布时间】:2013-08-16 15:46:48
【问题描述】:

我正在使用一些数据库多态性通过 eloquent/laravel 连接表关系。 (注意下面的例子已经被简化了,这两个对象已经在扩展一个基类,所以我不能扩展另一个可以实现我想要的行为的基类,它们扩展的基类与其他与我正在尝试的类无关的类共享在下面做)

class Pageable{
  public function table() {
    return $this->morphTo();
  }
}

class User {
  public function pageable() {
    return $this->morphOne('Pageable', 'table');
  }

  public function returnUrl() {
    return "http://...";
  }
}

class Company {
  public function pageable() {
    return $this->morphOne('Pageable', 'table');
  }

  public function returnUrl() {
    return "http://...";
  }  
}

我遍历 pageable,然后可以检索 User 或 Company 对象,但是我需要一个通用函数,例如 returnUrl,我可以调用任何可能被多态化为该关系的对象。有什么方法可以清理上面的内容,或者至少创建一些故障安全检查,以确保所有必需的方法都在类中实现,例如它们实现 PeageableInterface。比如我可以在界面中设置这个returnUrl函数是必需的吗?

我将如何创建这样的界面?

【问题讨论】:

    标签: php oop laravel eloquent


    【解决方案1】:

    尝试使用特征。

    在您的课程中,只需执行以下操作:

    use TraitWithReturnUrl;
    

    那么……

    trait TraitWithReturnUrl {
        function returnUrl() {
            // do stuff like it's on the object itself
        }
    }
    

    宾果! :)

    还可以查看我的 Fatty 库,它对类似的东西也很有用:https://github.com/kirkbushell/fatty

    在这两种情况下,您都需要 PHP 5.4+。

    【讨论】:

    • 您在这里找到了有趣的东西,先生! :) 有时间我会去看看。 PS。说什么? :P
    • 很棒的参考,我到底在哪里定义我的特征,哪个文件在哪个位置?我会研究一下 fat 它看起来很棒,这两者之间的唯一区别是 fat 在运行时吗?
    • @Oddman 我在 L 论坛上看到了你的帖子:P 但实际上我们还没有“见面”;p
    • 特征用于更具体的实现 - 正如您在这里所做的那样,因此应该采用您所采用的方法。您说 Fatty 更多地用于运行时扩展是正确的 - 它用于在您需要时提供方法和功能,而不是在实例化对象时提供。至于你把特征放在哪里——这完全取决于你。只要 Laravel 能看到它就可以了,这很容易通过 IoC 功能实现 :) Gadoma - 是的 :)
    【解决方案2】:

    Traits 可能是一种更好的方法(php 5.5 中的新功能),但您可以直接使用接口,我认为您的情况可能如下所示:

    1) 创建接口:

    interface Pageable {
    
        public function pageable();
    
    }
    

    2) 实现接口

    class User extends Model implements UserInterface, RemindableInterface, Pageable {
    
        ... other methods ...
    
        public function pageable() {
            return $this->morphOne('Pageable', 'table');
        }
    
    }
    

    但是,如果 pageable() 方法在每个实现中都是完全相同的代码,您可能需要创建一个定义它的抽象类,然后将其用作模型的基类:

    use Illuminate\Database\Eloquent\Model as BaseModel;
    
    abstract class NewModel extends BaseModel implements Pageable {
    
        public function pageable() {
            return $this->morphOne('Pageable', 'table');
        }
    
    }
    

    然后你的课程:

    class User extends NewModel implements UserInterface, RemindableInterface {
    
        // You now have the pageable() method available
    
    }
    

    希望能帮助你找到正确的方向。

    【讨论】:

    • 感谢 fideloper!这确实有帮助,但是我应该在哪里定义我的接口?
    • 当然,请参阅我的 SO 回答 here,这是我的想法,以及 setting up an application library 上的相应博客文章。
    猜你喜欢
    • 1970-01-01
    • 2015-05-08
    • 2015-04-17
    • 1970-01-01
    • 1970-01-01
    • 2013-02-19
    • 1970-01-01
    • 2015-10-23
    • 2021-12-14
    相关资源
    最近更新 更多