您现在的位置 > 首页>知识问答 >

【外野码农多】求助!观察者模式的UI设计具体应该怎么实现

点击图片查看下一页
查看原图
更新:07-15     编辑:     来源:    
  • 花了好几天总算大致明白了C#的事件与委托,但是对于如何用这东西实现UI的观察者模式设计还是一头雾水。

    【外野码农多】求助!观察者模式的UI设计具体应该怎么实现


    就以这张图具体来讲,ConcreteSubject应该是什么?是所有会引起变化的部件吗?比如说按下装备栏按钮进入装备页面,那装备栏按钮就要注册进被观察者?

    “Subject 抽象主题角色:也就是抽象的被观察者对象,里面保存了所有的观察者对象引用列表,提供了注册和反注册的功能。”
    如果我只是做UI,需要动态添加删除观察者列表吗?还是说提前写好UI之间的互动关系,列表就不再变了。如果说需要动态变化,那应该怎么变呢?当前UI页面所有可操作的部分注册进列表,如果换页面就换列表吗?

    如果一个按钮又会影响其他人又会被其他人影响,那他又要在被观察者列表里,又要在观察者列表里了?

    还有传送的信息具体是什么东西呢?是否打开页面的布尔值?血量经验值这些常数?由设计师自己决定吗?


    网友评论:

    你说的这个谁懂啊

    在看到这种问题,真是喷了

    随便举个例子,没头脑喜欢在psn会员促销的时候买一年会员,不高兴喜欢在steam打折的时候喜加一,那么Subject就是所有这种游戏平台,ConcreteSubject就是psn或者steam,Observer就是所有玩家,没头脑和不高兴就是ConcreteObserver。
    Subject提供了让玩家关注并接收到最新打折消息(attach)并且可以随时取关(detach),而且会在促销时通知所有玩家(notifyObservers)
    所以没头脑和不高兴关注打折消息的流程就是psn.attach(没头脑)或者steam.attach(不高兴),促销来了的时候,psn.notifyObservers和steam.notifyObservers会触发关注玩家的update方法(通常实现为遍历关注的玩家并且逐个调用玩家的update方法,所有关注玩家列表可以由observers获得),没头脑的update的实现是买一年会员,不高兴的update的实现就是喜加一,至此,psn和steam实现了自动让两个傻叉玩家掏钱,因为只需要notifyObservers,直到他们detach。

    所以观察者模式的核心是:注册观察者在被观察的主体上,然后当主体遇到变化通知他们时,他们就会采取相应的行动

    打了这么多字,给点分吧

    这类问题为什么不google呢,偏要发到外野



    喜加一和续一年应该是observer上的listener调subject的接口实现的,update只是subject通知observer数据变化的接口。


    取决于observer和update怎么实现了
    模式只是现象,不是教条



    如果我只是做UI,需要动态添加删除观察者列表吗?

    我姑且理解只做UI是说你只写observer。那么你需要干的事情就是在observer里留一个subject的引用,在observer的构造里调用一下subject的attach把自己加到subject的观察者列表里就行了。UI上显示的数据和触发的事件都通过这个引用调用subject的对应的方法从subject拿过来或者传给subject。

    还是说提前写好UI之间的互动关系,列表就不再变了。如果说需要动态变化,那应该怎么变呢?

    UI之间的互动关系只能通过subject里的状态实现。比如说你实现了一个耍猴页面,所有人的页面(observer)上最开始都显示着剩余猴机数量和一个抢购按钮,剩余猴机数量被存储在服务器上(subject)。那么每次有人按抢购按钮,都会生成一个抢购事件通过页面存着的服务器地址(observer里对subject的引用)把事件传给服务器(调用subject里规定的方法),服务器处理事件的方式是剩余猴机数量减一,然后通过notifyObservers遍历并调用所有目前开着的页面(observer),于是所有页面上的猴机剩余数量都减一。这个过程中间可以有无数人打开新的页面或者有人关掉自己的页面,这个过程是动态的,服务器(subject)的观察者列表随时都可以增减页面(observer)。

    如果一个按钮又会影响其他人又会被其他人影响,那他又要在被观察者列表里,又要在观察者列表里了?

    按钮跟观察者被观察者不是一个层级的概念。比如说刚才的例子,抢购按钮是会影响其他人(所有页面上显示的剩余猴机数量)也会被其他人影响(剩余猴机数量为0,抢购按钮失效)的,但是它本身只是观察者UI的一部分,服务器(subject)并不知道有这么个按钮,更不用说加到观察者列表了。subject的观察者列表里是所有调用过attach的observer实例的引用。一个observer想要影响另一个observer只能通过对subject内存储的状态的修改来进行,对于这个例子就是如果你想要让别人抢不到猴机,那你能干的就是狂按抢购按钮按到服务器上的剩余猴机数量为零为止。

    还有传送的信息具体是什么东西呢?是否打开页面的布尔值?血量经验值这些常数?由设计师自己决定吗?
    你UI上要显示啥就传啥呗。



    问题在于update()是让subject调用的方法,如果它里面包含喜加一或者续一年那这个系统太脑控了!什么!steam告诉我打折的同时直接触发了一个喜加一的事件!我控制不住我自己啊(

    不太明白“装备栏按钮就要注册进被观察者”,被观察者是属于逻辑层的东西,一般会有相关的设值接口,表示层的按钮调用相关的接口就可以


    哈哈,那这样吧,把自己传进去
    void update(Subject subject) {
        subject.takeMoneyFrom(this);
    }



    这是observer自己的选择,我并没办法阻止它233


    感谢大佬指点!烦了一下午没思路...我还是太菜了

    在C#里面似乎是可以用delegate做观察者列表?

    我想最终做到在Unity里只挂载一个脚本就实现UI框架,而不是给每个按钮分别写脚本。
    这种种情况下observer和ConcreteSubject应该都是所有活动的UI组件?

    我期望的框架是有一堆UI组件(按钮图片文字啥的)他们发送的所有信息都发给一个UI管家一样的抽象类,然后UI管家把信息传给其他需要这信息的UI组件。由管家决定把这些信息发给谁。

    但是如何让这个管家收到某个特定UI的信息后发给另一个特定的UI,我想不出来怎么做...难道要给每一个发送规则都做一套观察列表和发送列表吗?



    听起来不像是该用观察者模式的地方。

    如果只是UI组件间传递下信息,那只要在你所谓的UI管家里放一些变量,然后给它们写getter setter,让一些UI组件调用setter让另一些UI组件在每次帧刷新的时候或者setter被调用(这种实现可能比较像你说的每个组件一个观察者列表)的时候都调用一下getter就行了吧。



    感谢大佬,听了上面的讲解我也发现我好像对观察者模式的理解有点错误...

    我原以为添加和移除出观察列表是Subject做的事,听了上面的解释,原来Subject只提供方法,还是得靠ConcreteSubject自己动手...


    这段看着好像访问者模式

    LZ打算干啥我咋搞不清楚?你这些要求感觉wpf的MVVM模式就能满足啊?为何要自己造轮子?


    写多了我也看不出啥模式不模式了,反正针对接口编程一不小心就是个模式,毕竟本身就是写多了的人总结出来的


    看了这描述,愈发搞不懂。感觉lz好像把思路变成了怎么写一个UI框架而不是怎么实现功能(事件的响应)
    通常的UI框架内,程序员要关心的就是什么时候产生事件,和怎么在事件产生的时候在组件上实现对应的功能(在组件上注册对应某种事件的event handler或者event listener)。事件的传播(比如冒泡)由框架代码完成,所以你不用关心谁把消息怎么传给各个组件。
    我没玩过unity,难道unity没有事件传播?感觉可能性有点小啊。还是说lz就是想实现一个UI框架?

    顺便提个建议,lz问问题的时候最好直接把问题提出来,而不是把自己想的方案说出来,比如delegate或者observer,也许都不是解决你问题的方法,大家也不知道怎么帮。你想知道x,但是你问y,于是产生了xy问题。其实很多时候如果你问题够准确,google直接帮到你,而不是上。


    我好像的确犯了明明想做功能反倒又跑去造轮子的毛病

    是这样的,我受了这篇文章的影响
    http://www.cnblogs.com/jeason1997/p/4854606.html
    我遇到了和博主同样的问题,uity里面实现UI逻辑最简单的办法是分别给UI组件写脚本再挂在上去,但是UI组件一多就会乱,而且耦合度太高,unity的确有SendMessage,但是不是太好用,于是就想自己写个UI框架出来...



    不过看来这件事对我来说的确难度太大而且太花时间了,我看我还是直接用博主找到的那几个框架吧

相关推荐

精彩图集

一品图片网部分图片资源收集于互联网,如果侵犯了您的版权请来信告知,我们会及时处理和回复,邮件地址:
© 2021 一品图片网 版权所有 苏ICP备150288886号 | sitemap | 图片大全