我對 OOP 和 C# 比較陌生,想問一下讓兩個類相互使用方法的“最佳實踐”是什么。
示例:我有一個“主類”,它實體化一個管理與觸摸顯示幕通信的類“UI”和一個與外部傳感器通信的類“傳感器”。
當有人在 Display 上按下按鈕時,UI 類中會觸發一個事件。作為反應,需要呼叫傳感器類的“ReadSensor”方法。(反之,“SensorDataCallback”需要將內容寫入顯示幕)。
現在在 C 中,我會將兩個類物件都設為全域,但在 C# 中沒有選擇。我嘗試將方法添加到類中,該類接受對相應其他類實體的參考并存盤它們,但這似乎不是最好的方法。我的另一種方法是使兩個類都靜態,因為只有一個顯示幕和一個傳感器,但這也不是我猜的最好方法。
草圖
任何人都可以給我一個提示嗎?
uj5u.com熱心網友回復:
我不建議將兩個類如此緊密地聯系在一起,事實上你最終會得到回圈參考。
盡量保持你的類是自包含的,這樣就可以保持一定的關注點分離。
因此 Sensor 類只處理檢索傳感器資料和發出新值通知(如果要定期或異步自動讀取值)。
您的 UI 類只處理顯示和對用戶輸入的反應。
您的 Main 類充當兩者之間的資料處理程式。
UI 顯示代碼通知主類用戶請求資訊;Main 類處理此問題并觸發 Sensor 類以檢索新的傳感器值。
Sensor 類將新的傳感器值通知/傳遞給主類;然后主類通知 UI 有一個新值可用。
因此傳感器不需要知道顯示幕,顯示幕也不需要知道傳感器。
以上符合當前為具有用戶界面的 C# 程式使用 MVVM(模型-視圖-視圖模型)結構的“最佳實踐”。在這種情況下,您的 View 是顯示幕,ViewModel 是您的主類,Model 是您的傳感器類。
在這種安排中,View 類使用資料系結從 ViewModel 中檢索傳感器值。View 將在按下 ViewModel 回應的按鈕時引發一個事件(可能系結到一個命令),觸發它從傳感器請求更新資料。傳感器將該資料提供給 ViewModel,當它更新其傳感器值屬性時,會引發屬性更改通知,觸發 View 進行更新。
這是 WPF 應用程式中 MVVM 的一個非常基本的示例。我沒有將整個專案只包括基本類:
查看:(MainWindow.xaml)
<Window x:Class="SimpleWPF.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:SimpleWPF"
mc:Ignorable="d"
Title="MainWindow" Height="204.673" Width="219.626">
<Window.DataContext>
<local:MainViewModel/>
</Window.DataContext>
<Grid>
<TextBox x:Name="textBox" Text="{Binding SensorValue, Mode=OneWay }" HorizontalAlignment="Left" Height="23" Margin="38,47,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/>
<Button x:Name="button" Command="{Binding ReadSensorCommand}" Content="Read" HorizontalAlignment="Left" Margin="62,94,0,0" VerticalAlignment="Top" Width="75"/>
</Grid>
帶有輔助類的 ViewModel (MainViewMode.cs):
public class MainViewModel :INotifyPropertyChanged
{
public MainViewModel()
{
ReadSensorCommand = new RelayCommand(new Action<object>(ReadFreshSensorData));
}
private ICommand _ReadSensorCommand;
private int _sensorValue;
private readonly SensorModel _sensor = new SensorModel();
private void ReadFreshSensorData(object o)
{
SensorValue =_sensor.ReadSensor();
}
public int SensorValue
{
get=>_sensorValue;
private set
{
_sensorValue = value;
OnPropertyChanged(nameof(SensorValue));
}
}
public ICommand ReadSensorCommand
{
get => _ReadSensorCommand;
set => _ReadSensorCommand = value;
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
class RelayCommand : ICommand
{
private readonly Action<object> _action;
public RelayCommand(Action<object> action)
{
_action = action;
}
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
_action(parameter ?? "");
}
}
最后是模型(SensorModel.cs)
public class SensorModel
{
private Random _rnd = new Random();
public int ReadSensor()
{
return _rnd.Next(1000);
}
}
誠然,這僅演示了用戶觸發從傳感器讀取,但 SensorModel 可以在其介面上具有事件屬性,而 MainViewModel 可以具有處理程式。然后 SensorModel 可以呼叫該事件將一個值傳遞給 MainViewModel,然后 MainViewModel 將從事件處理程式中更新 SensorValue。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/429028.html
上一篇:不要以為我得到.clone()
下一篇:Python-描述符-損壞的類
