2011-10-28 4 views
6

मेरे पास एक कक्षा है जो समय के साथ लगातार बढ़ रही है। इसे LayoutManager कहा जाता है।एक सिंगलटन/ईश्वर/प्रबंधक वर्ग से दूर शर्मिंदा होने की कोशिश कर रहा है। सुनिश्चित नहीं है कि मुझे कार्यक्षमता को कैसे बनाए रखना है, हालांकि

यह मेरे पृष्ठ पर गतिशील रूप से बनाए गए नियंत्रणों का ट्रैक रखने के लिए एक तरीका के रूप में शुरू हुआ।

public CormantRadDockZone() 
{ 
    ID = String.Format("RadDockZone_{0}", Guid.NewGuid().ToString().Replace('-', 'a')); 
    MinHeight = Unit.Percentage(100); 
    BorderWidth = 0; 
    HighlightedCssClass = "zoneDropOk"; 
    CssClass = "rightRoundedCorners"; 
    LayoutManager.Instance.RegisteredDockZones.Add(this); 
} 

इस तरह पृष्ठ जीवनचक्र की शुरुआत चरणों के दौरान, नियंत्रण होगा पुनर्निमित किया जा सकता है और वे अपने-अपने नियंत्रण की सूची के लिए खुद को जोड़ना होगा,: तो, उदाहरण के लिए, मैं इस किया है।

कुछ समय बाद मैंने खुद को विधियों के बीच 'पृष्ठ' ऑब्जेक्ट पास कर पाया। यह पृष्ठ पर पाए गए नियंत्रणों तक पहुंचने में सक्षम होने के एकमात्र उद्देश्य के लिए था। मैंने खुद को सोचा - ठीक है, मेरे पास पहले से ही एक लेआउट मैनेजर है, मैं सिर्फ उसी तरह से स्थिर नियंत्रण का इलाज करूंगा।

जैसे, मेरी Page_Init विधि अब इस गड़बड़ की तरह दिखता है:

protected void Page_Init(object sender, EventArgs e) 
{ 
    SessionRepository.Instance.EnsureAuthorized(); 

    LayoutManager.Instance.RegisteredPanes.Clear(); 
    LayoutManager.Instance.RegisteredDocks.Clear(); 
    LayoutManager.Instance.RegisteredDockZones.Clear(); 
    LayoutManager.Instance.RegisteredSplitters.Clear(); 
    LayoutManager.Instance.RegisteredSplitBars.Clear(); 
    LayoutManager.Instance.RegisteredPageViews.Clear(); 

    LayoutManager.Instance.CheckBox1 = CheckBox1; 
    LayoutManager.Instance.CheckBox4 = CheckBox4; 

    LayoutManager.Instance.StartEditButton = StartEditButton; 
    LayoutManager.Instance.FinishEditButton = FinishEditButton; 

    LayoutManager.Instance.RadNumericTextBox1 = RadNumericTextBox1; 
    LayoutManager.Instance.RadNumericTextBox2 = RadNumericTextBox2; 

    LayoutManager.Instance.LeftPane = LeftPane; 
    LayoutManager.Instance.DashboardUpdatePanel = DashboardUpdatePanel; 

    LayoutManager.Instance.CustomReportsContainer = CustomReportsContainer; 
    LayoutManager.Instance.HistoricalReportsContainer = HistoricalReportsContainer; 
    RegenerationManager.Instance.RegenerateReportMenu(); 

    LayoutManager.Instance.MultiPage = DashboardMultiPage; 
    LayoutManager.Instance.MultiPageUpdatePanel = MultiPageUpdatePanel; 
    LayoutManager.Instance.TabStrip = DashboardTabStrip; 

    RegenerationManager.Instance.RegenerateTabs(DashboardTabStrip); 
    RegenerationManager.Instance.RegeneratePageViews(); 

    LayoutManager.Instance.Timer = RefreshAndCycleTimer; 
    LayoutManager.Instance.Timer.TimerEvent += DashboardTabStrip.DoTimerCycleTick; 

    RegenerationManager.Instance.RegeneratePageState(); 
} 

मैं उस पर देख रहा हूँ और नहीं, नहीं, नहीं कह। यह सब गलत है। फिर भी, मेरे पृष्ठ पर नियंत्रण हैं जो एक दूसरे पर बहुत निर्भर हैं, लेकिन एक दूसरे तक पहुंच नहीं है। ऐसा लगता है कि यह इतना जरूरी है।

मुझे लगता है कि अभ्यास में इसका एक अच्छा उदाहरण अपडेटपेनल का उपयोग करेगा। इसलिए, उदाहरण के लिए, लेआउटमैनेजर को DashboardUpdatePanel दिया जा रहा है। पृष्ठ पर नियंत्रण हैं, जो सशर्त रूप से, डैशबोर्ड की संपूर्ण सामग्री को अपडेट करने का कारण बनना चाहिए।

