VB.NET_委派的語法(Delegate優點使用時機)研究_Low coupling_高內聚_低耦合

委派在VB.NET  和  C#中語法的使用示例


委派就是  Methods 或  Function 的 Pointer

 delegate小範本


VB.NET  視窗應用程式


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
Public Class Form1
    Public Delegate Function PointertoAddFunction(a As Integer, b As Integer) As Integer
    Public Sub New()

        ' 設計工具需要此呼叫。
        InitializeComponent()

        ' 在 InitializeComponent() 呼叫之後加入所有初始設定。

    End Sub
    Public Function Add(x As Integer, y As Integer) As Integer
        Return x + y
    End Function

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim addPtr As PointertoAddFunction = Nothing
        addPtr = AddressOf Me.Add
        MessageBox.Show(addPtr.Invoke(30, 25).ToString())
    End Sub
End Class

這裡如果是熟悉  C#的朋友ˋ也可以透過
線上的  Code Converter : http://converter.telerik.com/
去做C# 和VB之間的語法轉換

C#版


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace PointerOfMethods_App_CS
{
    public partial class Form1 : Form
    {
        public delegate int PointertoAddFunction(int a, int b);

        public Form1()
        {
            InitializeComponent();
        }

        public int Add(int x, int y)
        {
            return x + y;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            PointertoAddFunction addPtr = null;
            addPtr = this.Add;
            MessageBox.Show(addPtr.Invoke(30, 25).ToString());
        }
    }
}


OK那這裡跟大家詳述當中歷經的幾個細部運作流程


Step1. Declare  delegate
Step2. Create delegate reference
Step3. Point the reference to Add Method
Step4. Invoke the method through delegate object







假設我今天創建一個Class去實踐一個整數四則運算的物件

好降低寫重複Code的問題

原程式碼



================================================================

第一階段. 改寫為Class


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
Public Class CalculateHelper
    Public Function Add(a As Integer, b As Integer) As Integer
        Return a + b
    End Function
    Public Function Subtract(a As Integer, b As Integer) As Integer
        Return a - b
    End Function
    Public Function Mul(a As Integer, b As Integer) As Integer
        Return a * b
    End Function
    Public Function Div(a As Integer, b As Integer) As Integer
        Return a / b
    End Function
End Class










這裡你會發現會造成  Heavy coupling (高耦合度)的現象
(物件中的方法和你Client端程式碼有密切的連動性)


每當你的Class中又定義了新方法
你想調用時就必須在主程式外部去跟著牽動配合其設計
每當你去寫針對四則運算這方面的程式時
就必須一直不停重複寫 clc.XXX  .....  去掉用當中所定義的方法
 clc.Add  .....
 clc.Subtract  .....
 clc.Multi .....
 clc.Add  .....
 clc.Div  .....
 clc.Div  .....
 clc.Subtract  .....

是不是很煩....~~~~~~~~
而且當此Class定義的方法有愈來愈多時就會不容易去記
各自方法名稱叫捨麼而沿用
而且每當你Class又擴充了額外新的  Public 方法要到
外部去調用時則可能要更著去照寫


這樣實際上還是沒有提升程式碼的重用性
也不易維護


理想的物件導向程式設計我們希望能實踐
高內聚,低耦合
high cohesion、low coupling

用分子結構來圖樣表示就是如下的概念



物件的程式碼
應該要有很高的比率只和物件內其他有關的程式碼有關聯,
而對外部的程式碼(物件或元件等)的關聯度要愈低愈好
 (最佳的狀態是零耦合)。


目的是讓物件可以獨立發展
而無須依賴外部的任何程式碼
(可以防範  牽一髮動全身)

物件本身可以在不影響其他程式的情況下自由的修改與變化
而外部程式的任何修改也不會影響到物件本身的功能與運作。


======================================================================






【程式碼】

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
Public Class Form1
    Public Sub New()

        ' 設計工具需要此呼叫。
        InitializeComponent()

        ' 在 InitializeComponent() 呼叫之後加入所有初始設定。

    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim objMath As CalculateHelper = New CalculateHelper
        Dim OperationNum As Integer = Convert.ToInt16(TextBox3.Text)
        Dim num1 As Integer = Convert.ToInt32(TextBox1.Text)
        Dim num2 As Integer = Convert.ToInt32(TextBox2.Text)
        Dim res As Integer = objMath.getPointer(OperationNum).Invoke(num1, num2)
        lblResult.Text = res.ToString()
    End Sub
End Class


新修改後的CalculateHelper   Class


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
Public Class CalculateHelper
    Public Delegate Function PointerCalculate(x As Integer, y As Integer) As Integer

    Public Function getPointer(intOperation As Integer) As PointerCalculate
        Dim objPtr As PointerCalculate = Nothing

        If intOperation = 1 Then
            objPtr = AddressOf Me.Add
        ElseIf intOperation = 2 Then
            objPtr = AddressOf Me.Subtract
        ElseIf intOperation = 3 Then
            objPtr = AddressOf Me.Mul
        ElseIf intOperation = 4 Then
            objPtr = AddressOf Me.Div
        End If
        Return objPtr
    End Function

    Private Function Add(a As Integer, b As Integer) As Integer
        Return a + b
    End Function
    Private Function Subtract(a As Integer, b As Integer) As Integer
        Return a - b
    End Function
    Private Function Mul(a As Integer, b As Integer) As Integer
        Return a * b
    End Function
    Private Function Div(a As Integer, b As Integer) As Integer
        Return a / b
    End Function

End Class






這裡我透過定義1~4數值去讓使用者輸入
明確對應的四則運算種類
1  --> Add
2 --> Subtract
3 --> Multi
4 --> Divide

於後端程式中
會先透過建立好的 objMath  委派
去指向當前使用者是輸入何值間接帶入兩參數
去做對應運算

這樣的好處是不需像剛才寫太多程式
且我在修改後的類別Code中也將  四種運算方法定義改為Private修飾
就是要避免像一開始又在外部   物件實體.Method名

物件實體.Method名
物件實體.Method名
物件實體.Method名
物件實體.Method名
物件實體.Method名
.......N行Code







這次分享到這邊結束喔~~~~
學習
高內聚低耦合層次的設計模式
(PS:  除法的定義  其實不太嚴謹要記得判斷分母為0情形的錯誤例外排除)

學習參考:

中鳥階段-高內聚,低耦合
https://ithelp.ithome.com.tw/articles/10080201




留言

這個網誌中的熱門文章

何謂淨重(Net Weight)、皮重(Tare Weight)與毛重(Gross Weight)

Architecture(架構) 和 Framework(框架) 有何不同?_軟體設計前的事前規劃的藍圖概念

經得起原始碼資安弱點掃描的程式設計習慣培養(五)_Missing HSTS Header