Đây có phải là một mô hình mùi của người khác để đặt các getters như là Full Full tên hay hay FormattedPhoneNumber INTERN trong mô hình của bạn không?


13

Tôi đang làm việc trên một ứng dụng ASP.NET MVC và tôi đã có thói quen đưa những thứ có vẻ như hữu ích và tiện lợi vào các lớp mô hình / thực thể của tôi.

Ví dụ:

public class Member
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string PhoneNumber { get; set; }

    public string FullName
    {
        get { return FirstName + " " + LastName; }
    }

    public string FormattedPhoneNumber
    {
        get { return "(" + PhoneNumber.Substring(0, 3) + ") " + PhoneNumber.Substring(3, 3) + "-" + PhoneNumber.Substring(6); }
    }
}

Tôi đang tự hỏi mọi người nghĩ về FullNameFormattedPhoneNumbergetters.

Chúng giúp dễ dàng tạo các định dạng dữ liệu được tiêu chuẩn hóa trong ứng dụng và dường như chúng lưu rất nhiều mã lặp lại, nhưng chắc chắn có thể lập luận rằng định dạng dữ liệu là thứ cần được xử lý trong ánh xạ từ mô hình sang mô hình xem.

Trên thực tế, ban đầu tôi đã áp dụng các định dạng dữ liệu này trong lớp dịch vụ của mình, nơi tôi thực hiện ánh xạ của mình, nhưng nó trở thành gánh nặng khi phải liên tục phải viết các trình định dạng sau đó áp dụng chúng ở nhiều nơi khác nhau. Ví dụ: tôi sử dụng "Tên đầy đủ" trong hầu hết các chế độ xem và phải nhập một cái gì đó giống như model.FullName = MappingUtilities.GetFullName(entity.FirstName, entity.LastName);mọi nơi có vẻ thanh lịch hơn nhiều so với chỉ gõ model.FullName = entity.FullName(hoặc, nếu bạn sử dụng một cái gì đó như AutoMapper, có khả năng không gõ gì cả).

Vì vậy, nơi bạn vẽ đường khi định dạng dữ liệu. Là "ổn" để thực hiện định dạng dữ liệu trong mô hình của bạn hay đó là "mùi mẫu"?

Lưu ý: Tôi chắc chắn không có bất kỳ html nào trong mô hình của mình. Tôi sử dụng trợ giúp html cho việc đó. Tôi nghiêm túc nói về định dạng hoặc kết hợp dữ liệu (và đặc biệt là dữ liệu thường được sử dụng).


1
Làm điều này có thể được thuận tiện. Nhưng hy vọng và cầu nguyện rằng bạn không bao giờ phải quốc tế hóa mã đó.
btilly

@btilly, điểm tốt, nhưng tôi tự tin khoảng 99,99% rằng tôi sẽ không.
devuxer

Cụ thể với FullName và PhoneNumber, chắc chắn. Là câu hỏi cụ thể về những câu hỏi đó bởi vì chúng có định dạng không nhất quán ở các nền văn hóa khác nhau, hoặc @DanM chỉ đơn giản chọn các ví dụ không quốc tế hóa tốt cho câu hỏi chung chung hơn?
Greg Jackson

@Greg Jackson, chắc chắn là cái thang. Như ammoQ đã chỉ ra, PhoneNumbercó lẽ thuộc về lớp của chính nó (mà bây giờ tôi đã thực hiện). Nhưng FullNameđó thực sự là một trong những động lực thúc đẩy tôi viết câu hỏi. Nhưng tôi quan tâm đến việc tìm hiểu xem, nói chung, có ý nghĩa gì khi đặt định dạng / kết hợp dữ liệu, v.v. trong mô hình cho những thứ sẽ áp dụng trên toàn ứng dụng hay không. Từ các câu trả lời dưới đây, có vẻ như đây không phải là một mô hình chống đối, nhưng quyết định nên được đưa ra một cách cẩn thận.
devuxer

