มันเป็น "รูปแบบกลิ่น" ที่จะนำตัวแบบเช่น "FullName" หรือ "FormattedPhoneNumber" ในรุ่นของคุณหรือไม่?


13

ฉันกำลังทำงานกับแอพ ASP.NET MVC และฉันเริ่มติดนิสัยในการวางสิ่งที่ดูเหมือนว่า getters ที่เป็นประโยชน์และสะดวกในคลาส / โมเดลเอนทิตีของฉัน

ตัวอย่างเช่น:

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); }
    }
}

ฉันสงสัยว่าคนที่คิดเกี่ยวกับFullNameและFormattedPhoneNumbergetters

พวกเขาทำให้ง่ายต่อการสร้างรูปแบบข้อมูลที่เป็นมาตรฐานทั่วทั้งแอพและดูเหมือนว่าจะบันทึกรหัสซ้ำจำนวนมาก แต่อาจเป็นที่ถกเถียงกันอยู่ว่ารูปแบบข้อมูลนั้นเป็นสิ่งที่ควรจัดการในการทำแผนที่จากแบบจำลองไปยังแบบจำลอง

ที่จริงแล้วฉันเดิมใช้รูปแบบข้อมูลเหล่านี้ในชั้นบริการของฉันที่ฉันทำแผนที่ของฉัน แต่มันก็กลายเป็นภาระที่ต้องเขียน formatters อย่างต่อเนื่องแล้วนำไปใช้ในหลาย ๆ ที่ เช่นฉันใช้ "ชื่อเต็ม" ในมุมมองส่วนใหญ่และต้องพิมพ์บางสิ่งบางอย่างเหมือนmodel.FullName = MappingUtilities.GetFullName(entity.FirstName, entity.LastName);ทั่วสถานที่ดูเหมือนจะดูสง่างามกว่าการพิมพ์เพียงเล็กน้อยmodel.FullName = entity.FullName(หรือถ้าคุณใช้บางอย่างเช่น AutoMapper อาจไม่พิมพ์อะไรเลย)

ดังนั้นคุณจะวาดเส้นที่ไหนเมื่อมันมาถึงการจัดรูปแบบข้อมูล "โอเค" ในการจัดรูปแบบข้อมูลในโมเดลของคุณหรือเป็น "กลิ่นของรูปแบบ" หรือไม่?

หมายเหตุ: ฉันไม่มี html ใด ๆ ในแบบจำลองของฉัน ฉันใช้ตัวช่วย html เพื่อสิ่งนั้น ฉันกำลังพูดถึงการจัดรูปแบบหรือการรวมข้อมูลอย่างเคร่งครัด (และโดยเฉพาะอย่างยิ่งข้อมูลที่ใช้บ่อย)


1
การทำเช่นนี้จะสะดวก แต่หวังและอธิษฐานว่าคุณไม่จำเป็นต้องทำให้รหัสนั้นเป็นสากล
btilly

@billy จุดดี แต่ฉันประมาณ 99.99% มั่นใจว่าฉันจะไม่
devuxer

เฉพาะกับ FullName และ PhoneNumber อย่างแน่นอน คำถามเกี่ยวกับคำถามเหล่านั้นเป็นพิเศษเพราะมีรูปแบบที่ไม่สอดคล้องกันในวัฒนธรรมที่แตกต่างกันหรือ @DanM เลือกตัวอย่างที่ไม่เป็นสากลสำหรับคำถามทั่วไปที่มากขึ้นหรือไม่?
เกร็กแจ็คสัน

@ Greg Jackson แน่นอนบันได ตามที่ ammoQ ชี้ให้เห็นPhoneNumberอาจเป็นของชั้นเรียนของตัวเอง (ซึ่งตอนนี้ฉันได้นำไปใช้แล้ว) แต่FullNameเป็นคนที่กระตุ้นให้ฉันเขียนคำถาม แต่ฉันสนใจที่จะทราบว่าโดยทั่วไปแล้วมันสมเหตุสมผลที่จะนำการจัดรูปแบบ / การจัดเรียงข้อมูล ฯลฯ ในโมเดลสำหรับสิ่งต่าง ๆ ที่จะใช้กับแอป จากคำตอบด้านล่างดูเหมือนว่านี่ไม่ใช่รูปแบบต่อต้าน แต่ควรตัดสินใจอย่างรอบคอบ
devuxer

โปรดทราบว่าการจัดรูปแบบเฉพาะสำหรับชื่อเต็มอาจไม่เป็นสากลเช่นกัน ยกตัวอย่างเช่นในเอเชียตะวันออกคำสั่งชื่อนั้นตรงกันข้ามกับสิ่งที่อยู่ในโลกตะวันตก คุณต้องการจัดการกับสิ่งนี้จริงๆหรือ? อาจจะไม่ใช่ แต่จำไว้ว่ามีหลายสิ่งที่คุณจะเจอเมื่อทำการฟอร์แมตข้อมูล
เกร็กแจ็คสัน

