在VB 2013中用另一个包装对象

时间:2014-03-01 20:20:34

标签: vb.net

我正在尝试用另一个在Visual Basic 2013中包含相同超类的创建类的实例。我是VB的新手并且一直在努力解决这个问题。

这是用于Java到VB的转换..

我写的代码示例:

' Abstract product creator Class
Public MustInherit Class PizzaMaker

' Abstract Method to create a pizza
Public MustOverride Function createPizza(ByRef size As Integer, ByRef crust As String) As Pizza

Public Function orderPizza(ByRef size, ByRef crust) As Pizza
    Dim pizza As Pizza
    pizza = createPizza(size, crust)

    Return pizza
End Function
End Class

' Concrete factory Class
Public Class MargheritaMaker
Inherits PizzaMaker

' Override abstrat method in superclass
Public Overrides Function createPizza(ByRef size As Integer, ByRef crust As String) As Pizza
    Dim pizza As New MargheritaPizza(size, crust)

    Return pizza
End Function

End Class

' Abstract component product Class
Public MustInherit Class Pizza
' Consatant variables used for pizza size
Public Const SMALL As Integer = 1
Public Const MEDIUM As Int16 = 2
Public Const LARGE As Int16 = 3
Public Const EXTRA_LARGE As Int16 = 4

' Crust type of pizza
Private crustType As String

' Size of the pizza
Private size As Int16

' Description of the pizza
Public description As String = "Pizza"

' Abstract method to return the cost of the pizza
Public MustOverride Function getCost() As Double

' Returns size description
Public Function getSizeDescription() As String
    Dim desc As String

    ' Determin pizza size and return String description
    If (size = 1) Then
        desc = "Small"
    ElseIf (size = 2) Then
        desc = "Medium"
    ElseIf (size = 3) Then
        desc = "Large"
    Else
        desc = "Extra Large"
    End If

    Return desc
End Function

Public Function getCrust() As String
    Return crustType
End Function

' Sets the pizza crust type
Public Sub setCrust(ByRef crust)
    crustType = crust
End Sub

' Returns the pizza size
Public Function getSize() As Integer
    Return size
End Function

' Set the size of our Pizza
Public Sub setSize(ByVal i)
    size = i
End Sub

' Returns the String description of the pizza
Public Function getDescription() As String
    Return getSizeDescription() + " " + crustType + " " + description
End Function


End Class

' Concrete component product Class defining a Margherita Pizza
Public Class MargheritaPizza
Inherits Pizza
'Dim cost
' Constructor set's the Pizza size, crust type & description
Sub New(ByRef size As Integer, ByRef crust As String)
    setSize(size)
    setCrust(crust)
    description = "Margherita Pizza"
End Sub

' Returns the Pizza base cost based on it's size
Public Overrides Function getCost() As Double
    Dim cost As Double
    If (getSize() = Pizza.SMALL) Then
        'Console.Write("in if" & vbNewLine)
        cost = 9.5
    ElseIf (getSize() = Pizza.MEDIUM) Then
        cost = 10.5
    ElseIf (getSize() = Pizza.LARGE) Then
        cost = 11.5
    ElseIf (getSize() = Pizza.EXTRA_LARGE) Then
        cost = 12.5
    End If
    'Console.Write("in if" * vbNewLine)
    Return cost
End Function

End Class

' Abstract component product decorator Class
Public MustInherit Class PizzaDecorator
Inherits Pizza

' Abstract method that returns decorator description
Public MustOverride Overloads Function getDescription()

End Class

' Concrete component product decorator Class (used as Object wrapper)
Public Class Cheese
Inherits PizzaDecorator

Dim pizza ' As Pizza

' Check that the construtor paramaters are correct!!! Also check scope of variables!!!
Sub New(ByVal pizz)
    pizza = pizz
    'pizza.setSize(pizz.getSize())
    'pizza.setCrust(pizz.getCrust())
End Sub

' Returns cost of product by delegating call to wrapped objects
Public Overrides Function getCost() As Double
    Dim cost ' As Double = pizza.getCost()

    If (pizza.getSize() = pizza.SMALL) Then
        Console.Write(" In cheese pizza = SMALL" & vbNewLine)
        cost += 0.1
    ElseIf (pizza.getSize() = pizza.MEDIUM) Then
        cost += 0.2
    ElseIf (pizza.getSize() = pizza.LARGE) Then
        cost += 0.3
    ElseIf (pizza.getSize() = pizza.EXTRA_LARGE) Then
        cost += 0.4
    End If
    Console.Write(" Pizza size = " + pizza.getSize().ToString & vbNewLine)
    Console.Write(" in end if" & vbNewLine)
    Return cost + pizza.getCost()
End Function

Public Overrides Function getDescription() As Object
    Return pizza.getDescription() + ", Extra Cheese"
End Function

End Class

然后用这个进行测试:

Public Class TestForm

Public margheritaM ' As MargheritaMaker
Public pizza ' As Pizza

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    'Dim m As New MargheritaMaker()
    'Dim pizza
    'Dim margheritaM As New MargheritaMaker()
    margheritaM = New MargheritaMaker()
    pizza = margheritaM.createPizza(1, "Deep Pan")

    MargheritaBox.AppendText(pizza.getDescription() & vbNewLine)
End Sub

Private Sub CheeseButton_Click(sender As Object, e As EventArgs) Handles CheeseButton.Click
    'pizza As New Cheese(pizza)
    pizza = New Cheese(pizza)
    MargheritaBox.AppendText(pizza.getDescription() & vbNewLine)
