在 Rails 中,我见过的最接近Django Signals的是Observers。它们的问题在于,它们仅限于触发与模型生命周期相关的硬编码事件的回调。
Django 信号可以在任何地方创建、在任何地方触发并在任何地方处理。模型生命周期回调只是碰巧内置的常规信号,由 ORM 触发。
有谁知道 Rails 有类似的通用解决方案吗?它可以是一些通用的 Ruby 库,不依赖于 Rails,这会更好。
编辑:观察者是最接近的东西,但这不是我正在寻找的东西。这是一个一对多的解决方案。任何人都可以收听,但只有原始对象可以发帖。我想要一个声明信号的东西,任何人都可以触发它并处理它。另外,我不喜欢 Ruby Observer 规定处理程序具有 #update 方法。我希望能够传递具有适当签名的任何方法引用。
我可以使用 Ruby Observer 来实现我自己的此类代理,但我正在尝试了解是否有人已经这样做了。
开门见山!
- 信号/槽和事件/事件监听器如何比较?
- 有什么优点和缺点吗?
- 我应该考虑哪一个?为什么?
提前致谢!
events design-patterns event-listener signals-slots observer-pattern
在观察者模式中是否有向新观察者发布“初始状态”的首选习惯用法?
大多数描述观察者模式的可用材料和示例都假设观察者对收到更改通知感兴趣,但不关心“初始状态”(观察者订阅更改时的当前状态)。
一种可能性是在订阅时将“初始”(当前)状态推送给新观察者,例如:
public class MyObservable extends java.util.Observable
{
public synchronized void addObserver(Observer observer)
{
super.addObserver(observer);
// Push current state to this observer
observer.update(this, currentState);
}
}
Run Code Online (Sandbox Code Playgroud)
有更好/首选的方法吗?
是否有一种设计模式可以形成“复合”观察者/可观察者?
我的意思是我有一个可观察的对象A,可以通知其侦听器发生某些变化。
每个侦听器也是一个可观察对象,并通知其自己的侦听器(在它执行的某些操作上,该操作是由第一个可观察对象的通知触发的)。
这种观察者/可观察量的“链接”是否符合设计要求,或者是否有标准模式?
这个问题的目标是确定我是否可以包装设置对象的属性,而不必只编写 setter 然后包装 setter。
我正在尝试实现一个观察者模式,并且我不想编写超出我需要的代码(所以我当然会写一个又大又长的 StackOverflow 问题,哈 - 我认为长期回报是值得的)。
我开始尝试用obj.__setattr__一个函数来包装,但它没有达到我预期的效果,所以现在我想知道如果我不只编写一个 setter,我是否可以包装对象属性的赋值或更改。
这是我尝试过的:
class A(object):
pass
def wrapper(obj, func):
def inner(*args, **kwargs):
print "called it"
return func(*args, **kwargs)
return inner
Stick = A()
Stick.__setattr__ = wrapper(Stick, Stick.__setattr__)
Stick.x = 14 #does not print "called it"
Run Code Online (Sandbox Code Playgroud)
如果我只写一个设置器,它将成为一个简单的钩子,例如:
class A(object):
def __init__(self, x):
self.x = x
def set_x(self, new_x):
self.x = x
Run Code Online (Sandbox Code Playgroud)
但我希望能够以这样的方式实现观察者模式:每当obj.x由于任何原因发生更改时,侦听器都会更新。例如,如果obj.x是一个,int我可以直接设置它,也可以使用obj.x += some_int它来设置它,所以我想知道是否有一种方法可以包装任何/所有设置obj.x,例如,编写obj.set_x(), obj.add_to_x(), …
我想知道我对不同事件(例如“ userLoggedOut”、“ userRegistered”、“ userLoggedIn”)的观察者模式的实现是否正确,以下是我的简化代码:
索引.php
$login = new \Observer\Observable\Login;
$userData = $login->getData();
$login->attach( new \Observer\Observer\Email );
$login->notify( 'userLoggedIn' );
$login->notify( 'userLoggedOut', $userData );
$login->notify( 'userRegistered' );
Run Code Online (Sandbox Code Playgroud)
登录.php
namespace Observer\Observable;
use Observer\Interfaces;
class Login implements Interfaces\Observable {
private $observers = array();
function attach( Interfaces\Observer $object ) {
$this->observers[] = $object;
}
function getObservers() {
return $this->observers;
}
function notify( $action, $data = null ) {
foreach( $this->observers as $observer ) :
if( method_exists( $observer, $action ) ) $observer->$action( …Run Code Online (Sandbox Code Playgroud) 我对 MVVM 和观察者模式的概念感到困惑。MVVM 本身是否遵循观察者模式。或者它们彼此完全不同?
任何人都可以用简单的词来解释我。
提前致谢。
我java.util.Observable在我的Android应用程序中使用时遇到了麻烦.在我的应用程序中,我想更新listview数据在后台更改的时间.
所以来自的对象listview都在观察者中.我arraylist从观察者班看到他们.在Eclipse Debugging中,我看到了对象的引用,例如:at.stockserv.todo.Todo@1a3f2cb7
有一点我不明白:在我的观察者更新方法中更改数据时
@Override
public void update(Observable observable, Object data) {
if (observable instanceof DBObjectUpdateObserver) {
ObserverMessage message = (ObserverMessage) data;
if (message.getAction() == Actions.messageIdChanged) {
if (message.getData().get("oldId").equals(Integer.valueOf(getId()))) {
setId((Integer) message.getData().get("newId"));
DBObjectUpdateObserver.getInstance().dataHasChanged(this);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
在setId之后,对象突然有另一个引用.所以在我看来listview,旧的数据仍然存储在旧的引用中.
我在视图中的代码:
@Override
public void update(Observable observable, Object data) {
ObserverMessage message = (ObserverMessage) data;
if (message.getAction() == Actions.messageDBDataChanged) {
if (actNotices.contains(message.getData().get("dbObject"))) {
notifyDataSetChanged();
Toast.makeText(getApplicationContext(), "Data is updated ", Toast.LENGTH_LONG).show();
}
} …Run Code Online (Sandbox Code Playgroud) 我正在编写一个 java 软件,它就像一个中间件,用于从不同来源收集数据,然后处理数据并将其发送到不同的目的地。
数据源和目的地包括:文件、数据库、TCP、HTTP。
用户将能够创建一个通道,每个通道将有一个数据源(文件读取器、数据库读取器、tcp 侦听器)和一个或多个数据目的地(文件写入器、数据库写入器、tcp 发送器)。
该应用程序将按以下方式工作:
我想到的是:

那么,这是代表渠道、来源和目的地的最佳方式吗?我认为源和目标有相似之处,例如,FileReader 和 FileWriter 类将相同,只是一个用于读取,另一个用于写入,将它们中的每一个表示为一个单独的类是否好?
我正在经典 CI mvc 设置中构建应用程序,其中用户具有通用/通用任务列表。任务的主要目的是向用户表明他必须完成特定操作,并将他重定向到他需要完成此操作的页面。
我的问题是当用户被重定向到需要发生操作的特定页面时,我们会丢失特定任务的上下文。因此,即使任务完成(在本例中,例如文档被上传),任务本身也不知道这一点,我们也没有真正的连接来更新任务。
经过一些研究,观察者设计模式看起来可以满足这一需求。但是在所有的例子中,我都没有提到如何在我们当前的系统中实际实现这一点。
在处理文档上传的控制器中,函数 upload_doc(){} 成功执行后,还应更新连接或订阅此文档上传的任务。
class Dashboard extends MY_Controller{
public function __construct()
{
parent::__construct();
// Force SSL
$this->force_ssl();
}
public function upload_doc(){
//Handle doc upload and update task
}
}
Run Code Online (Sandbox Code Playgroud)
任何人都可以以 noobfriendly 的方式帮助我如何在 CI 框架中实现此设置?
提前致谢!