클래스 복제 패턴?


11

현재 내 프로젝트에서 솔로 개발자로 일하고 있습니다. 나는 회사를 떠난 다른 개발자로부터 프로젝트를 물려 받았습니다. C #의 모델 뷰 컨트롤러 스타일 웹 응용 프로그램입니다. 객체 관계형 매핑에 Entity Framework를 사용합니다. 도메인 모델에는 유형에 대한 두 가지 다른 클래스 세트가 있습니다. 한 세트는 ORM과의 상호 작용에 사용되며 다른 세트는 MVC 시스템의 모델로 사용됩니다. 예를 들어 다음과 같은 두 가지 클래스가있을 수 있습니다.

public class Order{
    int ID{get;set;}
    String Customer{get;set;}
    DateTime DeliveryDate{get;set;}
    String Description{get;set;}
}

public class OrderModel{
    String Customer{get;set;}
    DateTime DeliveryDate{get;set;}
    String Description{get;set;}
    public OrderModel( Order from){
        this.Customer= from.Customer;
        // copy all the properties over individually
    }
    public Order ToOrder(){
        Order result =new Order();
        result.Customer = this.Customer;
        // copy all the properties over individually
    }

}

이 접근법에 대한 몇 가지 단점 (어떤 것이 변경되면 코드를 변경할 수있는 더 많은 장소, 메모리에 더 많은 객체가 앉아 있고, 데이터를 복사하는 데 더 많은 시간이 걸렸음)을 생각할 수 있지만 실제로 어떤 이점이 있는지 잘 모르겠습니다. 모델 클래스에 더 많은 유연성이 있다고 생각합니다. 그러나 엔티티 클래스를 서브 클래스 화하여 얻을 수 있습니다. 내 성향은이 두 클래스 그룹을 병합하거나 모델 클래스가 엔티티 클래스의 하위 클래스가되도록하는 것입니다. 그래서 여기서 중요한 것을 놓치고 있습니까? 이것이 내가 모르는 일반적인 디자인 패턴입니까? 내가 생각하고있는 리 팩터를 사용하지 않는 좋은 이유가 있습니까?

최신 정보

여기에 대한 답변 중 일부는 프로젝트에 대한 초기 설명에 중요한 세부 정보가 부족하다는 것을 깨닫게합니다. 프로젝트에 존재하는 세 번째 클래스 그룹 인 페이지 모델 클래스도 있습니다. 이들은 실제로 페이지를 뒷받침하는 모델로 사용되는 것들입니다. 또한 UI에 특정한 정보를 포함하며 데이터베이스에서 주문과 함께 저장되지 않습니다. 예제 페이지 모델 클래스는 다음과 같습니다.

public class EditOrderPagelModel
{
    public OrderModel Order{get;set;}
    public DateTime EarliestDeliveryDate{get;set;}
    public DateTime LatestAllowedDeliveryDate{get;set;}
}

나는이 세 번째 그룹의 유틸리티가 여기에서 구별되는 것을 완전히보고 다른 이름과 병합 할 계획이 없습니다 (이름을 바꿀 수도 있음).

모델 그룹의 클래스는 현재 응용 프로그램의 API에서도 사용되며, 이것이 좋은 아이디어인지에 대한 의견을 듣는 데 관심이 있습니다.

또한 여기에서 고객이 문자열로 표현되는 것은 시스템에서 실제로 그러한 방식으로 표현되기 때문에 예제를 단순화하는 것이 아니라고 언급해야합니다. 실제 시스템은 고유 한 특성을 가진 고객을 도메인 모델에서 고유 한 유형으로 보유합니다.


1
"저는 회사를 떠난 다른 개발자로부터 프로젝트를 물려 받았습니다." 이런 방식으로 시작되는 스토리 전용 사이트가 있습니다 .

업데이트와 관련하여 충분한 이익을 얻지 못하는 간접적 인 것으로 보입니다.
Robert Harvey

@RobertHarvey 너무 간접적이라고 말하는 것은 무엇입니까?
Robert Ricketts

1
OrderModel. OrderViewModel (EditOrderPageModel이라고도 함)은 충분한 간접 지시입니다. 아래 내 답변을 참조하십시오.
Robert Harvey

질문에 대한 답과 같은이 소리 @RobertHarvey 나는 실제로 물어려고
로버트 리 케츠

답변:


16

그래서 여기서 중요한 것을 놓치고 있습니까?

이것들은 같은 것으로 보이고 도메인에서 같은 것을 나타내지 만, 같은 (OOP) 객체는 아닙니다.

하나는 Order코드의 데이터 저장 부분에서 알려진 것과 같습니다. 다른 하나는 OrderUI에서 알려진 것과 같습니다. 이러한 클래스가 동일한 속성을 갖는 것은 우연의 일치이지만 보장 되지는 않습니다 .

또는 다른 관점에서 살펴 보려면 단일 책임 원칙을 고려하십시오. 여기서 중요한 동기는 "수업에 변화를 가져야 할 이유가 하나있다"는 것입니다. 특히 ORM 및 / 또는 UI 프레임 워크와 같은 퍼베이시브 프레임 워크를 처리 할 때는 프레임 워크를 변경하면 엔터티가 변경 될 수 있으므로 개체를 잘 격리해야합니다.