คำตอบ:


9

ในตัวอย่างของคุณฉันชอบFullNameทะเยอทะยาน (ด้วยเหตุผลทั้งหมดที่คุณให้) แต่ฉันไม่ชอบฟอร์แมต เหตุผลก็คือ: มันอาจไม่ใช่เรื่องง่าย (เมื่อคุณมีหมายเลขโทรศัพท์ระหว่างประเทศเป็นต้น) และถ้าคุณวางตรรกะในการจัดรูปแบบหมายเลขโทรศัพท์ด้วยวิธีการMemberโอกาสที่คุณจะต้อง refactor (หรือคัดลอกวางcaugh ) เมื่อคุณ จำเป็นต้องมีการจัดรูปแบบหมายเลขโทรศัพท์สำหรับInstitution, Vendorฯลฯ เกินไป

แก้ไข: IMO มันจะดีกว่าที่จะมีPhoneNumberชั้นเรียนที่มีFormattedทะเยอทะยาน


+1 และขอบคุณ แต่ถ้าฉันใส่รหัสการจัดรูปแบบหมายเลขโทรศัพท์ในวิธีการต่อเติมจริง จากนั้นโมเดลใด ๆ ก็สามารถใช้งานได้และจะไม่มีการปรับโครงสร้างหรือคัดลอก / วาง โซลูชันนี้จะยังคงซ้ำซ้อนน้อยกว่าการใช้ตัวจัดรูปแบบกับหมายเลขโทรศัพท์ทุกหมายเลขที่ปรากฏในทุกมุมมอง
devuxer

3
การใช้วิธีการขยายสำหรับสิ่งนั้นจะเป็นวิธีที่รวดเร็วในการแยกสลาย "functional functional" โดยใช้วิธีการขยาย (สำหรับStringชั้นเรียนฉันถือว่า) คุณ "สอน" Stringวิธีการจัดรูปแบบหมายเลขโทรศัพท์ในชั้นเรียน เป็นความรับผิดชอบของStringชั้นเรียนที่จะรู้เกี่ยวกับหมายเลขโทรศัพท์หรือไม่ ฉันไม่คิดอย่างนั้น ใช้วิธีการดังกล่าวเป็นส่วนเสริมในการสร้างประโยคเพื่อให้สิ่งที่ชัดเจนไม่ใช่แบบเชิงวัตถุ
281377

1
โอเคลืมฉันว่าวิธีการขยาย แกล้งทำเป็นว่าวิธีการยูทิลิตี้หรือชั้นเรียนจัดรูปแบบ ฉันเพียงแค่บอกว่าการวาง / คัดลอกวางใหม่ไม่ควรจำเป็นโดยไม่คำนึงว่าฉันมีตัวรับรุ่นหรือทำการจัดรูปแบบที่อื่น
devuxer

1
และฉันชอบความคิดของPhoneNumberชั้นเรียน ฉันวางแผนที่จะทำเช่นนั้นเพราะฉันมีPhoneTypeทรัพย์สินด้วย
devuxer

ฉันไม่ชอบความคิดที่มีPhoneNumberคลาสอินสแตนซ์เนื่องจากข้อมูลนั้นเป็นแบบstringดั้งเดิม public static string Format(string phoneNumber, PhoneNumberStyle style)แต่ก็ควรจะมีระดับคงที่ด้วยวิธีการเช่น
นายแอนเดอร์สัน

5

สิ่งที่คุณต้องพิจารณาเมื่อเขียนรหัส: ถูกต้องหรือไม่ มันอ่านได้หรือไม่ มันมีประสิทธิภาพหรือไม่ มันสามารถบำรุงรักษาได้หรือไม่? ฉันจะโต้แย้งอย่างที่ @btilly พูดถึงว่ามันไม่สามารถบำรุงรักษาได้เนื่องจากการจัดรูปแบบเฉพาะวัฒนธรรม แต่คำถามดูเหมือนจะเป็นเรื่องทั่วไปมากกว่านั้น

การใช้ accessors เช่นนี้ทำให้โค้ดของคุณอ่านง่ายขึ้นและขึ้นอยู่กับว่าคุณใช้มันอย่างไรอาจทำให้ส่วนอื่น ๆ ของโค้ดของคุณสะอาดขึ้น ในความคิดของฉันมันไม่ได้มีกลิ่นเลย มันจะเริ่มมีกลิ่นถ้าคุณมีการจัดรูปแบบ accessors สำหรับสตริงชนิดใด ๆ ที่คุณอาจต้องการพิมพ์ ( public string FirstLastName; public string FullName; public string FullNameWithMiddleInitial; public string PhoneNumberWithAreaCode; public string PhoneNumberWithoutAreaCode; public string PhoneNumberWithCountryCode;ฯลฯ )

หรืออีกวิธีหนึ่งการใช้รูปแบบไม่ทำให้รหัสของคุณมี "รูปแบบกลิ่น" โดยอัตโนมัติ คุณต้องใช้มันหากคุณต้องการที่จะได้รับคุณลักษณะนั้น