अब, मेरी आँखों में, मेरा मानना ​​है कि मैं दो विकल्प हैं:

  1. वस्तु UpdatePanel.Update() कॉल करने के लिए इच्छुक के अंदर, मैं माता पिता वस्तुओं के माध्यम से ऊपर recurse, प्रकार और ID जांच जब तक मुझे लगता है उचित अद्यतन पैनेल।
  2. मैं UpdatePanel के लिए LayoutManager से पूछता हूं।

स्पष्ट रूप से दूसरा इस परिदृश्य में क्लीनर लगता है ... लेकिन मैं खुद को कई उदाहरणों में उसी तर्क का उपयोग कर पाता हूं। इसके परिणामस्वरूप एक प्रबंधक वर्ग है जो इस तरह दिखता है:

public class LayoutManager 
{ 
    private static readonly ILog _logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 

    private static readonly LayoutManager _instance = new LayoutManager(); 
    private LayoutManager() { } 

    public static LayoutManager Instance 
    { 
     get { return _instance; } 
    } 

    private IList<CormantRadDock> _registeredDocks; 
    private IList<CormantRadDockZone> _registeredDockZones; 
    private IList<CormantRadPane> _registeredPanes; 
    private IList<CormantRadSplitter> _registeredSplitters; 
    private IList<CormantRadSplitBar> _registeredSplitBars; 
    private Dictionary<string, StyledUpdatePanel> _registeredUpdatePanels; 
    private IList<CormantRadPageView> _registeredPageViews; 

    public RadMultiPage MultiPage { get; set; } 
    public CormantTimer Timer { get; set; } 
    public CormantRadListBox HistoricalReportsContainer { get; set; } 
    public CormantRadListBox CustomReportsContainer { get; set; } 
    public StyledUpdatePanel MultiPageUpdatePanel { get; set; } 
    public CormantRadTabStrip TabStrip { get; set; } 
    public RadPane LeftPane { get; set; } 
    public StyledUpdatePanel DashboardUpdatePanel { get; set; } 
    public RadButton ToggleEditButton { get; set; } 

    public CheckBox CheckBox1 { get; set; } 
    public CheckBox CheckBox4 { get; set; } 
    public RadNumericTextBox RadNumericTextBox1 { get; set; } 
    public RadNumericTextBox RadNumericTextBox2 { get; set; } 

    public RadButton StartEditButton { get; set; } 
    public RadButton FinishEditButton { get; set; } 

    public IList<CormantRadDock> RegisteredDocks 
    { 
     get 
     { 
      if (Equals(_registeredDocks, null)) 
      { 
       _registeredDocks = new List<CormantRadDock>(); 
      } 

      return _registeredDocks; 
     } 
    } 

    public IList<CormantRadDockZone> RegisteredDockZones 
    { 
     get 
     { 
      if (Equals(_registeredDockZones, null)) 
      { 
       _registeredDockZones = new List<CormantRadDockZone>(); 
      } 

      return _registeredDockZones; 
     } 
    } 

    public IList<CormantRadPane> RegisteredPanes 
    { 
     get 
     { 
      if (Equals(_registeredPanes, null)) 
      { 
       _registeredPanes = new List<CormantRadPane>(); 
      } 

      return _registeredPanes; 
     } 
    } 

    public IList<CormantRadSplitter> RegisteredSplitters 
    { 
     get 
     { 
      if (Equals(_registeredSplitters, null)) 
      { 
       _registeredSplitters = new List<CormantRadSplitter>(); 
      } 

      return _registeredSplitters; 
     } 
    } 

    public IList<CormantRadSplitBar> RegisteredSplitBars 
    { 
     get 
     { 
      if (Equals(_registeredSplitBars, null)) 
      { 
       _registeredSplitBars = new List<CormantRadSplitBar>(); 
      } 

      return _registeredSplitBars; 
     } 
    } 

    public Dictionary<string, StyledUpdatePanel> RegisteredUpdatePanels 
    { 
     get 
     { 
      if(Equals(_registeredUpdatePanels, null)) 
      { 
       _registeredUpdatePanels = new Dictionary<string, StyledUpdatePanel>(); 
      } 

      return _registeredUpdatePanels; 
     } 
    } 

    public IList<CormantRadPageView> RegisteredPageViews 
    { 
     get 
     { 
      if (Equals(_registeredPageViews, null)) 
      { 
       _registeredPageViews = new List<CormantRadPageView>(); 
      } 

      return _registeredPageViews; 
     } 
    } 

    public StyledUpdatePanel GetBaseUpdatePanel() 
    { 
     string key = MultiPage.PageViews.Cast<CormantRadPageView>().Where(pageView => pageView.Selected).First().ID; 
     return RegisteredUpdatePanels[key]; 
    } 

    public CormantRadDockZone GetDockZoneByID(string dockZoneID) 
    { 
     CormantRadDockZone dockZone = RegisteredDockZones.Where(registeredZone => dockZoneID.Contains(registeredZone.ID)).FirstOrDefault(); 

     if (Equals(dockZone, null)) 
     { 
      _logger.ErrorFormat("Did not find dockZone: {0}", dockZoneID); 
     } 
     else 
     { 
      _logger.DebugFormat("Found dockZone: {0}", dockZoneID); 
     } 

     return dockZone; 
    } 

