2011-10-28 1 views
3

저는 지금 꽤 오랫동안 커뮤니티에 어떤 삶을 살고 있는지 궁금해했습니다. 큰 비즈니스 지향 WPF/Silverlight 엔터프라이즈 응용 프로그램에 대해 말하고 있습니다.WPF/Silverlight 엔터프라이즈 응용 프로그램 아키텍처 .. 당신은 무엇을합니까?

이론적으로, 놀이에 다른 모델이 있습니다 :

  • 데이터 모델은 실제 비즈니스 로직을 포함
  • 비즈니스 모델 (클래스 (일반적으로, 귀하의 DB 테이블, Edmx/NHibarnate/.. 매핑 된 엔티티에 링크))
  • 전송 모델 (클래스 (DTO의) 실제 뷰가 결합되는
  • 보기 모델 (클래스)
) 외부 세계/클라이언트에 노출

이 분리는 분명한 장점이 있습니다. 하지만 실생활에서 작동합니까? 유지 보수의 악몽인가요?

그럼 어떻게하니? 실제로 이러한 모든 모델에 대해 서로 다른 클래스 모델을 사용합니까? 나는 예를 들어,이에 변화를 많이 본 적이 :

  • 데이터 모델 = 비즈니스 모델 : 데이터 모델 (POCO의로) 첫 번째 코드를 구현뿐만 아니라 거기에 비즈니스 로직과 비즈니스 모델로
  • 을 사용
  • 비즈니스 모델 = 전송 모델 =보기 모델 : 비즈니스 모델은 클라이언트에 그대로 노출됩니다. DTO에 대한 매핑이 없습니다 .. .. 발생합니다. 보기가이 비즈니스 모델에 직접 바인딩됩니다.
  • 데이터 모델이 노출 된 Silverlight RIA Services, 즉 데이터 모델이 노출되었습니다. Data Model = Business Model = Transfer Model. 그리고 때로는 모델 전송 = 모델보기.
  • ..

는 나는이 대답은 여기에 장소에 "이 달려있다"알고; 그러나 그것은 무엇에 달려 있습니까? 어떤 접근 방법을 사용 했습니까? 어떻게 사용 했습니까? 공유

감사합니다,

감사합니다, 공원

답변

2

좋은 질문입니다. 필자는 진취적인 것을 전혀 코딩하지 않았으므로 경험은 제한적이지만 나는 시작할 것이다.

현재 (WPF/WCF) 프로젝트는 데이터 모델 = 비즈니스 모델 = 전송 모델 = 모델보기를 사용합니다! DB 백엔드가 없으므로 "데이터 모델"은 사실상 XML로 직렬화 된 비즈니스 객체입니다.

나는 DTO 's와 놀았지만 극단적 인 관리가 빠르다는 것을 빠르게 발견했습니다. 그리고 나에게는 항상 존재하는 조기 옵티마이 저는 불필요한 복사를 싫어했습니다. 이것은 나에게 물어보기 위해 다시 올 수 있습니다 (예를 들어, comms 직렬화는 때때로 지속성 직렬화와 다른 필요성을가집니다). 그러나 지금까지는별로 문제가되지 않았습니다.

내 비즈니스 개체와 뷰 개체 모두 값 변경 알림을 푸시해야하므로 같은 방법 (INotifyPropertyChanged)을 사용하여 값을 구현하는 것이 좋습니다.MVVM을 사용하면 ViewModel이 필요한 경우 래퍼를 쉽게 제공 할 수 있지만 내 비즈니스 개체를 WPF 뷰 내에서 직접 바인딩 할 수 있다는 것은 좋은 부작용입니다.

지금까지 나는 주요한 걸림돌을 치지 않았으며, 유지할 한 세트의 물건을 가지고 있으면 좋고 단순합니다. 네 개의 "모델"을 모두 나누면이 프로젝트가 얼마나 큰지 생각하기가 두렵습니다.

필자는 별도의 객체를 사용하면 얻을 수있는 이점을 확실히 볼 수 있지만 실제로 문제가 될 때까지 나에게 노력과 복잡성이 낭비되는 것처럼 보입니다.

비록 내가 말했듯이, 이것은 상당히 작은 규모이며, 몇 10 대의 PC에서 작동하도록 설계되었습니다. 나는 진정한 엔터프라이즈 개발자들의 다른 반응을 읽는 것에 관심이있다.

0

MVVM을 디자인 패턴으로 사용했기 때문에 별 의미는 전혀 사용하지 않습니다. 저는 최근 MVVM을 사용하여 다소 큰 제품의 UI 구성 요소를 작성한 팀의 일원이었습니다.이 MVVM은 모든 데이터베이스 호출을 처리하는 서버 응용 프로그램과 상호 작용했으며 솔직히 제가 작업 한 최고의 프로젝트 중 하나라고 말할 수 있습니다.

