首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 實作 MVC 模式:ACME 車輛控制系統完整案例

     編輯:關於C#

前言

MVC (Model-View-Controller) 將業務邏輯、使用者介面、控制流程分離,降低耦合、提升可測試性與重用性。本文透過一個「ACME 車輛控制系統」完整案例,示範如何用介面定義契約、觀察者模式同步 Model/View,並輕鬆擴充新車種與新控制器。

領域模型與列舉


public enum AbsoluteDirection { North, East, South, West }
public enum RelativeDirection { Right, Left, Back }

三大介面契約


// Model:車輛狀態與行為
public interface IVehicleModel
{
    string Name { get; set; }
    int Speed { get; set; }
    int MaxSpeed { get; }
    int MaxTurnSpeed { get; }
    int MaxReverseSpeed { get; }
    AbsoluteDirection Direction { get; set; }
    void Accelerate(int amount);
    void Decelerate(int amount);
    void Turn(RelativeDirection dir);
}

// View:介面操作與顯示
public interface IVehicleView
{
    void EnableAcceleration(); void DisableAcceleration();
    void EnableDeceleration(); void DisableDeceleration();
    void EnableTurning(); void DisableTurning();
    void Update(IVehicleModel model); // 觀察者更新介面
}

// Controller:協調 Model 與 View
public interface IVehicleControl
{
    void RequestAccelerate(int amount);
    void RequestDecelerate(int amount);
    void RequestTurn(RelativeDirection dir);
    void SetModel(IVehicleModel model);
    void SetView(IVehicleView view);
}

Controller 實作:邏輯中樞


public class AutomobileControl : IVehicleControl
{
    private IVehicleModel Model;
    private IVehicleView View;

    public AutomobileControl() { }
    public AutomobileControl(IVehicleModel m, IVehicleView v) { Model = m; View = v; }

    public void SetModel(IVehicleModel m) => Model = m;
    public void SetView(IVehicleView v) => View = v;

    public void RequestAccelerate(int amount)
    {
        if (Model != null) { Model.Accelerate(amount); UpdateView(); }
    }
    public void RequestDecelerate(int amount)
    {
        if (Model != null) { Model.Decelerate(amount); UpdateView(); }
    }
    public void RequestTurn(RelativeDirection dir)
    {
        if (Model != null) { Model.Turn(dir); UpdateView(); }
    }

    private void UpdateView()
    {
        if (View == null) return;
        // 依速度啟用/停用按鈕
        if (Model.Speed >= Model.MaxSpeed) { View.DisableAcceleration(); View.EnableDeceleration(); }
        else if (Model.Speed <= Model.MaxReverseSpeed) { View.DisableDeceleration(); View.EnableAcceleration(); }
        else { View.EnableAcceleration(); View.EnableDeceleration(); }

        if (Model.Speed >= Model.MaxTurnSpeed) View.DisableTurning();
        else View.EnableTurning();

        View.Update(Model); // 觸發 View 重繪
    }
}

Model 基底類別與具體車種


public abstract class Automobile : IVehicleModel
{
    public string Name { get; set; }
    public int Speed { get; set; }
    public int MaxSpeed { get; }
    public int MaxTurnSpeed { get; }
    public int MaxReverseSpeed { get; }
    public AbsoluteDirection Direction { get; set; }

    protected Automobile(int maxSpeed, int maxTurn, int maxReverse, string name)
    {
        MaxSpeed = maxSpeed; MaxTurnSpeed = maxTurn; MaxReverseSpeed = maxReverse; Name = name;
    }

    public virtual void Accelerate(int amount) => Speed += amount;
    public virtual void Decelerate(int amount) => Speed -= amount;
    public virtual void Turn(RelativeDirection dir)
    {
        // 簡化:右轉+1、左轉-1、掉頭+2
        int turn = (dir == RelativeDirection.Right) ? 1 : (dir == RelativeDirection.Left) ? -1 : 2;
        Direction = (AbsoluteDirection)(((int)Direction + turn + 4) % 4);
    }
}

// 具體車種只需指定參數
public class ACME2000SportsCar : Automobile
{
    public ACME2000SportsCar(string name) : base(250, 40, -20, name) { }
    public ACME2000SportsCar(string name, int maxS, int maxT, int maxR) : base(maxS, maxT, maxR, name) { }
}

public class ACME2000Truck : Automobile
{
    public ACME2000Truck(string name) : base(80, 25, -12, name) { }
}

View 實作:WinForms UserControl


public partial class AutoView : UserControl, IVehicleView
{
    private IVehicleControl Control = new AutomobileControl();
    private IVehicleModel Model = new ACME2000SportsCar("Speedy");

    public AutoView() { InitializeComponent(); WireUp(Control, Model); }

    public void WireUp(IVehicleControl ctrl, IVehicleModel mdl)
    {
        if (Model != null) Model.RemoveObserver(this); // 假設 Model 實作觀察者
        Model = mdl; Control = ctrl;
        Control.SetModel(Model); Control.SetView(this);
        Model.AddObserver(this);
    }

    // 按鈕事件 → Controller
    private void btnAccelerate_Click(object sender, EventArgs e) => Control.RequestAccelerate(int.Parse(txtAmount.Text));
    private void btnDecelerate_Click(object sender, EventArgs e) => Control.RequestDecelerate(int.Parse(txtAmount.Text));
    private void btnLeft_Click(object sender, EventArgs e) => Control.RequestTurn(RelativeDirection.Left);
    private void btnRight_Click(object sender, EventArgs e) => Control.RequestTurn(RelativeDirection.Right);

    // 介面更新
    public void UpdateInterface(IVehicleModel auto)
    {
        lblStatus.Text = $"{auto.Name} heading {auto.Direction} at speed: {auto.Speed}";
        pBar.Value = (auto.Speed > 0) ? auto.Speed * 100 / auto.MaxSpeed : auto.Speed * 100 / auto.MaxReverseSpeed;
    }

    // IVehicleView 介面實作
    public void EnableAcceleration() => btnAccelerate.Enabled = true;
    public void DisableAcceleration() => btnAccelerate.Enabled = false;
    public void EnableDeceleration() => btnDecelerate.Enabled = true;
    public void DisableDeceleration() => btnDecelerate.Enabled = false;
    public void EnableTurning() => btnLeft.Enabled = btnRight.Enabled = true;
    public void DisableTurning() => btnLeft.Enabled = btnRight.Enabled = false;
    public void Update(IVehicleModel m) => UpdateInterface(m);
}

擴充展示:新車種、新控制器、Web 介面

  • 新車種:新增 ACME2000Truck,WireUp(new AutomobileControl(), new ACME2000Truck("Heavy")) 即可。
  • 新控制器:SlowPokeControl 繼承 AutomobileControl,覆寫 RequestAccelerate/Decelerate 限制最大加減速 5,WireUp(new SlowPokeControl(), new ACME2000Truck(...))。
  • Web 介面:建立 ASP.NET WebForm/UserControl 實作 IVehicleView,同樣可與既有 Model/Controller 搭配。

結語

此案例展示 MVC 核心價值:介面導向程式設計 定義契約,觀察者模式 解耦 Model/View 同步,依賴注入 (WireUp) 組合具體實作。擴充新車種、新控制邏輯、新介面技術均無需修改既有程式碼,完美符合開放封閉原則 (OCP)。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved