我的实用设计模式之 关于Policy-based design在Windows Mobile网络连接管理的应用

以下文章为Policy-based design的想法,不是经典的Strategy模式。

 

本文主要讲述Strategy模式在Windows Mobile网络连接管理的应用。经过我的实用设计模式之二--关于Policy-based design的讨论,对Strategy模式进一步思考,有了一些新的认识,Strategy模式使用最为广泛的情景是封装不同的算法,使得客户端不关心具体算法的处理,因此我使用stragety模式最多的是在 Analysis Engine(分析引擎),根据Raw Data(原数据)使用不要的分析器(分析器使用不同的算法)分析出关心的Event(事件,对象,告警等等)。同时作为behavior模式之一,stragety模式也可以使用在 定义多个behaviors(行为,在C#中可以为method或者property)来代替大量的条件语句(if else或者switch)的情景。

下面是用案例论述,有一个Windows Mobile的手机系统,需要定期往服务器提交数据,在数据传输时需要网络连接,由于这个手机支持3G和Wifi,因此,可以通过多种硬件连接进行数据提交。下面是一个没有用到OO的设计。

 

public enum ConnectionType
{
    Wifi,
    ThreeG
}

public class DataSubmitter
{
    
public ConnectionType connectionType;
    
public void SubmitData()
    {
        
if(!CheckConnection())
        {
            MakeConnection();
        }
        
        
//submit data
        
        StopConnection();
        
    }
    
    
public bool CheckConnection()
    {
        
switch(connectionType)
        {
            
case ConnectionType.Wifi:
                CheckWifiConnection();
            
break;
            
case ConnectionType.ThreeG:
                CheckThreeGConnection();
            
break;
            
        }
    }
    
    
public bool MakeConnection()
    {
        
switch(connectionType)
        {
            
case ConnectionType.Wifi:
                MakeWifiConnection();
            
break;
            
case ConnectionType.ThreeG:
                MakeThreeGConnection();
            
break;
            
        }
    }
    
    
public bool StopConnection()
    {
        
switch(connectionType)
        {
            
case ConnectionType.Wifi:
                StopWifiConnection();
            
break;
            
case ConnectionType.ThreeG:
                StopThreeGConnection();
            
break;
            
        }
    }
        
}

 

数据提交程序(Client)每次提交数据都需要调用CheckConnection,MakeConnection(如果需要),StopConnection这些behaviors.但是由于硬件连接有多种,需要使用条件语句(if else或者switch case)来表达不同behavior。如果新增一种新的网络连接方式,例如新增GPRS,那么需要修改client来完成。试想一下应用程序应该不关心具体的网络连接,例如msn和QQ不管Windows的连接,这个链接可能是wifi,可能是有线网络,可能是拨号。作为上层应用的msn和QQ不会关心这些具体网络连接技术,msn更加不可能需要修改程序来支持新的网络连接方式。为了解决这个问题,我们引进Strategy模式。

 

    public enum ConnectionType
    {
        Wifi,
        ThreeG,
        Gprs
    }

    
//strategy
    public interface Connection
    {
        
//behaviors
        bool Connect();
        
bool Disconnect();
        
bool IsConnected {get;}
    }

    
public class WifiConnection : Connection
    {
        
public bool Connect()
        {
            
//invoke wifi api to make connection
            return true;
        }
        
public bool Disconnect()
        {
            
//invoke wifi api to stop connection
            return true;
        }

        
public bool IsConnected 
        {
            
get
            {
                
//invoke wifi api to check connection
                return true;
            } 
        }
    }

    
public class ThreeGConnection : Connection
    {
        
public bool Connect()
        {
            
//invoke ThreeG api to make connection
            return true;
        }
        
public bool Disconnect()
        {
            
//invoke ThreeG api to stop connection
            return true;
        }

        
public bool IsConnected
        {
            
get
            {
                
//invoke ThreeG api to check connection
                return true;
            }
        }
    }

    
public class GprsConnection : Connection
    {
        
public bool Connect()
        {
            
//invoke Gprs api to make connection
            return true;
        }
        
public bool Disconnect()
        {
            
//invoke Gprs api to stop connection
            return true;
        }

        
public bool IsConnected
        {
            
get
            {
                
//invoke Gprs api to check connection
                return true;
            }
        }
    }

    
//Context
    public class ConnectionManager
    {
        
private Dictionary<ConnectionType, Connection> connections;
        
private Connection currentConnection;

        
public ConnectionManager()
        {
            
foreach(setting from configurations) // this is fake code
            {
                ConnectionType type; 
// get from configurations
                connections[type] = ConnectionFactory.CreateConnection(type);
            }
        }

        
public bool CheckConnection()
        {
            
//according to specific requirement, pick up one of connections to connect
            currentConnection = connections[ConnectionType.Wifi];
            
return currentConnection.Connect();
        }

        
public bool MakeConnection()
        {
            
return currentConnection.Disconnect();

        }

        
public bool StopConnection()
        {
            
return currentConnection.IsConnected;
        }
    }

    
//connection factory
    public sealed class ConnectionFactory
    {
        
public static Connection CreateConnection(ConnectionType connectionType)
        {
            
try
            {
                System.Reflection.Assembly asm 
= System.Reflection.Assembly.GetExecutingAssembly();
                Type type 
= typeof(ConnectionFactory);
                
return (Connection)asm.CreateInstance(type.Namespace + "." + connectionType.ToString() + "Connection");
            }
            
catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
            
return null;
        }
    }

    
//client
    public class DataSubmitter
    {
        
public ConnectionManager connectionMgr;
        
public void SubmitData()
        {
            
if(!connectionMgr.CheckConnection())
            {
                connectionMgr.MakeConnection();
            }
            
            
//submit data
            
            connectionMgr.StopConnection();
        }
    }

 

Connection是Strategy父类,定义需要实现的behaviors(在C#里面是method和property),ConnectionManager是Context,负责管理各个具体的connection,在connection里面使用了简单工厂和Reflection,connection通过配置文件来生成。当新增新的连接技术时,只需要增加Connection的子类,实现他的behaviors,修改简单工厂的配置文件就可以了。这样client根本不需要知道新的连接技术,原先的功能(数据提交)可以使用新的连接技术而不需要任何的修改。

关于工厂模式和Reflection,我打算在下一篇进行论述。

 Jake's Blog in 博客园 -- 精简开发 无线生活

posted @ 2009-03-25 08:55  Jake Lin  阅读(3788)  评论(1编辑  收藏  举报