Hãy nhớ rằng định dạng cụ thể này cho tên đầy đủ cũng có thể không quốc tế hóa tốt. Ví dụ, ở Đông Á, thứ tự tên ngược lại với thế giới phương Tây. Bạn có thực sự cần phải xử lý rõ ràng điều này? Có thể không, nhưng chỉ cần nhớ rằng có rất nhiều điều khó khăn bạn sẽ gặp phải khi định dạng dữ liệu.
Greg Jackson

Câu trả lời:


9

Trong ví dụ của bạn, tôi thích FullNamegetter (vì tất cả các lý do bạn đã đưa ra) nhưng tôi không thích getter FormattedPhoneNumber. Lý do là: có thể không dễ dàng như vậy (một khi bạn có số điện thoại quốc tế, v.v.) và nếu bạn đặt logic để tạo số điện thoại theo phương pháp Member, rất có thể bạn sẽ cần phải cấu trúc lại (hoặc sao chép-dán caugh ) một khi bạn cần một số điện thoại hình thành cho Institution, Vendorvv quá.

EDIT: IMO sẽ tốt hơn nếu có một PhoneNumberlớp học với một Formattedgetter.


+1 và cảm ơn. Nhưng nếu tôi thực sự đặt mã định dạng số điện thoại của mình trong một phương thức mở rộng thì sao? Sau đó, bất kỳ mô hình nào cũng có thể sử dụng nó và sẽ không có cấu trúc lại hoặc sao chép / dán. Giải pháp này vẫn sẽ ít lặp đi lặp lại hơn là áp dụng công cụ định dạng cho mọi số điện thoại xuất hiện trong mọi chế độ xem.
devuxer

3
Sử dụng một phương pháp mở rộng cho điều đó sẽ là một cách nhanh chóng để phản đối "phân rã chức năng". Bằng cách sử dụng một phương thức mở rộng (đối với Stringlớp, tôi giả sử), bạn "dạy" Stringlớp cách định dạng số điện thoại. Có thực sự là trách nhiệm của Stringlớp để biết về số điện thoại? Tôi không nghĩ vậy. Được sử dụng như vậy, các phương thức mở rộng là đường cú pháp để cho thứ gì đó rõ ràng không hướng đối tượng trông giống như nó.
user281377

1
Được rồi, quên tôi nói phương pháp mở rộng. Giả sử tôi nói phương thức tiện ích hoặc lớp định dạng. Tôi chỉ đơn giản nói rằng tái cấu trúc / sao chép không cần thiết, bất kể tôi có trình tạo mô hình hay thực hiện định dạng ở nơi nào khác không.
devuxer

1
Và tôi thích ý tưởng của một PhoneNumberlớp học. Tôi đã lên kế hoạch để làm điều đó bởi vì tôi cũng có một PhoneTypetài sản.
devuxer

Tôi không thích ý tưởng có PhoneNumbermột lớp thể hiện vì dữ liệu là nguyên bản string. Thay vào đó, nó phải là một lớp tĩnh với các phương thức như public static string Format(string phoneNumber, PhoneNumberStyle style).
Ông Anderson

5

Những điều bạn cần xem xét khi viết mã: Có đúng không? Có đọc được không? Có hiệu quả không? Có thể duy trì? Tôi sẽ lập luận, như @btilly đã đề cập, rằng nó không thể duy trì được do định dạng văn hóa cụ thể, nhưng câu hỏi dường như khái quát hơn rằng.

Sử dụng các bộ truy cập như thế này làm cho mã của bạn dễ đọc hơn và, tùy thuộc vào cách bạn sử dụng nó, có thể làm cho các phần khác trong mã của bạn sạch hơn nhiều. Theo tôi, điều đó không có mùi gì cả. Nó sẽ bắt đầu có mùi nếu bạn có các bộ truy cập Định dạng cho bất kỳ loại chuỗi nào bạn có thể muốn in ( public string FirstLastName; public string FullName; public string FullNameWithMiddleInitial; public string PhoneNumberWithAreaCode; public string PhoneNumberWithoutAreaCode; public string PhoneNumberWithCountryCode;, v.v.)

Hoặc, nói cách khác, sử dụng một mẫu không tự động làm cho mã của bạn có "mùi mẫu". Bạn cần phải lạm dụng nó nếu bạn muốn kiếm được thuộc tính đó.