End Sub

Private Sub CostButton_Click(sender As Object, e As EventArgs) Handles CostButton.Click
    MargheritaBox.AppendText(pizza.getCost() & vbNewLine)
End Sub

Private Sub PepperoniButton_Click(sender As Object, e As EventArgs) Handles PepperoniButton.Click
    pizza = New Pepperoni(pizza)
    MargheritaBox.AppendText(pizza.getDescription() & vbNewLine)
End Sub
End Class

我假设我可以使用Button1点击创建一个MargheritaPizza对象,并通过它的工厂方法createPizza

将比萨饼对象分配给比萨饼

然后在cheeseButton上点击我可以包裹用披萨=新奶酪(披萨)创建的披萨对象!奶酪类包含比萨饼的额外顶部。我以为我可以在原始的披萨对象上调用成本,它将通过包裹的对象委托成本?与装饰模式一样。

以下输出的一些屏幕截图:

enter image description here

在这里我点击创建披萨然后计算成本然后额外的奶酪最终计算成本,一切似乎都很好!

enter image description here

这次我还点了额外的奶酪并计算成本,但成本并没有正确地委托给对象!

enter image description here

enter image description here

在这里,我添加了几个额外的奶酪,并在控制台窗口显示一些输出进行测试,控制台窗口显示每次包装对象时披萨的大小,并显示披萨大小为0,除了最内层包装......我做错了什么?

我的第一语言是Java,过去对这种技术没有任何问题,但是对于VB 2013是新手,并且在这里感谢一些帮助..

欢迎所有建设性意见。

非常感谢

请忽略在测试过程中注释掉的代码

1 个答案:

答案 0 :(得分:2)

<强>包装

首先,这只是我的意见,当您处理wrapping课程时,会使用术语NotInheritable

示例:

Public Class String2

    Public Sub New(s As String)
        Me.s = s
    End Sub

    Default Public ReadOnly Property Chars(index As Integer) As Char
        Get
            Return Me.s.Chars(index)
        End Get
    End Property

    Public ReadOnly Property Length() As Integer
        Get
            Return s.Length
        End Get
    End Property

    Private ReadOnly s As String

End Class

基础课程

其次,你过度复杂了。以下代码被剥离以使其更具可读性。请注意,这不是最终解决方案。

首先定义CrustSize枚举。

Public Enum PizzaCrust As Integer
    [Default] = 0
    DeepPan = 1
End Enum

Public Enum PizzaSize As Integer
    S = 0
    M = 1
    L = 2
    XL = 3
End Enum

您只需要两个基类PizzaExtra

Public MustInherit Class Pizza

    Public Property Crust() As PizzaCrust

    MustOverride ReadOnly Property Description() As String

    Public ReadOnly Property Extras() As List(Of Extra)

    MustOverride ReadOnly Property Name() As String

    Public Property Size() As PizzaSize

    Public Function CalculateCost() As Decimal
        Dim value As Decimal = Me.GetBaseCost(Me.Size)
        For Each extr As Extra In Me.Extras
            value += extr.Cost
        Next
        Return value
    End Function

    Protected MustOverride Function GetBaseCost(size As PizzaSize) As Decimal

End Class

Public MustInherit Class Extra

    Public MustOverride ReadOnly Property Name() As String
    Public MustOverride ReadOnly Property Description() As String
    Public MustOverride ReadOnly Property Cost() As Decimal

End Class

<强>比萨饼

创建一个名为Pizzas的命名空间,并将所有比萨放在这里。

Namespace Pizzas

    Public Class Margarita
        Inherits Pizza

        Public Overrides ReadOnly Property Description() As String

        Public Overrides ReadOnly Property Name() As String

        Protected Overrides Function GetBaseCost(size As PizzaSize) As Decimal
            Select Case size
                Case PizzaSize.S
                    Return 10
                Case PizzaSize.M
                    Return 15
                Case PizzaSize.L
                    Return 20
                Case PizzaSize.XL
                    Return 30
                Case Else
                    Return 0
            End Select
        End Function

    End Class

    Public Class Quattro
        Inherits Pizza

        Public Overrides ReadOnly Property Description() As String
        Public Overrides ReadOnly Property Name() As String
        Protected Overrides Function GetBaseCost(size As PizzaSize) As Decimal

    End Class

End Namespace

<强>附加功能

最后,创建一个名为Extras的命名空间,并将所有附加内容放在此处。

Namespace Extras

    Public Class Cheese
        Inherits Extra

        Public Overrides ReadOnly Property Cost() As Decimal
        Public Overrides ReadOnly Property Description() As String
        Public Overrides ReadOnly Property Name() As String

    End Class

    Public Class Ham
        Inherits Extra

        Public Overrides ReadOnly Property Cost() As Decimal
        Public Overrides ReadOnly Property Description() As String
        Public Overrides ReadOnly Property Name() As String

    End Class

    Public Class Pineapple
        Inherits Extra

        Public Overrides ReadOnly Property Cost() As Decimal
        Public Overrides ReadOnly Property Description() As String
        Public Overrides ReadOnly Property Name() As String

    End Class

End Namespace

<强>用法

现在,要创建一个新的Margarita披萨,可以这样做:

Dim pizza As New Pizzas.Margarita()

pizza.Size = PizzaSize.L
pizza.Crust = PizzaCrust.DeepPan
pizza.Extras.Add(New Extras.Ham())
pizza.Extras.Add(New Extras.Cheese())