Lớp nhân đôi mô hình?


11

Tôi hiện đang làm việc như một nhà phát triển solo cho dự án hiện tại của mình. Tôi đã kế thừa dự án từ một nhà phát triển khác, người đã rời công ty. Đây là một ứng dụng web kiểu mô hình-khung nhìn-trình điều khiển trong C #. Nó sử dụng Entity Framework để ánh xạ quan hệ đối tượng. Và có hai nhóm lớp khác nhau cho các kiểu trong mô hình miền. Một bộ được sử dụng để tương tác với ORM và bộ kia được sử dụng làm mô hình trong hệ thống MVC. Ví dụ, có thể có hai lớp như sau:

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
    }

}

Tôi có thể nghĩ ra một số nhược điểm của phương pháp này (nhiều nơi thay đổi mã hơn nếu có gì đó thay đổi, nhiều đối tượng ngồi trong bộ nhớ hơn, mất nhiều thời gian hơn để sao chép dữ liệu xung quanh), nhưng tôi không thực sự chắc chắn những lợi thế ở đây là gì. Linh hoạt hơn cho các lớp mô hình, tôi cho rằng? Nhưng tôi có thể có được điều đó bằng cách phân lớp các lớp thực thể là tốt. Xu hướng của tôi sẽ là hợp nhất hai nhóm lớp này hoặc có thể có các lớp mô hình là các lớp con của các lớp thực thể. Vì vậy, tôi đang thiếu một cái gì đó quan trọng ở đây? Đây có phải là một mẫu thiết kế phổ biến mà tôi không biết? Có lý do chính đáng nào để không trải qua với công cụ tái cấu trúc mà tôi đang dự tính không?

CẬP NHẬT

Một số câu trả lời ở đây đang khiến tôi nhận ra mô tả ban đầu của tôi về dự án đang thiếu một số chi tiết quan trọng. Ngoài ra còn có một nhóm các lớp thứ ba tồn tại trong dự án: các lớp mô hình trang. Họ là những người thực sự đang được sử dụng như là mô hình sao lưu trang. Chúng cũng chứa thông tin dành riêng cho UI và sẽ không được lưu trữ với một đơn đặt hàng trong cơ sở dữ liệu. Một lớp mô hình trang ví dụ có thể là:

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

Tôi hoàn toàn thấy tiện ích của nhóm thứ ba này là khác biệt ở đây và không có kế hoạch hợp nhất nó với thứ khác (mặc dù tôi có thể đổi tên nó).

Các lớp trong nhóm mô hình hiện cũng được sử dụng bởi API của ứng dụng, điều mà tôi cũng quan tâm khi nghe ý kiến ​​đóng góp về việc đó có phải là một ý tưởng hay không.

Tôi cũng nên đề cập rằng khách hàng được đại diện như một chuỗi ở đây là để đơn giản hóa ví dụ, không phải vì nó thực sự được thể hiện theo cách đó trong hệ thống. Hệ thống thực tế có khách hàng là một loại khác biệt trong mô hình miền, với các thuộc tính riêng của nó


1
"Tôi đã kế thừa dự án từ một nhà phát triển khác, người đã rời công ty" có một trang dành riêng cho những câu chuyện bắt đầu theo cách này .

Về cập nhật của bạn: có vẻ như quá nhiều sự thiếu quyết đoán vì không đủ lợi ích.
Robert Harvey

@RobertHarvey Bạn đang đề cập đến điều gì là quá thiếu quyết đoán?
Robert Ricketts

1
OrderModel. OrderViewModel (cái mà bạn có thể gọi là EditOrderPageModel) là đủ điều kiện; xem câu trả lời của tôi dưới đây
Robert Harvey

@RobertHarvey Điều này nghe có vẻ như câu trả lời cho câu hỏi tôi thực sự đang cố gắng hỏi
Robert Ricketts

Câu trả lời:


16

Vì vậy, tôi đang thiếu một cái gì đó quan trọng ở đây?

ĐÚNG

Mặc dù chúng trông giống nhau và đại diện cho cùng một thứ trong miền, nhưng chúng không phải là các đối tượng (OOP) giống nhau.

Một là phần Orderđược biết đến bởi phần lưu trữ dữ liệu của mã. Cái khác là cái Orderđược biết bởi UI. Mặc dù điều trùng hợp thú vị là các lớp này có cùng thuộc tính, nhưng chúng không được đảm bảo .

Hoặc để xem xét nó từ một khía cạnh khác, hãy xem xét Nguyên tắc Trách nhiệm duy nhất. Động lực chính ở đây là "một lớp học có một lý do để thay đổi". Đặc biệt là khi xử lý các khung phổ biến như khung ORM và / hoặc UI, các đối tượng của bạn cần được cách ly tốt vì các thay đổi đối với khung thường sẽ khiến các thực thể của bạn thay đổi.

Bằng cách buộc các thực thể của bạn vào cả hai khung, bạn sẽ làm cho nó tồi tệ hơn nhiều.


7

