最近在Ruby on Rails社区中有关于装饰器和演示者的各种各样的讨论.
这两者之间的本质区别是什么?如果有,有哪些线索告诉我哪一个使用哪一个?或者也许将两者结合使用?
为了完全将Android SDK与我的演示者类分离,我试图找出避免访问我们通常使用R的资源ID的最佳方法.我以为我可以创建一个接口来访问字符串资源之类的东西,但我仍然需要ID来引用字符串.如果我要做的事......
public class Presenter {
private MyView view = ...;
private MyResources resources = ...;
public void initializeView() {
view.setLabel(resources.getString(LABEL_RES_ID);
}
}
Run Code Online (Sandbox Code Playgroud)
我仍然需要LABEL_RES_ID,然后将其映射到R.string.label我的资源桥.这很酷,因为我可以在用其他东西进行单元测试时将其换掉,但我不想管理另一个到字符串值的映射.
如果我放弃并只使用R.string值,我的演示者将再次绑定到我的视图.那不理想?是否有一个更容易的解决方案,人们用来解决这个问题,以使他们远离主持人.我不想以超出Android提供的方式管理字符串,因为我仍然希望将它们放在布局文件中并获得国际化等的好处.我想做一个可以与这个演示者一起工作的哑单元测试无需Android SDK即可生成R.java文件.这要问太多了吗?
关于使用新架构组件的MVVM,我有一个问题,如果我的应用程序需要显示一个Dialog,其中有3个选项来自我的VM中发生的某些操作,我应该如何实现?谁负责向Activity/Fragment发送显示对话框的命令?
我想有一个仪表板来显示多个模型的摘要,我使用Presenter实现它而没有自己的数据.我使用ActiveModel类(没有数据表):
class Dashboard
attr_accessor :user_id
def initialize(id)
self.user_id = id
end
delegate :username, :password, :to => :user
delegate :address, :to => :account
delegate :friends, :to => :friendship
end
Run Code Online (Sandbox Code Playgroud)
通过代表,我希望能够打电话Dashboard.address回来Account.find_by_user_id(Dashboard.user_id).address.
如果Dashboard是一个ActiveRecord类,那么我可以声明Dashboard#belongs_to :account并且委托会自动工作(即,Account会知道它应该从Dashboard实例中的user_idequals 返回地址属性to user_id).
但Dashboard不是ActiveRecord类,所以我不能声明belongs_to.我需要另一种方法来告诉Account查找正确的记录.
有办法克服这个问题吗?(我知道我可以假装Dashboard有一个空表,或者我可以将User的实例方法重写为带参数的类方法.但这些解决方案都是黑客攻击).
谢谢.
我遇到了需要嵌套MVP模式的场景.最好用一个可视化的例子来解释:
------------------------------
| [View] |
| | |
| +----[Presenter] |
| | |
| +------[Model] |
|____________________________|
|
+----[View]
|
+----[Presenter]
|
+------[Model]
Run Code Online (Sandbox Code Playgroud)
这就是两个MVP层应该如何交互的方式.我的问题是关于两者之间的联系.我可以设想几种方法来连接这两种方式:
哪个是正确的,如果有的话?
然后是他们如何联系的问题.第2层视图是否应该引用第1层中的一个对象?互动应该纯粹基于事件吗?两者的组合(如果是这样,参考应该在哪里?)?
我很擅长使用这些类型的模式,所以任何见解都会受到赞赏.
我正在使用MVP构建一个Android应用程序,我对此模式有一个疑问.
假设我有一个用于创建新人的屏幕.此屏幕将显示一个EditText用于插入名称,另一个用于ImageView显示所选照片图片等.这将导致一个View界面,由Fragment.它将与一个Presenter接口合作,由另一个类实现.
精细.
现在我有另一个功能:用于编辑现有人的屏幕.碰巧,View此功能与创建新人的功能相同.但是,Presenter情况有所不同.它将从db中加载现有人员以使用当前数据预先填充视图开始,单击"save"时对数据库的操作将是更新而不是插入.
因此,我认为这是MVP的一个示例,其中一个View与演示者的不同实现一起工作以实现不同的用例.
你认为这是一个正确的假设,或者你觉得不同的特点应该有不同的View和Presenter接口?
另外,如果你有一个共同的View和不同的Presenters,将View是共同的实现,还是会导致两个类实现相同的接口?在实践中,我看到两个选项.
只有一个Fragment实施View.根据用户是要创建新人还是更新现有人,Fragment应该接收并使用不同的Presenter.
有两个Fragment.每个人都会实例化一个不同的Presenter.使用组合或继承来避免在两个片段之间复制代码.
在这些情况下,您认为更好的做法是什么?
谢谢.
我有2个基本接口,IViewBase(所有视图都将实现)和IPresenterBase(所有演示者都将实现):
public interface IViewBase { }
public interface IPresenterBase
{
IViewBase View { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
然后我创建了一个新的接口ILogPresenter,它派生自IPresenterBase和ILogView派生自IViewBase:
public interface ILogPresenter : IPresenterBase { }
public interface ILogView : IViewBase{ }
Run Code Online (Sandbox Code Playgroud)
当我创建一个实现ILogPresenter的类时,
public class LogPresenter: ILogPresenter
{
public ILogView View { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我收到一个错误:
'LogPresenter'没有实现接口成员'IPresenterBase.View'.'LogPresenter.View'无法实现'IPresenterBase.View',因为它没有匹配的返回类型'Views.IViewBase'.
我不能将LogPresenter.View的返回类型设置为从IViewBase派生的ILogView?我想用不同的IView实现ILogPresenter,它来自IViewBase.
问题:尽可能避免创建多个对象或多个查询.
我正在使用带有rails的Presenters作为最佳实践.
我遵循的建议说,使用"扩展ActiveSupport.Memoizable"(然后使用memoize:方法来使用它们)比使用@the_record = record ||= @record样式设置项目更好,因为有几个问题 - 假或没有得到存储,以便再次调用查询,并且memoizable更好地使用缓存(即使用它!).
但是我看到memoizable在rails 3.1中被弃用了.我在运载波下使用github并使用语句:"DEPRECATION WARNING:不推荐使用ActiveSupport :: Memoizable,并且将在以后的版本中删除,只需使用Ruby memoization模式.(来自extend at /Users/kain/.rvm/gems/ruby-1.9.3-preview1/bundler/gems/carrierwave-c4459179b0f8/lib/carrierwave/mount.rb:284" .
也许它已经解决了?谁知道?
关于最佳实践的任何建议?使用|| =语法?上述问题怎么样?

我有一个活动模型.它belongs_to :parent, :polymorphic => true.
是否Rails的使用parent.class.name,parent.model_name还是其他什么东西来填充PARENT_TYPE场?
我希望Presenter的行为与它包装的父对象相似,我需要覆盖正确的方法.
谢谢.
ruby-on-rails presenter polymorphic-associations ruby-on-rails-3
目前我有它,以便适配器可以引用其中的所有模型.但让演示者只持有模型并且适配器可以简单地引用它们是否更好?
例如:
public class Adapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
private Presenter presenter;
public Adapter(Presenter presenter){
this. presenter = presenter;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
Model m = presenter.getModels().get(position);
// bind model to view holder
}
@Override
public int getItemCount() {
return presenter.getModels().size();
}
}
Run Code Online (Sandbox Code Playgroud)
这样,当Presenter获取更多模型时,它只是getAdapter().notfiyDataSetChanged();在获取后调用.
presenter ×10
android ×4
mvp ×4
view ×2
activemodel ×1
architecture ×1
c# ×1
components ×1
decorator ×1
interface ×1
memoization ×1
model ×1
mvvm ×1
nested ×1
testing ×1
ui-patterns ×1