엔터티를 프레임 워크에 연결하면 훨씬 더 나빠집니다.


7

뷰 모델의 목적은 두 가지 방법으로 디커플링을 제공하는 것입니다. 뷰에 필요한 형태 (모델과 무관)로 데이터를 제공하고 (특히 MVVM에서) 뷰 로직의 일부 또는 전부를 뷰에서 다시 푸시함으로써 뷰 모델에.

완전히 정규화 된 모델에서 고객은 모델에서 문자열이 아니라 ID로 표시됩니다. 고객의 이름이 필요한 경우 모델은 Orders 테이블에있는 CustomerID를 사용하여 Customers 테이블에서 이름을 찾습니다.

반면, 뷰 모델 Name은 ID가 아닌 고객의 관심에 더 관심이있을 수 있습니다 . 고객이 모델에서 업데이트되지 않는 한 ID가 필요하지 않습니다.

또한 View Model은 순수한 CRUD 가 아닌 경우 일반적으로 다른 모양을 가질 수 있습니다 . 송장보기 모델 개체에는 고객 이름, 주소 및 광고 항목이있을 수 있지만 모델에는 고객과 설명이 포함됩니다.

즉, 송장은 일반적으로 표시되는 것과 같은 방식으로 저장되지 않습니다.


3

어떤면에서는 당신이 옳습니다. 둘 다 같은 domainobject를 참조 합니다 order. 그러나 당신은 지금까지 틀 렸습니다 . 다른 목적에서 비롯된 다른 표현보다 실제 중복 은 아닙니다 . 주문을 유지하려면 예를 들어 각 열에 액세스하려고합니다. 그러나 당신은 그것을 외부로 유출하고 싶지 않습니다. 와이어를 통해 전체 엔터티 를 푸시하는 것 외에도 실제로 원하는 것은 아닙니다. orderskb 정도면 충분할 MB 모음이 클라이언트에 제공된 사례를 알고 있습니다.

긴 이야기를 짧게 만들려면 다음과 같이하십시오.

1) 캡슐화-응용 프로그램의 정보 숨기기

2) 소형 모델은 직렬화가 빠르고 전송이 쉽습니다.

3) 그것들은 서로 겹치지 만 다른 목적으로 사용되므로 다른 물체가 있어야합니다.

4) 때로는 다른 쿼리마다 다른 Value-Object 를 갖는 것이 합리적 입니다. C #에 어떻게 있는지 모르지만 Java에서는 POJO 를 사용하여 결과를 수집 할 수 있습니다. 내가 하나가 필요하면 order내가 사용하는 주문 -entity,하지만 난 단지 데이터의 양 가득 일부 열을 필요로하는 경우 사용하는 작은 객체 것이 더 효율적입니다.


엔티티 프레임 워크가 구조화되는 방식, 엔티티는 평범한 오래된 C # 객체이므로 유선으로 전송하는 것은 실제로 큰 문제가 아닙니다. 일부 상황에서는 주문 내용의 일부만 보낼 수있는 유틸리티가 있습니다.
Robert Ricketts

내가 말했듯이 하나 또는 무리는 문제가되지 않습니다. 그러나 MBs의 데이터가있는 경우로드 시간이 느려지는 경우가 있습니다. 모바일로드 시간의 생각
토마스 정크

0

(면책 조항 : 나는이 방법으로 만 사용되는 것을 보았습니다. 그렇게하는 실제 목적을 오해했을 수도 있습니다.이 대답은 의심으로 취급하십시오.)

또 다른 누락 된 비트가 있습니다 : Order과 사이의 변환 OrderModel.

Order는 동안 클래스는, 당신의 ORM에 연결되어 OrderModel당신의보기 모델의 설계에 연결되어 있습니다.

일반적으로 두 방법은 "매직 방식으로"제공됩니다 (때로는 DI, IoC, MVVM 또는 또 다른 방법이라고 함). 즉,이 두 가지 변환 방법을의 일부로 구현하는 OrderModel대신 이러한 것의 상호 변환 전용 클래스에 속합니다. 해당 클래스는 프레임 워크에 쉽게 등록 될 수 있도록 프레임 워크에 등록됩니다.

public class OrderModel {
    ...
    public OrderModel(Order from) { ... }
    public Order ToOrder() { ... }
}

이렇게하는 이유는에서 교차점이있을 때마다 것입니다 OrderModel받는 Order반대 또는 반대, 당신은 어떤 데이터가로드 또는 ORM에 저장되어 있어야합니다 것을 알고있다.


나는 모두 주위를 유지하고 있다면, 나는 확실히 전환이 더 자동화 할 수 있습니다하도록 설정하고 싶습니다
로버트 리 케츠를

@RobertRicketts 내가 본 것은 IMvxValueConverter 입니다. 비록 그 목적을 오해했을 수도 있습니다.
rwong
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.