Mục đích của Mô hình xem là cung cấp việc tách rời theo hai cách: bằng cách cung cấp dữ liệu theo hình dạng mà Chế độ xem yêu cầu (độc lập với mô hình) và (đặc biệt là trong MVVM) bằng cách đẩy một số hoặc tất cả logic của Chế độ xem lại khỏi Chế độ xem đến Mô hình xem.

Trong một mô hình được chuẩn hóa hoàn toàn, Khách hàng sẽ không được biểu diễn trong Mô hình bằng một chuỗi mà thay vào đó là một ID. Model, nếu cần tên của khách hàng, sẽ tra cứu tên từ bảng Khách hàng, sử dụng ID khách hàng được tìm thấy trong bảng Đơn hàng.

Mặt khác, Mô hình Chế độ xem có thể được Namekhách hàng quan tâm hơn , chứ không phải ID. Nó không cần ID trừ khi Khách hàng đang được cập nhật trong Mô hình.

Ngoài ra, Mô hình Chế độ có thể và thường có hình dạng khác (trừ khi đó là CRUD thuần túy ). Đối tượng Mô hình Chế độ xem Hóa đơn có thể có tên khách hàng, địa chỉ và chi tiết đơn hàng, nhưng mô hình chứa khách hàng và mô tả.

Nói cách khác, hóa đơn thường không được lưu trữ theo cùng một cách chúng được hiển thị.


3

Về mặt nào đó, bạn đúng: Cả hai đều đề cập đến cùng một tên miền, được gọi là order. Nhưng bạn đã sai ở xa, nó không phải là một bản sao thực sự hơn một đại diện khác - bắt nguồn từ các mục đích khác nhau. Nếu bạn muốn duy trì đơn hàng của mình, bạn muốn truy cập vào từng cột. Nhưng bạn không muốn rò rỉ ra bên ngoài. Bên cạnh việc đẩy toàn bộ Thực thể qua dây không phải là điều bạn thực sự muốn. Tôi biết các trường hợp, trong đó một tập hợp MB ordersđược chuyển đến máy khách trong đó một vài kb là đủ.

Để làm cho một câu chuyện dài ngắn - đây là những lý do chính bạn muốn làm điều đó:

1) Đóng gói - Thông tin ẩn ứng dụng của bạn

2) Mô hình nhỏ rất nhanh để tuần tự hóa và dễ truyền

3) Chúng phục vụ các mục đích khác nhau, mặc dù sự chồng chéo, và do đó nên có các đối tượng khác nhau.

4) Đôi khi nó có ý nghĩa đối với các Truy vấn khác nhau Các đối tượng Giá trị khác nhau . Tôi không biết nó như thế nào trong C #, nhưng trong Java có thể sử dụng POJO để thu thập kết quả. Nếu tôi cần một đơn hàng, ordertôi sử dụng Đơn hàng -Entity, nhưng nếu tôi chỉ cần một số cột chứa đầy số lượng trên dữ liệu, sử dụng các Đối tượng nhỏ hơn sẽ hiệu quả hơn.


Cách cấu trúc khung thực thể, các thực thể là các đối tượng C # cũ đơn giản, vì vậy việc gửi chúng qua dây không thực sự là vấn đề. Tôi thấy tiện ích của việc có thể gửi chỉ một phần nội dung của một đơn đặt hàng trong một số trường hợp.
Robert Ricketts

Một hoặc một bó không phải là vấn đề như tôi đã nói. Nhưng có những trường hợp, trong đó bạn có MB dữ liệu, làm chậm thời gian tải của bạn. Hãy nghĩ về thời gian tải di động
Thomas Junk

0

(Tuyên bố miễn trừ trách nhiệm: Tôi chỉ thấy nó được sử dụng theo cách này. Tôi có thể đã hiểu sai mục đích thực sự của việc này. Hãy đối xử với câu trả lời này bằng sự nghi ngờ.)

Đây là một bit còn thiếu: chuyển đổi giữa OrderOrderModel.

Các Orderlớp học được gắn với ORM của bạn, trong khi OrderModelđược gắn với việc thiết kế Xem các mẫu của bạn.

Thông thường, hai phương thức sẽ được cung cấp "một cách kỳ diệu" (đôi khi được gọi là DI, IoC, MVVM hoặc một thứ khác). Đó là, thay vì thực hiện hai phương thức chuyển đổi này như một phần của OrderModel, chúng sẽ thay vào đó thuộc về một lớp dành riêng cho việc chuyển đổi giữa các thứ này; lớp đó sẽ được đăng ký bằng cách nào đó với khung để khung có thể dễ dàng tra cứu nó.

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

Lý do để làm điều này là bất cứ khi nào có một giao thoa từ OrderModelđến Orderhoặc ngược lại, bạn biết rằng một số dữ liệu phải được tải từ hoặc lưu vào ORM.


Nếu tôi giữ cả hai xung quanh, tôi chắc chắn muốn thiết lập chúng để chuyển đổi được tự động hơn
Robert Ricketts

@RobertRicketts Điều tôi thấy giống như thế này: IMvxValueConverter . Mặc dù tôi có thể đã hiểu sai mục đích của nó.
rwong
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.