【问题标题】:MVVM logic architecture [closed]MVVM 逻辑架构
【发布时间】:2018-03-07 10:12:50
【问题描述】:

我在为我的 MVVM 项目设计良好的架构时遇到了问题。 我想出了类似下面的东西,请阅读并告诉我这是错误的方法还是好的: 我会有一些界面:

 public interface ISomeStrategy
        {
            void LoadData();

            void Search(string text);

            IList<SomeObject> SomeObjectsList { get; set; }
        }

还有一个实现这个接口的类:

 public class FirstStrategy: INotifyPropertyChanged, ISomeStrategy
    {
        public CompositePayslipItem(IDataService dataService)
        {
         DataService = dataService;
        }
     private IDataService DataService;
     public IList<SomeObject> SomeObjectList{get; set;}

     public async void LoadData()
     {
       SomeObjectList =await DataService.GetAll();
     }

     public async void Search(string text)
     {
       SomeObjectList =await DataService.GetByKey(text);
     }

}

和 ViewModel:

public void SomeViewModel
{
   public SomeViewModel(IDataService dataService)
   {
    Strategy = new FirstStrategy(dataService);
    Strategy.LoadData();
   }
   public ISomeStrategy Strategy {get; set;}
   private Command<string> searchCommand;

   public Command<string>  SearchCommand => searchCommand?? (searchCommand= new Command(ExecuteSearchCommandAsync));


  private async void ExecuteSearchCommandAsync(string text)
  {
    Strategy.Search(text);
  }
}

如您所见,所有逻辑都将位于“策略”类中,这些类将通过 ViewModel 绑定到 View。它给了我什么?我可以在运行时动态更改实现。例如,如果我有一个 Employee 和 Manager,其中搜索和获取数据的逻辑不同,我可以只实现另一个类并更改属性 ISomeStrategy Strategy 而无需编辑 Employee 的现有代码(在很多方法中没有额外的 if)。 不幸的是,它存在一些问题:

  1. 所有绑定(命令除外)都将在 *Factory 类中,这可能会产生误导
  2. 在大多数情况下,一台 VM 将有一个策略实现,因此会有大量代码无用。另一方面,将来客户可以要求另一个角色(实现),并且会更容易(只需实现另一个类 - 无需编辑旧代码)。

你怎么看?或者,也许您使用其他模式进行业务逻辑?

编辑: Xaml 部分:

<ContentPage
    x:Class="Test.SomePage"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
                <StackLayout>
                    <SearchBar
                        HeightRequest="50"
                        SearchCommand="{Binding SearchCommand}" />
                    <ListView
                        x:Name="formatsList"
                        Margin="0"
                        ItemsSource="{Binding Strategy.SomeObjectList}">
                </StackLayout>
</ContentPage>

【问题讨论】:

  • 你能用 XAML/Binding 部分更新你的问题吗?
  • 我添加了 XAML 部分
  • 啊,我明白您对宝贵评论的看法。在这种情况下,我不太理解您的第一个问题:所有绑定(命令除外)都将在 *Factory 类中,这可能会产生误导
  • 理论上,当他在 ViewModel 中看到命令正常但其他绑定绑定到一个大对象时,他可能会感到困惑。仅此而已。
  • 这个帖子是关于如果这个解决方案没有违反“规则”或者对未来可能加入项目的开发人员来说过于误导

标签: c# mvvm xamarin.forms


【解决方案1】:

为了帮助你,希望我能理解你的问题:

所有绑定(命令除外)都将在 Factory 类中,这可能会产生误导:我假设您绑定到视图模型而不是直接绑定到策略。

您应该绑定到视图模型,从那里与您的策略进行交互。否则你正在混合你的图层。

更新

据我所知,这不是问题,典型的程序员应该能够立即发现它。

如果 SomeObject 是来自业务层的一种模型,那么您正在打破层分离论点。未来的开发人员可能看不到例如的后果。重命名 SomeObject 中的属性。如果 SomeObject 是视图模型的一部分,那么您是安全的。请注意;我倾向于过度设计事物;-)

因此,您可以考虑为SomeObject 创建一个专用视图模型,并使用automapper 映射到业务相关模型。

在大多数情况下,一台虚拟机将有一个策略实现,因此会有大量代码无用。另一方面,将来客户可以要求另一个角色(实现),并且会更容易(只需实现另一个类 - 无需编辑旧代码)。

我在这里找不到问题或问题。作为一般规则,使用设计模式需要在前期付出更多努力,以帮助您应对日后不断变化的需求。

更多信息;看到这个(我的 XD)帖子:ViewModels in MVC / MVVM / Seperation of layers- best practices?


关于您的代码的更多建议,免责声明:有些是基于意见的:


在构造函数中加载数据是不好的做法。

典型的加载操作应该是非阻塞的并且async 以保持 UI 响应。

public SomeViewModel(IDataService dataService)
{
   //load data in constructor issue
   Strategy.LoadData();
}

如果为 null,则您正在创建一个新对象。如果多个线程正在调用此属性,则可能会发生争用情况。考虑lock(可能使用显式设置方法),或在构造函数中初始化。 我认为这在您的代码中并不是真正的问题,因为您提到了 Factory,仍然:

调用new 使用具体,而不是接口。使用工厂或 IoC(带有解析器,即工厂)来解决此问题。

public SomeViewModel(IDataService dataService)
{
    //`new` issue
    Strategy = new FirstStrategy(dataService);
}


不要使用async void 首选async Task

async/await - when to return a Task vs void?

//use Task if possible
private async void ExecuteSearchCommandAsync(string text)

可能的(棘手的)竞争条件

在这一行:

public Command<string>  SearchCommand => 
   searchCommand?? (searchCommand= new Command(ExecuteSearchCommandAsync));

【讨论】:

  • 感谢您的回答。从技术上讲,我仍将绑定在 ViewModel 中,而是将 List 直接放入 VM 中,我将其放入 Strategy 中。然后在我看来,{Binding SomeObjectList} 我将拥有 {Binding Strategy.SomeObjectList}
  • 关于免责声明:我只是快速编写这段代码来表达想法。我知道您的建议,以及此代码中的一些不良做法:)
  • @straiser:啊,很好。保持良好的设计模式工作! :-)
猜你喜欢
  • 1970-01-01
  • 2016-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-29
  • 1970-01-01
  • 2014-06-01
  • 2013-02-12
相关资源
最近更新 更多