2011-10-28 1 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(); 
} 

. 그것은 모두 잘못입니다. 그러나 내 페이지에는 서로에 매우 의존적 인 컨트롤이 있지만 서로 액세스 할 수는 없습니다. 이것은 이것이 그렇게 필요하게 만드는 것입니다.

실제로이 좋은 예가 실제로는 UpdatePanels를 사용한다고 생각합니다. 예를 들어, DashboardUpdatePanel이 LayoutManager에 제공되고 있습니다. 조건에 따라 대시 보드의 전체 내용을 업데이트해야하는 컨트롤이 페이지에 있습니다.

지금, 내 눈에, 나는 두 가지 옵션이 생각 : UpdatePanel.Update()를 호출하고자하는 객체의 내부

  1. 을, 나는이를 찾을 때까지 유형과 ID를 확인, 부모 객체를 통해 재귀 적절한 UpdatePanel.
  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 : 나는 LayoutManager에 가장 덜 통합 된 컨트롤을 찾아서 별도의 객체로 분리하는 방법을 찾는 것으로부터 개선의 길을 시작하기로 결정했습니다. 예를 들어, HistoricalReportsContainer 및 CustomReportsContainer 객체를 LayoutManager에 할당하는 대신 (RegenerationManager.RegenerateReportMenu에서 사용됨) 코드를 RadListBox "Load"이벤트로 이동했습니다. 거기에서, 나는 로딩하고 그에 따라 반응하는 컨트롤의 ID를 확인합니다. 강력한 개선이 이루어졌으며 LayoutManager에서 2 개의 컨트롤과 메서드가 제거되었습니다!

+0

중재자 패턴을 원하는 것처럼 보입니다. 그것은 당신이 여기서 겪고있는 것과 매우 흡사합니다. 참조 : http://www.dofactory.com/Patterns/PatternMediator.aspx –

+2

싱글 톤 레이아웃 관리자가 조금 냄새가납니다 ... 동시에 여러 페이지 요청을 처리 할 수 ​​있습니까? 당신이 그 순간에 할 수 없었던 것처럼 보입니다 ... – Reddog

+0

당신의 질문은 나를 약간 혼란스럽게합니다. 그러나 희망을 갖고 우리는 그것을 말할 수 있습니다. 로그인 한 사용자가 웹 응용 프로그램을 설계하고 있습니다. 사용자가 로그인하면 DB에서 정보를 가져 와서 세션에로드 한 다음 세션에 따라 레이아웃 관리자 변수를 설정합니다. 솔직히, 나는 Singleton 마크 업에서 두 ​​명의 관리자를 갖기를 원하지 않는다는 의미에서 "감각이 옳다"이외의 것을 추가하지는 않는다고 생각합니다. 하지만 두 번째 관리자를 요구하는 코드는 없습니다. –

답변

1

Inversion of control은 사람들이 이러한 문제에 사용하는 일반적인 접근 방법입니다. 종속성은 Jack-Bauer-kind-of-style 클래스에 저장되어서는 안되며, 예를 들어 생성자를 통해 주입되어야합니다. Castle Windsor, Unity, NInject 또는 기타와 같은 IoC 컨테이너를 살펴보십시오.

+0

MEF는 .NET 버전 4.0 이상에서 지원되는 좋은 제품입니다. – Mranz

0

이것이 MVC의 향후 계획과 어떻게 상호 작용할지는 모르지만 LayoutManager의 리팩토링 덩어리를 Page에서 상속 한 추상 클래스로 간주했다면 실제 페이지를 추상 클래스에서 상속 받겠습니까?

관련 문제