Design Patterns(十二):Flyweight Pattern--VB代码

结构图

 

角色

  • 抽象享元(Flyweight)角色:此角色是所有的具体享元类的超类,为这些类规定出需要实现的公共接口。那些需要外蕴状态(External State)的操作可以通过调用商业方法以参数形式传入。
  • 具体享元(ConcreteFlyweight)角色:实现抽象享元角色所规定的接口。如果有内蕴状态的话,必须负责为内蕴状态提供存储空间。享元对象的内蕴状态必须与对象所处的周围环境无关,从而使得享元对象可以在系统内共享的。
  • 享元工厂(FlyweightFactory)角色:本角色负责创建和管理享元角色。本角色必须保证享元对象可以被系统适当地共享。当一个客户端对象调用一个享元对象的时候,享元工厂角色会检查系统中是否已经有一个复合要求的享元对象。如果已经有了,享元工厂角色就应当提供这个已有的享元对象;如果系统中没有一个适当的享元对象的话,享元工厂角色就应当创建一个合适的享元对象。
  • 客户端(Client)角色:本角色需要维护一个对所有享元对象的引用。本角色需要自行存储所有享元对象的外蕴状态。

动机
  采用纯粹对象方案的问题在于大量细粒度的对象会很快充斥在系统中,从而带来很高的运行时代价--主要指内存需求方面的代价。
  如何在避免大量细粒度对象问题的同时,让外部客户程序仍然能够透明地使用面向对象的方式来进行操作?

意图

运用共享技术有效地支持大量细粒度的对象。

示意性代码 

示意性代码
'MainApp test application 
Public Class MainAppClass MainApp
    
Public Sub Main()Sub Main()
        
'Arbitrary extrinsic state
        Dim extrinsicstate As Integer = 22

        
Dim f As New FlyweightFactory

        
'Work with different flyweight instances
        Dim fx As Flyweight = f.GetFlyweight("X")
        fx.Operation(System.Threading.Interlocked.Decrement(extrinsicstate))

        
Dim fy As Flyweight = f.GetFlyweight("Y")
        fy.Operation(System.Threading.Interlocked.Decrement(extrinsicstate))

        
Dim fz As Flyweight = f.GetFlyweight("Z")
        fz.Operation(System.Threading.Interlocked.Decrement(extrinsicstate))

        
Dim uf As New UnsharedConcreteFlyweight
        uf.Operation(System.Threading.Interlocked.Decrement(extrinsicstate))

        Console.ReadLine()

    
End Sub

End Class


'"FlyweightFactory" 
Public Class FlyweightFactoryClass FlyweightFactory
    
Private flyweights As New Hashtable
    
'Constructor     
    Public Sub New()Sub New()
        flyweights.Add(
"X"New ConcreteFlyweight())
        flyweights.Add(
"Y"New ConcreteFlyweight())
        flyweights.Add(
"Z"New ConcreteFlyweight())
    