    public CormantRadPane GetPaneByID(string paneID) 
    { 
     CormantRadPane pane = RegisteredPanes.Where(registeredZone => paneID.Contains(registeredZone.ID)).FirstOrDefault(); 

     if (Equals(pane, null)) 
     { 
      _logger.ErrorFormat("Did not find pane: {0}", paneID); 
     } 
     else 
     { 
      _logger.DebugFormat("Found pane: {0}", paneID); 
     } 

     return pane; 
    } 

    public CormantRadDock GetDockByID(string dockID) 
    { 
     CormantRadDock dock = RegisteredDocks.Where(registeredZone => dockID.Contains(registeredZone.ID)).FirstOrDefault(); 

     if (Equals(dock, null)) 
     { 
      _logger.ErrorFormat("Did not find dock: {0}", dockID); 
     } 
     else 
     { 
      _logger.DebugFormat("Found dock: {0}", dockID); 
     } 

     return dock; 
    } 
} 

क्या मैं एक बुरे रास्ते पर हूं? इस बिंदु पर आम तौर पर क्या कदम उठाए जाते हैं?

EDIT1: मैंने नियंत्रणों को ढूंढकर सुधार का मार्ग शुरू करने का निर्णय लिया है जो कम से कम लेआउटमैनेजर में एकीकृत हैं और अलग-अलग वस्तुओं में उन्हें तोड़ने के तरीके ढूंढ रहे हैं। इसलिए, उदाहरण के लिए, HistoricalReportsContainer और CustomReportsContainer ऑब्जेक्ट्स को लेआउटमैनेजर को निर्दिष्ट करने के बजाय (जिसे तब पुनर्जन्म प्रबंधक में उपयोग किया जाता है। रीजनरेटपोर्टपोर्टू) मैंने कोड को RadListBox "लोड" ईवेंट में स्थानांतरित कर दिया है। वहां, मैं उस नियंत्रण की आईडी की जांच करता हूं जो लोड हो रहा है और तदनुसार प्रतिक्रिया करता है। एक मजबूत पहला सुधार, और लेआउटमैनेजर से 2 नियंत्रण और एक विधि हटा दी है!

+0

ऐसा लगता है कि आप मध्यस्थ पैटर्न चाहते हैं। यह वही है जो आप यहां जा रहे हैं। देखें: http://www.dofactory.com/Patterns/PatternMediator.aspx –

+2

सिंगलटन लेआउट मैनेजर थोड़ा गंध करता है ... क्या आप एक से अधिक पेज अनुरोध को संसाधित करने में सक्षम हैं? ऐसा लगता है कि आप इस समय नहीं कर सके ... – Reddog

+0

आपका प्रश्न मुझे थोड़ा उलझन में डालता है, लेकिन उम्मीद है कि हम इसे बात कर सकते हैं। मैं लॉग इन उपयोगकर्ताओं के साथ एक वेब अनुप्रयोग डिजाइन कर रहा हूँ। जब कोई उपयोगकर्ता लॉग इन करता है, तो सूचना को डीबी से खींचा जाता है, सत्र में लोड किया जाता है, और फिर सत्र के आधार पर सेट लेआउट प्रबंधक चर सेट किया जाता है। ईमानदारी से, मुझे ऐसा नहीं लगता कि सिंगलटन मार्क-अप इस अर्थ में "सही महसूस करने" के अलावा कुछ भी जोड़ता है कि मैं कभी दो प्रबंधक नहीं बनना चाहता था। कोड में कुछ भी नहीं है जो कभी भी दूसरे प्रबंधक के लिए पूछेगा। –

उत्तर

1

Inversion of control एक सामान्य दृष्टिकोण है जो लोग ऐसी समस्याओं के लिए उपयोग करते हैं। आपकी निर्भरताओं को एक जैक-बाउर-तरह-शैली शैली में संग्रहित नहीं किया जाना चाहिए, बल्कि इंजेक्शन दिया जाना चाहिए, उदाहरण के लिए कन्स्ट्रक्टर के माध्यम से। आईओसी कंटेनर, जैसे कैसल विंडसर, यूनिटी, एन इंजेक्ट या किसी अन्य पर एक नज़र डालें।

+0

एमईएफ एक अच्छा है जो .NET संस्करण 4.0 या बाद के हिस्से के रूप में समर्थित है – Mranz

0

मुझे यकीन नहीं है कि यह एमवीसी की भविष्य की योजनाओं के साथ कैसे बातचीत करेगा, लेकिन क्या आपने लेआउटमैनेजर के रीफैक्टरिंग हिस्सों को पृष्ठ से प्राप्त एक अमूर्त वर्ग में माना है, फिर आपके वास्तविक पृष्ठ उस सारणी वर्ग से प्राप्त होते हैं?

संबंधित मुद्दे

 संबंधित मुद्दे