Slider8jet 的 .NET 活动记录空间

讨论和发表一些架构或模式相关的讯息

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 :: 管理 ::

近几天看了有关 IoC 的文章后,觉得很不错,于是做了一个简单的小程序,分享一下心得,而如果使用一个完整的 IoC 构件如 Castle 无疑会有更强大功能,不过对于未接触过这个概念的人来说无什么帮助.

程序演示: 提供一个 Manager 类给操作者,操作者能取得其资讯(或操作其做某些动作).Manager 有 2 种技能和 2 种身体状态.

程序目的: 操作者不用知道 Manager 的实际组合和建立动作,就可以直接使用,而 Manager 能使用 XML 做设置,使其在运行时提供不同的功能给予操作者,而程序不必重新编译.

        [STAThread]
        
static void Main(string[] args)
        {
            ServiceContainer sc 
= new ServiceContainer();
            Manager mg 
= (Manager)sc.RequestService( Manager.strClassName );
            
if( mg == null )
                
return;

            Console.WriteLine( 
"{0}", mg.GetInfo() );
            Console.Read();
        }

using System;
using System.IO;
using System.Xml;
using System.Collections;

namespace Demo
{
    
    
//******************************** Room ***************** (A)
    public interface IRoomSkill
    {
        
string GetName();
    }

    
public class ClearRoom : IRoomSkill
    {
        
public const string strClassName = "ClearRoom";

        
public string GetName()
        {
            
return "room skill is: " + "清洁";
        }
    }

    
public class FixRoom : IRoomSkill
    {
        
public const string strClassName = "FixRoom";

        
public string GetName()
        {
            
return "room skill is: " + "修理";
        }
    }

    
//******************************** Body ***************** (B)
    public interface IBody
    {
        
string GetName();
    }

    
public class Strong : IBody
    {
        
public const string strClassName = "Strong";

        
public string GetName()
        {
            
return "body: " + "强壮";
        }
    }

    
public class Thin : IBody
    {
        
public const string strClassName = "Thin";

        
public string GetName()
        {
            
return "body: " + "瘦弱";
        }
    }

    
//********************************************************* (C)
    public class Manager
    {
        IRoomSkill m_IRoomSkill;
        IBody m_IBody;
        
        
public const string strClassName = "Manager";

        
public Manager()
        {
        }

        
// 建构 注入
        public Manager(IRoomSkill room,IBody roomOwner)
        {
            m_IRoomSkill 
= room;
            m_IBody 
= roomOwner;
        }

        
public bool AddComponent(object obj,string strInterfaceClassName)
        {
            
if( obj == null )
                
return false;

            
if( strInterfaceClassName == typeof( IRoomSkill ).Name.ToString() )
            {
                m_IRoomSkill 
= (IRoomSkill)obj;
                
return true;
            }
            
else if( strInterfaceClassName == typeof( IBody ).Name.ToString() )
            {
                m_IBody 
= (IBody)obj;
                
return true;
            }

            
return false;
        }

        
public string GetInfo()
        {
            
if( m_IRoomSkill == null || m_IBody == null )
                
return null;

            
return string.Format( "manager info, {0}, {1} ",
                m_IRoomSkill.GetName(),
                m_IBody.GetName() );
        }
    }

    
//********************************************************* (D)
    public class ClassInfo
    {
        
public string strInterfaceClassName;
        
public string strComponentName;
    }

    
//********************************************************* (E)
    public class ServiceContainer
    {
        
public object RequestService(string strClassName)
        {
            
if( strClassName == Manager.strClassName )
            {
                ArrayList ar 
= ReadXMLClassInfo( strClassName );
                
if( ar == null || ar.Count < 1 )
                    
return null;

                Manager mg 
= new Manager();
                
foreach(ClassInfo ci in ar)
                {
                    
object obj = ObjectBuilder( ci.strComponentName );
                    
if( obj == null )
                        
continue;

                    mg.AddComponent( obj, ci.strInterfaceClassName );
                }

                
return mg;
            }

            
return null;
        }

        
object ObjectBuilder(string strClassName)
        {
            
if( strClassName == ClearRoom.strClassName )
                
return new ClearRoom();
            
else if( strClassName == FixRoom.strClassName )
                
return new FixRoom();
            
else if( strClassName == Strong.strClassName )
                
return new Strong();
            
else if( strClassName == Thin.strClassName )
                
return new Thin();

            
return null;
        }

        ArrayList ReadXMLClassInfo(
string strClassName)
        {
            
string strFile = strClassName + ".xml";
            
if( File.Exists( strFile ) == false )
            {
                Console.WriteLine( 
"file not find" );
                
return null;
            }

            XmlTextReader xtr 
= new XmlTextReader( strFile );
            ArrayList ar 
= new ArrayList();

            
string strStartFlag = null;

            
while( xtr.Read() )
            {
                
if( xtr.NodeType == XmlNodeType.Element )
                {
                    strStartFlag 
= xtr.Name;
                }
                
else if( xtr.NodeType == XmlNodeType.Text )
                {
                    
if( strStartFlag != null && strStartFlag.Length > 0 )
                    {
                        ClassInfo ci 
= new ClassInfo();
                        ci.strInterfaceClassName 
= strStartFlag;
                        ci.strComponentName 
= xtr.Value;
                        ar.Add( ci );                    
                        strStartFlag 
= null;
                    }
                }
            }

            
return ar;
        }
    }

    
//*********************************************************

    
// namespace end

Manager.XML: (skill: ClearRoom or FixRoom, body: Strong,Thin )

<?xml version="1.0" encoding="utf-8" ?> 
<Manager> 
       
<IBody>Strong</IBody> 
       
<IRoomSkill>FixRoom</IRoomSkill> 
</Manager> 



IoC 容器优势: 分离使用者和建造者,使其两不相关,提供动态类组合.

依赖注入(Dependency Injection)优势: 使提供的操作类只和接口相关,使类只对接口编程,不用去关心其他类,能动态注入元件,增加新元件时模块改动很少.

 注: 除了可以使用 XML 外也可以使用任意资源,而使用 XML 做中介最后读取并放在内存中速度会更快,另外 ObjectBuilder() 建立类的方法及 AddComponent() 的条件式也不是最好的做法.不过和主题无关也就不多写了.

程序文件Demo.zip: https://files.cnblogs.com/slider8jet/Demo.zip

 

posted on 2005-09-08 16:44  Slider8jet  阅读(1256)  评论(15)    收藏  举报