Cảm ơn, Greg. +1. Tôi đồng ý với bạn về việc đặt mọi sự kết hợp. Tôi thực sự chỉ đang cố gắng đưa ra cách sạch nhất để chuẩn hóa cách xem dữ liệu.
devuxer

3

Phá vỡ nguyên tắc trách nhiệm duy nhất. Tại sao không tạo một lớp số điện thoại, vv ...?


Được rồi, tôi thực sự đồng ý với điều đó (xem thảo luận dưới câu trả lời của ammoQ), nhưng tôi cũng nên tạo một FullNamelớp học?
devuxer

Có, bạn nên, nhưng bạn nên sửa lỗi chính tả từ "FullName" thành "FoolName". Hoặc có thể là "PersonalName", vì đó là tên của một người, và không phải là đầy đủ.
kevin cline

1
Có thật không? Trừ khi lớp đã cho được dự kiến ​​sẽ phát triển, chính xác thì điều gì là sai với nó? Ngay cả khi nó phát triển, làm thế nào khó khăn để tái yếu tố sau đó?
Công việc

@DanM: Sau đó, đó là những gì bạn yêu cầu, tức là yêu cầu họ nhập tên hợp pháp đầy đủ của họ. Nếu bạn sắp xếp theo tên, bạn thực sự sắp xếp chữ cái đầu tiên (sau đó là thứ hai, v.v.) của tên đầu tiên (sau đó tiếp theo, v.v.), vì vậy các tên sẽ sắp xếp giống nhau bất kể.
Matt Ellen


1

Ví dụ của bạn, tôi không thấy việc sử dụng các định dạng cụ thể là một vấn đề quá lớn. Đó là một hoặc hai và tất cả các phần của ứng dụng sử dụng cùng một định dạng.

Trường hợp quyết định đó sẽ bắt đầu bị phá vỡ là khi bạn có cùng một dữ liệu đi đến một số nơi khác nhau yêu cầu các định dạng khác nhau .

Nếu điều đó xảy ra, tôi muốn lôi kéo Memberlớp học trở lại:

public class Member
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string PhoneNumber { get; set; }  
}

Và sau đó làm các bộ điều hợp khác nhau cho từng mục tiêu. Ví dụ: giả sử thông tin được yêu cầu ở định dạng CSV:

public static class CSVMemberAdapter
{
    public static string ToCSV(this Member mbr)
    {
         return mbr.Id + "," + mbr.LastName + "," + mbr.FirstName, "," mbr.PhoneNumber;
    }
}

Luôn luôn giả định rằng bạn đã vệ sinh dữ liệu để không có dấu phẩy, v.v.

Bộ điều hợp không phải là một phương pháp mở rộng, nhưng đối với trường hợp giả tạo này, nó có vẻ phù hợp.


Đã được một thời gian kể từ khi tôi viết C #, nhưng chắc chắn có các lớp tuần tự hóa có thể xử lý việc này, thay vì các phương pháp viết tẻ nhạt như lặp đi lặp lại nhiều lần và lặp đi lặp lại nhiều lần và hơn và hơn và hơn và hơn và hơn ...
kevin cline

@kevin cline: Nó phụ thuộc vào những gì bạn cần ở mỗi bồn rửa. Nếu tất cả những gì họ cần là XML tuần tự, tốt thôi. Nhiều hệ thống không. Nếu nó phải được thực hiện overnhiều lần như vậy, thì có gì đó không ổn với thiết kế.
Peter K

thông thường sẽ có nhiều lớp để tuần tự hóa. Có thể viết một CSV hoặc serializer khác có thể xử lý hầu hết các lớp thông qua sự phản chiếu, thay vì mã hóa chúng như ví dụ của bạn.
kevin cline

@kevin cline: Đồng ý dữ dội! Tôi chỉ đang viết một cái gì đó rất cụ thể cho câu hỏi được hỏi. Cụ thể, ví dụ đơn giản có xu hướng giải thích mọi thứ tốt hơn.
Peter K.
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.