太初有道

一万年 一秒一秒地过

数据共享问题--还是MVC
        以前在使用VC的时候,常常会看到Document/View的模型。那时候就知道他是MVC的一个变种。后来不断的看到有人MVC。但是其实我一直没有具体体会过MVC的好处。因为我们很少会重新设计界面或者重新实现数据模型。我们做的都是具体项目。不是产品也不是通用工具。
        但是 最近的项目中就遇到了一个问题。仔细想了一下发现这就是MVC的一个经典应用。我们通常认为MVC中的V是视图,这是大家都知道的。但是还有一个误解那就是V表示界面。这个误解常常使得我在设计系统的时候想不起MVC来。现在终于要改变这个观念了。V其实就是M的客户端而已。
        具体的问题是这样的。在我们的系统中每个图层上的对象都有一个属性是需要程序自动填上去的。因为我们做的编辑器是一个通用图形编辑器。在用户建立和修改图形的时候能够按照业务规则自动的给对象添上一些必要的属性。这个规则是可以配置的。现在问题就是,当用户在编辑的过程中,修改了规则或者添加了新规则。我们的编辑器是感觉不到这个规则的变化的。
        在开始编辑的时候,系统会把业务规则传递给编辑器使用。在其它地方就没有修改编辑器中业务规则的方式了。但是在我们的用户界面中有一个修改业务规则的界面。用户是可以在任何时候修改业务规则的。当然修改有就不能够立即其作用。我以前为了解决这个问题给编辑器添加了一个功能那就是刷行配置信息。这回导致所有的配置信息被重新载入。当然业务规则也会被重新载入。这样不久更新了吗。
        今天再仔细想了一下,我认为这两个控件都是我自己编写的并没有第三方库介入。为什么要使用这样一种不自然的方式来桥接这两个系统呢?
        于是我想到了让这两个控件共享同一个数据对象(里面是业务规则)。有用户界面的那个是可以编辑该对象的客户端。而编辑器则是一个只读取不修改的客户端。于是这个问题就解决了。不管什么时候用户修改了业务规则,在编辑器中都能马上反应出来。因为编辑器不在缓存规则而是直接引用。
       作到这一步我才发现这就是一个典型的MVC模型。
    
public interface EditorLayerObjects
    
...{
        
int LayerCount...{get;}
        EditLayerObject GetLayerAt(
int pIndex);
        EditLayerObject GetLayerOf(
string pClassName);
        
int IndexOfLayer(EditLayerObject pLayerObject);
        
void AppendLayer(EditLayerObject pLayerObject);     
        
void AppendLayer(ICollection pLayerObjectCol);
        
void RemoveLayer(EditLayerObject pLayerObject);
        
void ClearLayer();
    }
    上面是数据模型的接口。
    原先的编辑器自己实现了这个接口
  
public class DefaultEditor:EditorObject
...{
  
其他代码#region 其他代码
  
#endregion

    
EditorLayerObjects 成员#region EditorLayerObjects 成员
        
private void UpdateLayerObjectList()
        
...{
            
//这个函数用来检查LayerObject列表中的LayerObject是否都可用。
            if(this.ActiveView !=null)
            
...{
                
                
int aLayerCount=this.EditorLayerObjectList .Count ;
               
for(int li=0;li<aLayerCount;li++)
                
...{
                   EditLayerObject aObject
=this.EditorLayerObjectList [li] as EditLayerObject;
                   
if(aObject==nullthis.EditorLayerObjectList .Remove(aObject);
                    IGeoFeatureLayer aLayer
=LayerHelper.QueryLayerByModelName (
                        
this.ActiveView .FocusMap ,aObject.ClassName )as IGeoFeatureLayer ;
                   
if(aLayer!=null)
                   
...{//找到图层后就使用
                       aObject.ObjectLayer =aLayer;
                   }

                   
else
                   
...{//对于找不到图层的现在就直接去掉了。
                       this.EditorLayerObjectList .Remove (aObject);
                   }

                }

              
            }

        }

        
private ArrayList m_layerObjectList;
        
private ArrayList EditorLayerObjectList
        
...{
            
get
            
...{
                
if(this.m_layerObjectList ==null)
                    
this.m_layerObjectList =new ArrayList ();
                
return this.m_layerObjectList ;
            }

        }

        
public int LayerCount
        
...{
            
get
            
...{
                
return this.EditorLayerObjectList.Count ;
            }

        }

        
public EditLayerObject GetLayerAt(int pIndex)
        
...{
            
return this.EditorLayerObjectList [pIndex] as EditLayerObject;
        }

        
public EditLayerObject GetLayerOf(string pClassName)
        
...{
            
if(pClassName==null)return null;
            pClassName
=pClassName.ToUpper ();
            
int lCount=this.LayerCount ;
            EditLayerObject rLayer
=null;
            EditLayerObject aLayer
=null;
            
for(int li=0;li<lCount;li++)
            
...{
                aLayer
=this.GetLayerAt (li);
                
if(aLayer.ClassName .Equals(pClassName))
                
...{
                    rLayer
=aLayer;
                    
break;
                }

            }

            
return rLayer;
        }

        
public int IndexOfLayer(EditLayerObject pLayerObject)
        
...{
            
return this.EditorLayerObjectList .IndexOf (pLayerObject);
        }

        
public void AppendLayer(EditLayerObject pLayerObject)
        
...{
            
if(pLayerObject!=null)
            
...{
                
string aClassName=pLayerObject.ClassName ;                
                
if(this.ActiveView !=null)
                
...{//如果存在ActiveView 那么查询一下对应的图层。
                    
//只有有对应图层的对象才会保存下来。
                    ILayer aLayer=LayerHelper.QueryLayerByModelName (this.ActiveView.FocusMap ,aClassName);
                    
if(aLayer!=null)
                        pLayerObject.ObjectLayer 
=aLayer as IGeoFeatureLayer ;
                    
this.EditorLayerObjectList .Add (pLayerObject);
                }

                
else...{
                    
//由于目前没有ActiveView,所以先全部加入。在开始编辑的时候
                    
//和设置ActiveView的时候再查询一下。
                    this.EditorLayerObjectList .Add (pLayerObject); 
                }
       
            }

        }

        
public void AppendLayer(ICollection pLayerObjectCol)
        
...{
            
foreach(EditLayerObject aObject in pLayerObjectCol)
            
...{
                
this.AppendLayer (aObject);
            }

        }

        
public void RemoveLayer(EditLayerObject pLayerObject)
        
...{
            
this.EditorLayerObjectList .Remove (pLayerObject);
        }

        
public  void ClearLayer()
        
...{
            
this.EditorLayerObjectList .Clear ();
        }

        
#endregion

}
  后来修改了EditLayerObjects 添加了一个函数
public interface EditorLayerObjects
    
...{
        
void AttachModel(EditorLayerObjects pLayerObjects);
        
int LayerCount...{get;}
        EditLayerObject GetLayerAt(
int pIndex);
        EditLayerObject GetLayerOf(
string pClassName);
        
int IndexOfLayer(EditLayerObject pLayerObject);
        
void AppendLayer(EditLayerObject pLayerObject);     
        
void AppendLayer(ICollection pLayerObjectCol);
        
void RemoveLayer(EditLayerObject pLayerObject);
        
void ClearLayer();
    }
      这个方法允许对接口将自己的函数调用转发给另外一个挂接对象。
     于是这样就可以将那个编辑EditorLayerObjects的用户界面中对EditorLayerObjects的实现挂接到编辑器的EditorLayerObjects上。这样二者就自动地实现了数据共享。
阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

不良信息举报

数据共享问题--还是MVC

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