이 프로젝트는

  • 데이터 모델 (에서 INotifyPropertyChanged에 대한 지원없이 기본 클래스),
  • 보기 모델을 가지고,
  • 보기 (INPC, 관련된 뷰에 대한 모든 비즈니스 로직을 지원) (XAML 만 해당) ,
  • 전송 모델

내가 한 일로 전송 모델을 분류했다 (방법은 데이터베이스를 호출) 실제로는 여러 층으로 지어졌습니다.

나는 또한 추가 기능을 추가하거나 데이터가 표시되는 방식을 변경하기 위해 Model 클래스를 감싸는 래퍼 인 일련의 ViewModel 클래스를 가졌다. 이것들은 모두 INPC를 지원했고 내 UI가 연결된 것들이었습니다.

나는 MVVM 접근법이 매우 유용하다는 것을 알았고 모든 정직함에서 코드보기를 단순하게 유지했다. 각보기에는 해당보기에 대한 비즈니스 논리를 처리하는 해당보기 모델이 있었으며 모델로 간주 될 다양한 기본 클래스가있었습니다.

나는이 코드를 분리하여 이해하기 쉽다고 생각한다. 각 View Model에는 뷰와 관련된 내용 만 포함되어 있기 때문에 복잡해지는 위험이 없다. 뷰 모델 간의 공통점은 무엇이든간에 반복 코드를 줄이기 위해 상속에 의해 처리됩니다.

데이터베이스에 대한 호출이 서비스 호출로 처리 되었기 때문에 서비스 메소드의 작동이 변경 될 수 있음을 의미하므로이 코드는 즉시 유지 보수가 가능해졌습니다. 데이터가 반환되고 필요한 매개 변수가 그대로 유지되면 UI는이를 알 필요가 없습니다. 동일한 코드가있는 UI를 사용하면 UI를 매우 쉽게 조정할 수 있습니다.

단점은 슬프게도 MVVM에 충실하고 일부 복잡하지 않은 솔루션을 그림으로 그리지 않는 한 어떤 이유로 든 코드에서 뒤에해야 할 일이 있다는 것입니다. 그래서 어떤 경우에는 진정한 MVVM 구현 (우리 회사에서는 이것이 코드 뒤에 없다고 생각했습니다).

결론 여러분이 상속을 적절하게 사용하고 디자인 패턴을 고수하고 코딩 표준을 적용하면이 접근법이 잘 작동한다고 생각합니다. 그러나 일탈하기 시작하면 일이 더러워지기 시작합니다.

0

몇 개의 레이어로 유지 관리 악몽이 생기지 않으며 레이어가 적어 지므로 유지 관리가 더 쉽습니다. 그리고 이유를 설명하려고 노력할 것입니다.

Customer 
{ 
    int Id 
    Region Region 
    EntitySet<Order> Orders 
} 

그리고 당신이 원하는 :

1) 전송 모델

예를 들어, 당신은 당신의 ADO.Net 엔터티 데이터 모델에서 다음 개체를 데이터 모델과 같은 안 WCF 서비스에서 반환하려면 다음과 같이 코드를 작성하십시오.

dc.Customers.Include("Region").Include("Orders").FirstOrDefault(); 

그리고 문제가 있습니다. 서비스 소비자 e RegionOrders 속성이 null 또는 비어 있지 않은 것으로 보장됩니까? 그리고 Order 엔티티가 OrderDetail 엔티티의 콜렉션을 가지고 있다면, 그것도 직렬화됩니까? 그리고 때로는 지연로드를 끄는 것을 잊을 수 있으며 전체 객체 그래프가 직렬화됩니다.

그리고 다른 상황 :

  • 두 요소를 결합하여 단일 객체로를 반환해야합니다.

  • 이진 배열 유형의 FileContent 열을 제외한 File 테이블의 모든 정보와 같은 엔티티의 일부만 반환하려고합니다.

  • 테이블에서 일부 열을 추가하거나 제거하려고하지만 기존 데이터에 새 데이터를 노출하고 싶지는 않습니다.

자동 생성 된 엔티티가 웹 서비스에 적합하지 않다고 확신합니다.

class CustomerModel 
{ 
    public int Id { get; set; } 
    public string Country { get; set; } 
    public List<OrderModel> Orders { get; set; } 
} 