End Sub

    
Public Function GetFlyweight()Function GetFlyweight(ByVal key As StringAs Flyweight
        
Return TryCast(flyweights(key), Flyweight)
    
End Function

End Class


'"Flyweight"
Public MustInherit Class FlyweightClass Flyweight
    
Public MustOverride Sub Operation()Sub Operation(ByVal extrinsicstate As Integer)
End Class


'"ConcreteFlyweight" 
Public Class ConcreteFlyweightClass ConcreteFlyweight
    
Inherits Flyweight
    
Public Overrides Sub Operation()Sub Operation(ByVal extrinsicstate As Integer)
        Console.WriteLine(
"ConcreteFlyweight:" & extrinsicstate)
    
End Sub

End Class


'"UnsharedConcreteFlyweight" 
Public Class UnsharedConcreteFlyweightClass UnsharedConcreteFlyweight
    
Inherits Flyweight
    
Public Overrides Sub Operation()Sub Operation(ByVal extrinsicstate As Integer)
        Console.WriteLine(
"UnsharedConcreteFlyweight:" & extrinsicstate)
    
End Sub

End Class

一个实例 

实例代码
 ' Flyweight pattern -- Real World example

 
Imports System
 
Imports System.Collections

 
Namespace DoFactoryNamespace DoFactory.GangOfFour.Flyweight.RealWorld
    
     
' MainApp test application
     Class MainAppClass MainApp
         
Private Shared Sub Main()Sub Main()
             
' Build a document with text
             Dim document As String = "AAZZBBZB"
             
Dim chars As Char() = document.ToCharArray()
            
             
Dim f As New CharacterFactory()
            
             
' extrinsic state
             Dim pointSize As Integer = 10
            
             
' For each character use a flyweight object
             For Each c As Char In chars
                 pointSize 
+= 1
                 
Dim character As Character = f.GetCharacter(c)
                 character.Display(pointSize)
             
Next
            
             
' Wait for user
             Console.Read()
         
End Sub

     
End Class

    
     
' "FlyweightFactory"
     Class CharacterFactoryClass CharacterFactory
         
Private characters As New Hashtable()
        
         
Public Function GetCharacter()Function GetCharacter(ByVal key As CharAs Character
             
' Uses "lazy initialization"
             Dim character As Character = TryCast(characters(key), Character)
             
If character Is Nothing Then
                 
Select Case key
                     
Case "A"C
                         character 
= New CharacterA()
                         
Exit Select
                     
Case "B"C
                         character 
= New CharacterB()
                         
Exit Select
                     
Case "Z"C
                         
'
                         character = New CharacterZ()
                         
Exit Select
                 
End Select
                 characters.Add(key, character)
             
End If
             
Return character
         
End Function

     
End Class

    
     
' "Flyweight"
     MustInherit Class CharacterClass Character
         
Protected symbol As Char
         
Protected width As Integer
         
Protected height As Integer
         
Protected ascent As Integer
         
Protected descent As Integer
         
Protected pointSize As Integer
        
         
Public MustOverride Sub Display()Sub Display(ByVal pointSize As Integer)
     
End Class

    
     
' "ConcreteFlyweight"
     Class CharacterAClass CharacterA
         
Inherits Character
         
' Constructor
         Public Sub New()Sub New()
             
Me.symbol = "A"C
             
Me.height = 100
             
Me.width = 120
             
Me.ascent = 70
             
Me.descent = 0
         
End Sub

        
         
Public Overloads Overrides Sub Display()Sub Display(ByVal pointSize As Integer)
             
Me.pointSize = pointSize
             Console.WriteLine(
Me.symbol + " (pointsize " + Me.pointSize + ")")
         
End Sub

     
End Class

    
     
' "ConcreteFlyweight"
     Class CharacterBClass CharacterB
         
Inherits Character
         
' Constructor
         Public Sub New()Sub New()
             
Me.symbol = "B"C
             
Me.height = 100
             
Me.width = 140
             
Me.ascent = 72
             
Me.descent = 0
         
End Sub

        
         
Public Overloads Overrides Sub Display()Sub Display(ByVal pointSize As Integer)
             
Me.pointSize = pointSize
             Console.WriteLine(
Me.symbol + " (pointsize " + Me.pointSize + ")")
         
End Sub

        
     
End Class

    
     
'  C, D, E, etc.
    
     
' "ConcreteFlyweight"
     Class CharacterZClass CharacterZ
         
Inherits Character
         
' Constructor
         Public Sub New()Sub New()
             
Me.symbol = "Z"C
             
Me.height = 100
             
Me.width = 100
             
Me.ascent = 68
             
Me.descent = 0
         
End Sub

        
         
Public Overloads Overrides Sub Display()Sub Display(ByVal pointSize As Integer)
             
Me.pointSize = pointSize
             Console.WriteLine(
Me.symbol + " (pointsize " + Me.pointSize + ")")
         
End Sub

     
End Class

 
End Namespace

 

Flyweight模式的几个要点:
  1、面向对象很好地解决了抽象性的问题,但是作为一个运行在机器中的程序实体,我们需要考虑对象的代价问题。Flyweight设计模式主要解决面向对象的代价问题,一般不触及面向对象的抽象性问题。
  2、Flywight采用对象共享的做法来降低系统中对象的个数,从而降低细粒对象给系统带来的内存压力。在具体实现方面,要注意对象状态的处理。
  3、对象的数量太大从而导致对象内存开销加大--什么样的数量才算大?这需要我们仔细的根据具体应用情况进行评估,而不能凭空臆断。

参考资料

《C#设计模式(14)-Flyweight Pattern》        吕震宇
《C#面向对象设计模式纵横谈系列课程(12)》     李建中老师
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值