none
工厂化模式的一个问题,谢谢 RRS feed

  • 问题

  • 想问一个工厂模式的问题。

    想建立一个主类包含一个从类,主从关系就是从类是主类的一个属性。这一步基本解决了。

    下边就是想用工厂化方法实例化主类(当然从类也就实例化了)。以下是程序段。

    Public Class Child
        Private _ChildName As String
        Public Property ChildName() As String
            Get
                Return _ChildName
            End Get
            Set(ByVal value As String)
                _ChildName = value
            End Set
        End Property
    End Class
    
    
    Public Class Master
        Private _Child As Child
        Public Property Child() As Child
            Get
                Return _Child
            End Get
            Set(ByVal value As Child)
                _Child = value
            End Set
        End Property
        Public Sub New()
    
        End Sub
        Public Sub New(ByRef cld As Child)
            _Child = cld
        End Sub
    End Class
    
    
    Public Class Factory
        Public Shared Function SetMaster() As Master
            Dim _Child As New Child
            Dim _Master As New Master(_Child)
            Return _Master
        End Function
    
        Public Shared Function SetMaster(ByVal _Cld As Child, ByRef _Mst As Master) As Master
            _Mst = New Master(_Cld)
            Return _Mst
        End Function
    End Class
    
    
    Public Class Form1
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Dim _Child As New Child
            Dim _Master As New Master(_Child)
            _Master.Child.ChildName = "Loaded"
            MsgBox(_Master.Child.ChildName.ToString)
            'MsgBox(_Child.ChildName.ToString)
        End Sub
    
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Dim _MasterButton As Master
            _MasterButton = Factory.SetMaster()
            _MasterButton.Child.ChildName = "Button Clicked"
            MsgBox(_MasterButton.Child.ChildName.ToString)
        End Sub
    
        Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
            Dim _ChildButton2 As New Child
            Dim _MasterButton2 As New Master
            _MasterButton2 = Factory.SetMaster(_ChildButton2, _MasterButton2)
            _MasterButton2.Child.ChildName = "Button2 Clicked"
            MsgBox(_MasterButton2.Child.ChildName.ToString)
        End Sub
    End Class
    


    我的问题是,主类,从类都需要进行声明才能引用。但我不太清楚声明应该放在那里。 是放在工厂里,还是放在其他的什么地方 (调用工厂以前)。这样的做法有没有什么问题?

    我能发现的就是修改从类(Child)中参数的路径有所不同。vb默认的方法有两条路,Button1的方法只能通过声明的_MasterButton,Button2也可以有两条路,不知道这样的理解是否正确。还有是不是通过主类来接触从类参数的方法是好方法?

    我可以说比较盲目,并不清楚什么时间用什么样的声明。本人只能看懂vb代码。

    先谢过。
    2010年3月7日 9:59

答案

  • 你好!

    你这个非常别扭,下面的方式更好一些。

    Public Class Child
        Private _ChildName As String
        Public Property ChildName() As String
            Get
                Return _ChildName
            End Get
            Set(ByVal value As String)
                _ChildName = value
            End Set
        End Property
    End Class
    Public Class Master
        Private _Child As Child
        Public Property Child() As Child
            Get
                Return _Child
            End Get
            Set(ByVal value As Child)
                _Child = value
            End Set
        End Property
       
        Public Sub New()
                '默认构造一个 Child
            _Child = New Child()
        End Sub
    End Class
    Public Class Factory
        Public Shared Function CrateMaster() As Master
            Return New Master()
        End Function
    End Class
    Public Class Form1
        Private Sub Demo()
            Dim _Master As Master = Factory.CrateMaster()
               
                'Child _Child = new Child();
                '_Child.ChildName = "ChildName";
                '_Master.Child = _Child;
            _Master.Child.ChildName = "ChildName"
        End Sub
    End Class


    知识改变命运,奋斗成就人生!
    2010年3月8日 5:11
    版主
  • 第二种要简洁一些,另外需要注意的是 Master 中的 Child 应该是一个数组或List<T>(建议使用泛型),另外 Master.AddChild 方法最好能提供 Master.AddChild(String childName) 的重载方法。

    知识改变命运,奋斗成就人生!
    2010年3月10日 4:58
    版主