그리고 당신은에 변경없이 서비스 모델을 변경할 수 있습니다 당신이 자유롭게뿐만 아니라, 웹 서비스의 기존 소비자에 영향을주지 않고 데이터베이스의 테이블을 변경할 수 있습니다 : 우리는이 같은 전송 모델을 생성해야하는 이유 때문이다 데이터 베이스.

모델 변환 과정을 더 쉽게 수행하려면 AutoMapper 라이브러리를 사용할 수 있습니다.

2) 그것은보기 모델은 이전 모델과 동일하지 않을 것을 권장합니다

당신이보기에 직접 전송 모델 객체를 결합 할 수 있지만, 그것은 단지 "일회용"관계가 될 것입니다 : 모델의 변경 사항은 뷰에 반영되지 않으며 그 반대의 경우도 마찬가지입니다.대부분의 경우 뷰 모델 클래스는 모델 클래스에 다음과 같은 기능을 추가하십시오 INotifyPropertyChanged 인터페이스를 사용하여 속성 변경 사항에 대한

  • 알림 ObservableCollection 클래스

  • 를 사용하여 수집 변경 사항에 대한

  • 알림 속성의 유효성 검사

  • 명령 이벤트 또는 뷰의 이벤트에 대한 반응 {Binding Converter...}와 유사한 데이터 바인딩과 재산 세터) 속성의

  • 변환, 조합,하지만

그리고 다시보기 모델의 측면에, 때때로 당신은 그들을 표시하기 위해 여러 모델을 결합해야합니다 단일보기. 그리고 서비스 객체에 의존하지 않고 자신의 속성을 정의하여 모델의 구조를 변경하면 뷰 모델이 동일 해지는 것이 좋습니다.

필자는 위에 설명 된 3 개의 레이어를 응용 프로그램 용으로 항상 사용하므로 잘 작동하므로 모두에게 동일한 접근 방식을 사용하는 것이 좋습니다.

0

우리는 Purplegoldfish가 몇 가지 추가 레이어로 게시 한 것과 유사한 접근 방식을 사용합니다. 우리의 응용 프로그램은 주로 웹 서비스와 통신하므로 우리의 데이터 객체는 특정 데이터베이스에 바인딩되지 않습니다. 이는 데이터베이스 스키마 변경이 반드시 UI에 영향을주지 않아도된다는 것을 의미합니다.

  1. 데이터 모델 :

    우리는 사용자 인터페이스 층은 다음의 서브 층이 포함이 변경 통보를 지원하는 일반 데이터 객체를 포함한다. 이들은 UI에서 독점적으로 사용되는 데이터 모델이므로 UI의 요구 사항에 맞게이를 디자인 할 수있는 유연성이 있습니다. 물론 이러한 객체 중 일부는 객체의 상태를 조작하는 논리가 포함되어 있기 때문에 일반 객체가 아닙니다. 또한 많은 데이터 그리드를 사용하기 때문에 각 데이터 모델은 그리드에 바인딩 할 수있는 속성 목록을 제공해야합니다.

  2. 보기 : 뷰의 XAML 정의. 몇 가지 복잡한 요구 사항을 수용하기 위해 XAML 전용 접근 방식을 고수하는 것이 너무 지루한 경우가있었습니다.

  3. ViewModels : 여기서는 뷰에 대한 비즈니스 로직을 정의합니다. 이 사람들은 또한 아래에 설명 된 데이터 액세스 계층의 엔터티가 구현하는 인터페이스에 액세스 할 수 있습니다.

  4. 모듈 발표자 : 일반적으로 모듈 초기화를 담당하는 클래스입니다. 이 태스크에는이 모듈과 연관된 뷰 및 기타 엔티티 등록도 포함됩니다.

    1. 전송 개체 : 이들은 일반적으로 웹 서비스에 의해 노출 된 데이터 엔티티

    그런 다음 우리는 다음을 포함하는 데이터 액세스 계층이있다. 대부분이 자동 생성됩니다.

  5. 다른 원격 데이터 소스에 대한 WCF 클라이언트 프록시 및 프록시와 같은 데이터 어댑터 : 일반적으로 이러한 프록시는 ViewModel에 노출 된 하나 이상의 인터페이스를 구현하며 원격 데이터 소스에 대한 모든 호출을 비동기 적으로 수행하고 모든 응답 필요에 따라 UI와 동등한 데이터 모델로 변환합니다. 경우에 따라 번역을 위해 AutoMapper를 사용하지만이 모든 작업은이 계층에서만 수행됩니다. 레이어링 방식이 조금 복잡하므로 애플리케이션이 복잡합니다. 웹 서비스, 직접 데이터베이스 액세스 및 OGC 웹 서비스와 같은 다른 유형의 데이터 소스를 비롯한 다양한 유형의 데이터 소스를 처리해야합니다.