ขอบคุณเกรก +1 ฉันเห็นด้วยกับคุณเกี่ยวกับการรวมกันทุกชุด ฉันแค่พยายามหาวิธีที่สะอาดที่สุดเพื่อสร้างมาตรฐานให้กับการดูข้อมูล
devuxer

3

แบ่งหลักการความรับผิดชอบเดียว ทำไมไม่สร้างคลาสหมายเลขโทรศัพท์ ฯลฯ ...


ตกลงฉันเห็นด้วยกับที่จริง (ดูการสนทนาภายใต้คำตอบของ ammoQ) แต่ฉันควรจะทำFullNameชั้นเรียนด้วยหรือไม่
devuxer

ใช่คุณควร แต่คุณควรแก้ไขการสะกดจาก "FullName" เป็น "FoolName" หรืออาจเป็น "PersonalName" เนื่องจากเป็นชื่อของบุคคลและไม่ใช่ชื่อเต็ม
วินไคลน์

1
จริงๆ? หากชั้นเรียนที่คาดหวังจะเติบโตขึ้นสิ่งที่ผิดกับมันคืออะไร? แม้ว่ามันจะเติบโตขึ้นมันยากแค่ไหนที่จะพิจารณาปัจจัยใหม่อีกครั้ง?
งาน

@DanM: นั่นคือสิ่งที่คุณขอเช่นขอให้พวกเขาพิมพ์ชื่อเต็มตามกฎหมาย หากคุณเรียงลำดับตามชื่อคุณจะเรียงลำดับตามตัวอักษรแรก (ตามด้วยตัวอักษรที่สองและอื่น ๆ ) ของชื่อจริง (ตามด้วยตัวอักษรถัดไปและต่อไปเรื่อย ๆ ) ดังนั้นชื่อจะเรียงลำดับเหมือนกันโดยไม่คำนึงถึง
Matt Ellen


1

สำหรับตัวอย่างของคุณฉันไม่เห็นข้อตกลงที่จะใช้รูปแบบที่เฉพาะเจาะจงมากเกินไป มันเป็นหนึ่งหรือสองส่วนและทุกส่วนของแอปพลิเคชันใช้รูปแบบเดียวกัน

ไหนว่าการตัดสินใจจะเริ่มต้นที่จะทำลายลงคือเมื่อคุณมีข้อมูลเดียวกันจะไปยังสถานที่ที่แตกต่างกันกำหนดรูปแบบที่แตกต่างกัน

หากสิ่งนั้นเกิดขึ้นฉันจะถูกล่อลวงให้ดึงMemberชั้นเรียนกลับไปที่:

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

จากนั้นทำอะแดปเตอร์ที่แตกต่างกันสำหรับแต่ละเป้าหมาย ตัวอย่างเช่นสมมติว่าข้อมูลนั้นจำเป็นในรูปแบบ CSV:

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

สมมติว่าคุณได้ทำการล้างข้อมูลให้เสมอเพื่อไม่ให้มีเครื่องหมายจุลภาค ฯลฯ อยู่ในสตริง

อะแดปเตอร์ไม่จำเป็นต้องเป็นวิธีการขยาย แต่สำหรับกรณีที่เชื่อว่ามันดูเหมือนจะพอดี


เป็นเวลานานแล้วที่ฉันได้เขียน C # แต่แน่นอนว่ามีคลาสการทำให้เป็นอนุกรมที่สามารถจัดการกับสิ่งนี้ได้แทนที่จะใช้วิธีการเขียนที่น่าเบื่ออย่าง tocsv ซ้ำไปซ้ำมาซ้ำแล้วซ้ำเล่า เป็นวรรคเป็นเวรซ้ำแล้วซ้ำอีก ...
วินไคลน์

@ ไคลน์ไคลน์: มันขึ้นอยู่กับสิ่งที่คุณต้องการในแต่ละอ่าง หากสิ่งที่พวกเขาต้องการคือ XML ที่เป็นอนุกรมปรับ ระบบจำนวนมากทำไม่ได้ หากต้องทำoverหลายครั้งเท่านี้แสดงว่ามีบางอย่างผิดปกติกับการออกแบบ
Peter K.

โดยทั่วไปจะมีหลายคลาสให้เป็นอันดับ มันควรจะเป็นไปได้ที่จะเขียน CSV เดียวหรือ serializer อื่น ๆ ที่สามารถจัดการเรียนส่วนใหญ่ผ่านการสะท้อนมากกว่าการเขียนโค้ดด้วยมือเหมือนตัวอย่างของคุณ
วินไคลน์

@kevin cline: เห็นด้วยอย่างรุนแรง! ฉันแค่เขียนสิ่งที่เฉพาะเจาะจงมากสำหรับคำถามที่ถาม ตัวอย่างคอนกรีตที่เรียบง่ายมักจะอธิบายสิ่งต่าง ๆ ได้ดีขึ้น
Peter K.
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.