全部回复

  • 你好!

    你这个非常别扭,下面的方式更好一些。

    Public Class Child
        Private _ChildName As String
        Public Property ChildName() As String
            Get
                Return _ChildName
            End Get
            Set(ByVal value As String)
                _ChildName = value
            End Set
        End Property
    End Class
    Public Class Master
        Private _Child As Child
        Public Property Child() As Child
            Get
                Return _Child
            End Get
            Set(ByVal value As Child)
                _Child = value
            End Set
        End Property
       
        Public Sub New()
                '默认构造一个 Child
            _Child = New Child()
        End Sub
    End Class
    Public Class Factory
        Public Shared Function CrateMaster() As Master
            Return New Master()
        End Function
    End Class
    Public Class Form1
        Private Sub Demo()
            Dim _Master As Master = Factory.CrateMaster()
               
                'Child _Child = new Child();
                '_Child.ChildName = "ChildName";
                '_Master.Child = _Child;
            _Master.Child.ChildName = "ChildName"
        End Sub
    End Class


    知识改变命运,奋斗成就人生!
    2010年3月8日 5:11
    版主
  • 十分感谢。

    你提供的方法很清楚。 Factory 生成 Master , Master 生成 Child。

    还有一个在这个问题基础上的引申问题:

    如果要在Master中生成多个Child。应该怎么做才比较好?

    从书上学了这么一个方法:

    用三个类:Child, ChildList, Master, 一个工厂:Factory

    Public Class Child
        Private _ChildName As String
        Public Property ChildName() As String
            Get
                Return _ChildName
            End Get
            Set(ByVal value As String)
                _ChildName = value
            End Set
        End Property
        Private Sub New()
        End Sub
        Public Shared Function Create() As Child
            Dim _Child As New Child
            Return _Child
        End Function
    End Class
    
    Imports System.ComponentModel
    Public Class Master
        Dim _ChildList As ChildList
        Public Property ChildList() As ChildList
            Get
                Return _ChildList
            End Get
            Set(ByVal value As ChildList)
                _ChildList = value
            End Set
        End Property
        Private Sub New()
            
        End Sub
        Public Shared Function Create() As Master
            Dim _Master As New Master
            Return _Master
        End Function
    End Class
    
    
    Public Class Factory
        Public Shared Function CreateMaster() As Master
            Return Master.Create()
        End Function
    End Class
    
    Public Class Form1
        Dim _Master As Master
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            _Master = Factory.CreateMaster()
            _Master.ChildList = ChildList.Create()
            Dim i As Integer
            For i = 0 To 3
                _Master.ChildList.Add(Child.Create())
                _Master.ChildList.Item(i).ChildName = i.ToString
                MsgBox(_Master.ChildList.Item(i).ChildName.ToString)
            Next
        End Sub
    End Class
    
    

    这里还有一个方法,我是这么写的:

    Child 和 Factory 不变,修改 Master, 这里不需要 ChildList。
    Imports System.ComponentModel
    Public Class Master
        Dim _ChildList As BindingList(Of Child)
        Public Property ChildList() As BindingList(Of Child)
            Get
                Return _ChildList
            End Get
            Set(ByVal value As BindingList(Of Child))
                _ChildList = value
            End Set
        End Property
        Public Sub AddChild()
            _ChildList.Add(Child.Create())
        End Sub
        
        Private Sub New()
            _ChildList = New BindingList(Of Child)
        End Sub
        Public Shared Function Create() As Master
            Dim _Master As New Master
            Return _Master
        End Function
    End Class
    
    Public Class Form1
        Dim _Master As Master
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            _Master = Factory.CreateMaster()
            
            Dim i As Integer
            For i = 0 To 3
                
                _Master.AddChild()
                _Master.ChildList.Item(i).ChildName = i.ToString
                MsgBox(_Master.ChildList.Item(i).ChildName.ToString)
            Next
        End Sub
    End Class
    虽然两个方法本身是一回事,但我比较倾向第二种方法。因为少一个ChildList类。感觉好像整齐一些。在这个例子中效果是一样的。但不知道有什么其它问题(就工厂方法而言)。

    如果这两个方法有不妥,请多多指正。其实不论如何都希望得到些意见。

    多谢了先。



    2010年3月9日 13:17
  • 第二种要简洁一些,另外需要注意的是 Master 中的 Child 应该是一个数组或List<T>(建议使用泛型),另外 Master.AddChild 方法最好能提供 Master.AddChild(String childName) 的重载方法。

    知识改变命运,奋斗成就人生!
    2010年3月10日 4:58
    版主
  • 太感谢了。

    我用BindingList就是因为书上用了这个来做集合,而且以前也没接触过。书上说,如果要用来和用户界面的控件进行邦定用BindingList方便些。但是现在还没有感性认识。List应该也挺好用。

    谢谢提示:Master.AddChild(String childName) 应该是必须要用的。

    再引申一个问题行不行?哈哈哈 有点儿不好意思,引申下去没头儿了,这是关于这个问题的最后一问。

    如果用了工厂方法,是不是最好所有的类都只用工厂方法来实例化?还是只需要把在运行时根据用户输入来生成的类是用工厂方法?其实我是觉得麻烦,但是又觉得混着来不漂亮,看着乱。一般来说的约定俗成是怎样的?

    多谢。
    2010年3月10日 9:53