วิธีทำให้การสร้างโหมดดูที่รันไทม์เจ็บปวดน้อยลง


17

ฉันขอโทษสำหรับคำถามยาว ๆ มันอ่านได้เล็กน้อยว่าเป็นคำโหยหวน แต่ฉันสัญญาว่ามันจะไม่! ฉันได้สรุปคำถามของฉันด้านล่าง

ในโลกของ MVC สิ่งต่าง ๆ ตรงไปตรงมา รูปแบบมีสถานะมุมมองแสดงรูปแบบและตัวควบคุมทำสิ่งต่าง ๆ เพื่อ / กับรุ่น (โดยทั่วไป) ตัวควบคุมไม่มีสถานะ ในการทำสิ่งต่าง ๆ ที่คอนโทรลเลอร์มีการขึ้นต่อกันของบริการบนเว็บ, ที่เก็บ, ล็อต เมื่อคุณยกตัวอย่างคอนโทรลเลอร์ที่คุณสนใจเกี่ยวกับการจัดหาการพึ่งพาเหล่านั้นไม่มีอะไรอื่น เมื่อคุณเรียกใช้การกระทำ (เมธอดบนตัวควบคุม) คุณใช้การอ้างอิงเหล่านั้นเพื่อดึงหรืออัปเดตโมเดลหรือเรียกบริการโดเมนอื่น ๆ หากมีบริบทใด ๆ ให้พูดเช่นผู้ใช้บางคนต้องการดูรายละเอียดของรายการใดรายการหนึ่งคุณจะส่ง Id ของรายการนั้นเป็นพารามิเตอร์ไปยัง Action ไม่มีที่ใดในคอนโทรลเลอร์มีการอ้างอิงถึงสถานะใด ๆ จนถึงตอนนี้ดีมาก

ป้อน MVVM ฉันรัก WPF ฉันรักการผูกข้อมูล ฉันรักเฟรมเวิร์กที่ทำให้การผูกข้อมูลกับ ViewModels ง่ายยิ่งขึ้น (โดยใช้ Caliburn Micro atm) ฉันรู้สึกว่าสิ่งต่าง ๆ ตรงไปตรงมาน้อยในโลกนี้แม้ว่า ลองทำแบบฝึกหัดอีกครั้ง: Model มีสถานะวิวจะแสดง ViewModel และ ViewModel จะทำสิ่งต่าง ๆ ให้กับ / กับ Model (โดยทั่วไป) ViewModel จะมีสถานะ! (เพื่อชี้แจง; บางทีมันอาจจะได้รับมอบหมายคุณสมบัติทั้งหมดที่หนึ่งหรือมากกว่าหนึ่งรุ่น แต่นั่นหมายความว่าจะต้องมีการอ้างอิงถึงรูปแบบหรืออีกวิธีหนึ่งซึ่งเป็นของรัฐในตัวเอง) ในการทำสิ่งที่ ViewModel มีขึ้นอยู่กับการให้บริการของเว็บพื้นที่เก็บข้อมูลจำนวนมาก เมื่อคุณสร้างอินสแตนซ์ ViewModel ให้คุณสนใจเกี่ยวกับการจัดหาการพึ่งพาเหล่านั้น แต่ยังรวมถึงสถานะด้วย และนี่คือสุภาพสตรีและสุภาพบุรุษทำให้ฉันรำคาญใจไม่สิ้นสุด

เมื่อใดก็ตามที่คุณต้องการยกตัวอย่างProductDetailsViewModelจากProductSearchViewModel(จากสิ่งที่คุณเรียกว่าสิ่งProductSearchWebServiceที่กลับมาIEnumerable<ProductDTO>ทุกคนยังคงอยู่กับฉัน) คุณสามารถทำสิ่งใดสิ่งหนึ่งต่อไปนี้:

  • โทรnew ProductDetailsViewModel(productDTO, _shoppingCartWebService /* dependcy */);นี่มันไม่ดีลองนึกภาพการขึ้นต่อกันอีก 3 ครั้งนั่นหมายถึงProductSearchViewModelความจำเป็นในการพึ่งพาเหล่านั้นเช่นกัน การเปลี่ยนคอนสตรัคเตอร์ก็เจ็บปวดเช่นกัน
  • โทร_myInjectedProductDetailsViewModelFactory.Create().Initialize(productDTO);โรงงานเป็นเพียง Func พวกเขาสร้างขึ้นได้อย่างง่ายดายโดยกรอบ IoC ส่วนใหญ่ ฉันคิดว่ามันไม่ดีเพราะวิธีการเริ่มต้นเป็นสิ่งที่เป็นนามธรรมรั่วไหล คุณไม่สามารถใช้คำหลักแบบอ่านอย่างเดียวสำหรับเขตข้อมูลที่ตั้งค่าในวิธีการเริ่มต้น ฉันแน่ใจว่ามีเหตุผลอีกสองสามข้อ
  • โทร_myInjectedProductDetailsViewModelAbstractFactory.Create(productDTO);ดังนั้น ... นี่คือรูปแบบ (โรงงานนามธรรม) ที่มักจะแนะนำสำหรับปัญหาประเภทนี้ ฉันแม้ว่ามันจะเป็นอัจฉริยะเพราะมันสนองความอยากของฉันในการพิมพ์แบบคงที่จนกว่าฉันจะเริ่มใช้มัน จำนวนรหัส boilerplate คือฉันคิดว่ามากเกินไป (คุณรู้นอกเหนือจากชื่อตัวแปรไร้สาระที่ฉันได้ใช้) สำหรับ ViewModel แต่ละตัวที่ต้องการพารามิเตอร์แบบรันไทม์คุณจะได้รับไฟล์เพิ่มเติมสองไฟล์ (ส่วนต่อประสานจากโรงงานและการนำไปใช้งาน) และคุณต้องพิมพ์การขึ้นต่อแบบไม่ใช้งานจริงเช่น 4 ครั้งเพิ่มเติม และทุกครั้งที่มีการเปลี่ยนแปลงการพึ่งพาคุณจะได้รับการเปลี่ยนแปลงในโรงงานเช่นกัน รู้สึกเหมือนฉันไม่ได้ใช้ DI container อีกต่อไป (ฉันคิดว่า Castle Windsor มีวิธีแก้ปัญหาบางอย่างสำหรับเรื่องนี้ [ด้วยข้อเสียของตัวเองแก้ไขฉันถ้าฉันผิด])
  • ทำอะไรกับประเภทหรือพจนานุกรมที่ไม่ระบุชื่อ ฉันชอบการพิมพ์แบบคงที่ของฉัน

ดังนั้นใช่ การผสมสถานะและพฤติกรรมในลักษณะนี้จะสร้างปัญหาที่ไม่มีอยู่ใน MVC และฉันรู้สึกว่าในปัจจุบันยังไม่มีวิธีแก้ปัญหาที่เพียงพอสำหรับปัญหานี้ ตอนนี้ฉันต้องการสังเกตบางสิ่ง:

  • ผู้คนใช้ MVVM จริง ดังนั้นพวกเขาจึงไม่สนใจทั้งหมดข้างต้นหรือมีวิธีแก้ปัญหาอื่นที่ยอดเยี่ยม
  • ฉันไม่พบตัวอย่างเชิงลึกของ MVVM ด้วย WPF ตัวอย่างเช่นโครงการตัวอย่าง NDDD ช่วยฉันอย่างมากในการทำความเข้าใจแนวคิด DDD บางอย่าง ฉันชอบมันมากถ้ามีคนชี้ให้ฉันเห็นทิศทางของสิ่งที่คล้ายกันกับ MVVM / WPF
  • บางทีฉันอาจทำผิดพลาด MVVM และฉันควรพลิกการออกแบบของฉันให้คว่ำ บางทีฉันไม่ควรมีปัญหานี้เลย ฉันรู้ว่าคนอื่นถามคำถามเดียวกันดังนั้นฉันคิดว่าฉันไม่ใช่คนเดียว

เพื่อสรุป

  • ฉันถูกต้องหรือไม่ที่จะสรุปว่าการมี ViewModel เป็นจุดรวมสำหรับทั้งรัฐและพฤติกรรมเป็นสาเหตุของปัญหาบางอย่างกับรูปแบบ MVVM โดยรวมหรือไม่?
  • การใช้รูปแบบนามธรรมจากโรงงานเป็นวิธีเดียวที่ดีที่สุดในการสร้างอินสแตนซ์ ViewModel ด้วยวิธีการพิมพ์แบบคงที่หรือไม่
  • มีบางอย่างเช่นการใช้การอ้างอิงเชิงลึกหรือไม่
  • การมี ViewModels จำนวนมากที่มีทั้งสภาวะ / พฤติกรรมมีกลิ่นของการออกแบบหรือไม่?

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

คุณบอกว่าคุณรัก Caliburn.Micro แต่คุณไม่รู้ว่าเฟรมเวิร์กนี้สามารถช่วยยกตัวอย่างโมเดลมุมมองใหม่ได้อย่างไร ตรวจสอบตัวอย่างของมัน
ร่าเริง

@Eehoric คุณอาจจะเจาะจงไปกว่านี้เล็กน้อย Google ดูเหมือนจะไม่ช่วยฉันที่นี่ มีคำค้นหาที่ฉันสามารถค้นหาได้หรือไม่
dvdvorle

3
ฉันคิดว่าคุณกำลังทำให้ MVC ง่ายขึ้นเล็กน้อย แน่นอนว่ามุมมองจะแสดงรุ่นที่จุดเริ่มต้น แต่ในระหว่างการดำเนินการมันเปลี่ยนสถานะ ในความคิดของฉันการเปลี่ยนแปลงนี้เป็น "แก้ไขแบบจำลอง" นั่นคือโมเดลรุ่นแบนที่มีข้อ จำกัด ที่สอดคล้องกันลดลง อันที่จริงสิ่งที่ฉันเรียกว่า Edit Model คือ MVVM ViewModel มันถือสถานะในขณะที่อยู่ในช่วงการเปลี่ยนภาพซึ่งก่อนหน้านี้เคยเป็นมุมมองใน MVC หรือผลักดันกลับสู่รุ่นที่ไม่มีข้อผูกมัดของโมเดลซึ่งฉันไม่คิดว่ามันเป็นของมัน ดังนั้นคุณจึงมีสถานะ "ในฟลักซ์" มาก่อน ตอนนี้ทุกอย่างใน ViewModel
Scott Whitlock

@ScottWhitlock ฉันทำให้ MVC ง่ายขึ้นอย่างแน่นอน แต่ฉันไม่ได้บอกว่ามันผิดที่รัฐ "ในฟลักซ์" อยู่ใน ViewModel ฉันกำลังบอกว่าการยัดเยียดพฤติกรรมในที่นั่นทำให้ยากที่จะเริ่มต้น ViewModel ให้เป็นสถานะที่ใช้งานได้จากการพูด ViewModel อื่น "แก้ไขโมเดล" ของคุณใน MVC ไม่ทราบวิธีบันทึกตัวเอง (ไม่มีวิธีบันทึก) แต่ผู้ควบคุมจะรู้เรื่องนี้และมีการพึ่งพาทั้งหมดที่จำเป็นในการทำเช่นนั้น
dvdvorle

คำตอบ:


2

ปัญหาของการพึ่งพาเมื่อเริ่มต้นรูปแบบมุมมองใหม่สามารถจัดการกับ IOC

public class MyCustomViewModel{
  private readonly IShoppingCartWebService _cartService;

  private readonly ITimeService _timeService;

  public ProductDTO ProductDTO { get; set; }

  public ProductDetailsViewModel(IShoppingCartWebService cartService, ITimeService timeService){
    _cartService = cartService;
    _timeService = timeService;
  }
}

เมื่อตั้งค่าคอนเทนเนอร์ ...

Container.Register<IShoppingCartWebService,ShoppingCartWebSerivce>().As.Singleton();
Container.Register<ITimeService,TimeService>().As.Singleton();
Container.Register<ProductDetailsViewModel>();

เมื่อคุณต้องการโมเดลมุมมองของคุณ:

var viewmodel = Container.Resolve<ProductDetailsViewModel>();
viewmodel.ProductDTO = myProductDTO;

เมื่อใช้เฟรมเวิร์กเช่นcaliburn microมักจะมีคอนเทนเนอร์ของ IOC บางรูปแบบอยู่แล้ว

SomeCompositionView view = new SomeCompositionView();
ISomeCompositionViewModel viewModel = IoC.Get<ISomeCompositionViewModel>();
ViewModelBinder.Bind(viewModel, view, null);

1

ฉันทำงานทุกวันกับ ASP.NET MVC และทำงานบน WPF มานานกว่าหนึ่งปีและนี่คือสิ่งที่ฉันเห็น:

MVC

คอนโทรลเลอร์ควรจะควบคุมการกระทำ (ดึงข้อมูลนี้เพิ่มเข้าไป)

มุมมองมีหน้าที่รับผิดชอบในการแสดงแบบจำลอง

โมเดลมักจะรวมข้อมูล (ตัวอย่างเช่น UserId, FirstName) และสถานะ (เช่นชื่อเรื่อง) และโดยทั่วไปจะดูเฉพาะ

MVVM

โดยทั่วไปโมเดลจะเก็บข้อมูลเท่านั้น (เช่น UserId, FirstName) และมักจะส่งผ่านไปมา

โมเดลมุมมองครอบคลุมพฤติกรรมของมุมมอง (เมธอด) ข้อมูล (โมเดล) และการโต้ตอบ (คำสั่ง) - คล้ายกับรูปแบบ MVP ที่ใช้งานอยู่ซึ่งผู้นำเสนอจะรับรู้รูปแบบ โมเดลมุมมองเป็นมุมมองที่เฉพาะเจาะจง (1 view = 1 มุมมองโมเดล)

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


สิ่งที่คุณควรจำไว้คือรูปแบบการนำเสนอ MVVM นั้นมีความเฉพาะเจาะจงกับ WPF / Silverlight เนื่องจากลักษณะการเชื่อมโยงข้อมูล

โดยทั่วไปมุมมองจะรู้ว่ามุมมองแบบใดที่สัมพันธ์กับ (หรือสิ่งที่เป็นนามธรรม)

ฉันขอแนะนำให้คุณปฏิบัติต่อโมเดลการดูเป็นซิงเกิลแม้ว่ามันจะถูกสร้างขึ้นตามการดู กล่าวอีกนัยหนึ่งคุณควรจะสามารถสร้างมันผ่าน DI ผ่านคอนเทนเนอร์ IOC และเรียกวิธีการที่เหมาะสมในการพูด; โหลดแบบจำลองตามพารามิเตอร์ บางสิ่งเช่นนี้

public partial class EditUserView
{
    public EditUserView(IContainer container, int userId) : this() {
        var viewModel = container.Resolve<EditUserViewModel>();
        viewModel.LoadModel(userId);
        DataContext = viewModel;
    }
}

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


หาก FirstName ของฉันคือ "Peter" และชื่อของฉันคือ {"Rev", "Dr"} * ทำไมคุณถึงพิจารณาข้อมูล FirstName และสถานะ Title หรือคุณสามารถอธิบายตัวอย่างของคุณ? * ไม่ได้จริงๆ
Pete Kirkham

@PeteKirkham - ตัวอย่าง 'ชื่อ' ที่ฉันอ้างถึงในบริบทของการพูดคอมโบ โดยทั่วไปเมื่อคุณส่งข้อมูลเพื่อยืนยันคุณจะไม่ส่งสถานะ (เช่นรายการรัฐ / จังหวัด / ชื่อเรื่อง) ที่ใช้ในการเลือกจาก ควรตรวจสอบสถานะที่คุ้มค่าที่จะถ่ายโอนด้วยข้อมูล (เช่นชื่อผู้ใช้ที่ใช้งาน) ณ จุดประมวลผลเนื่องจากสถานะอาจค้าง (ถ้าคุณใช้รูปแบบอะซิงโครนัสเช่นการจัดคิวข้อความ)
Shelakel

แม้ว่าจะผ่านไปสองปีแล้วตั้งแต่โพสต์นี้ฉันต้องแสดงความคิดเห็นเพื่อให้ผู้ชมในอนาคต: สองสิ่งรบกวนฉันด้วยคำตอบของคุณ มุมมองอาจสอดคล้องกับ ViewModel หนึ่งอัน แต่ ViewModel สามารถแสดงได้หลาย Views ประการที่สองสิ่งที่คุณอธิบายคือรูปแบบการป้องกันของผู้ให้บริการ IMHO คุณไม่ควรแก้ไข viewmodels โดยตรงทุกที่ นั่นคือสิ่งที่ DI สำหรับ ทำให้การแก้ไขของคุณในจุดที่น้อยที่สุดเท่าที่จะทำได้ ขอให้คาลิเบอร์ทำงานให้คุณตัวอย่างเช่น
Jony Adamit

1

คำตอบสั้น ๆ สำหรับคำถามของคุณ:

  1. ใช่สถานะ + พฤติกรรมนำไปสู่ปัญหาเหล่านั้น แต่นี่เป็นเรื่องจริงสำหรับ OO ทั้งหมด ผู้ร้ายที่แท้จริงคือการมีเพศสัมพันธ์ของ ViewModels ซึ่งเป็นการละเมิด SRP
  2. พิมพ์แบบคงที่อาจจะ แต่คุณควรลด / กำจัดความต้องการของคุณในการปรับแต่ง ViewModels จาก ViewModels อื่น ๆ
  3. ไม่ใช่ว่าฉันรู้
  4. ไม่ แต่มี ViewModels ที่มีสถานะและพฤติกรรมที่ไม่เกี่ยวข้อง (เช่นเดียวกับบางรุ่นอ้างอิงและบางรุ่นอ้างอิง ViewModel)

รุ่นยาว:

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

  1. ใช้โมเดล bindable จาก DTO เพื่อติดตามการเปลี่ยนแปลงและตรวจสอบความถูกต้อง "ข้อมูล" - ViewModels เหล่านั้นจะต้องไม่ขึ้นอยู่กับบริการและไม่ได้มาจากคอนเทนเนอร์ พวกเขาสามารถเป็นเพียง "ใหม่" ed up ผ่านไปและอาจได้มาจาก DTO Bottomline คือการใช้โมเดลเฉพาะสำหรับแอปพลิเคชันของคุณ (Like MVC)

  2. แยก ViewModels ของคุณออก Caliburn ทำให้การจับคู่ ViewModels เข้าด้วยกันเป็นเรื่องง่าย นอกจากนี้ยังแนะนำผ่านหน้าจอรุ่น / ตัวนำ แต่การมีเพศสัมพันธ์นี้ทำให้การทดสอบ ViewModels ยากต่อหน่วยสร้างการพึ่งพาจำนวนมากและที่สำคัญที่สุด: กำหนดภาระในการจัดการวงจรชีวิตของ ViewModel บน ViewModels ของคุณ วิธีหนึ่งในการแยกพวกเขาคือการใช้บริการนำทางหรือตัวควบคุม ViewModel เช่น

    ส่วนต่อประสานสาธารณะ IShowViewModels {แสดงเป็นโมฆะ (วัตถุ inlineArgumentsAsAnonymousType, string regionId); }

ยิ่งไปกว่านั้นก็คือการส่งข้อความบางอย่าง แต่สิ่งสำคัญคือไม่ต้องจัดการกับวงจรชีวิต ViewModel จาก ViewModels อื่น ๆ ในตัวควบคุม MVC ไม่ได้ขึ้นอยู่กับแต่ละอื่น ๆ และใน MVVM ViewModels ไม่ควรขึ้นอยู่กับแต่ละอื่น ๆ รวมเข้าด้วยกันด้วยวิธีอื่น

  1. ใช้คุณสมบัติ "stringly" -typed / dynamic ของคอนเทนเนอร์ของคุณ แม้ว่ามันอาจเป็นไปได้ในการสร้างสิ่งที่ชอบINeedData<T1,T2,...>และบังคับใช้พารามิเตอร์การสร้างชนิดที่ปลอดภัย แต่ก็ไม่คุ้มค่า การสร้างโรงงานสำหรับ ViewModel แต่ละประเภทก็ไม่คุ้มค่าเช่นกัน ภาชนะบรรจุ IoC ส่วนใหญ่ให้บริการโซลูชั่นนี้ คุณจะได้รับข้อผิดพลาดขณะทำงาน แต่การยกเลิกการเชื่อมต่อและการทดสอบหน่วยมีค่า คุณยังคงทำการทดสอบการรวมบางอย่างและพบข้อผิดพลาดเหล่านั้นได้อย่างง่ายดาย

0

วิธีที่ฉันมักจะทำนี้ (ใช้ PRISM) คือแต่ละชุดประกอบประกอบด้วยโมดูล initialisation คอนเทนเนอร์ที่ซึ่งอินเทอร์เฟซทั้งหมดอินสแตนซ์ทั้งหมดถูกลงทะเบียนเมื่อเริ่มต้น

private void RegisterResources()
{
    Container.RegisterType<IDataService, DataService>();
    Container.RegisterType<IProductSearchViewModel, ProductSearchViewModel>();
    Container.RegisterType<IProductDetailsViewModel, ProductDetailsViewModel>();
}

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

/// <summary>
/// IDataService Interface
/// </summary>
public interface IDataService
{
    DataTable GetSomeData();
}

public class DataService : IDataService
{
    public DataTable GetSomeData()
    {
        MessageBox.Show("This is a call to the GetSomeData() method.");

        var someData = new DataTable("SomeData");
        return someData;
    }
}

public interface IProductSearchViewModel
{
}

public class ProductSearchViewModel : IProductSearchViewModel
{
    private readonly IUnityContainer _container;

    /// <summary>
    /// This will get resolved if it's been added to the container.
    /// Or alternately you could use constructor resolution. 
    /// </summary>
    [Dependency]
    public IDataService DataService { get; set; }

    public ProductSearchViewModel(IUnityContainer container)
    {
        _container = container;
    }

    public void SearchAndDisplay()
    {
        DataTable results = DataService.GetSomeData();

        var detailsViewModel = _container.Resolve<IProductDetailsViewModel>();
        detailsViewModel.DisplaySomeDataInView(results);

        // Create the view, usually resolve using region manager etc.
        var detailsView = new DetailsView() { DataContext = detailsViewModel };
    }
}

public interface IProductDetailsViewModel
{
    void DisplaySomeDataInView(DataTable dataTable);
}

public class ProductDetailsViewModel : IProductDetailsViewModel
{
    private readonly IUnityContainer _container;

    public ProductDetailsViewModel(IUnityContainer container)
    {
        _container = container;
    }

    public void DisplaySomeDataInView(DataTable dataTable)
    {
    }
}

เป็นเรื่องปกติที่จะมีคลาส ViewModelBase ซึ่งโมเดลการดูทั้งหมดของคุณได้รับมาจากซึ่งมีการอ้างอิงไปยังคอนเทนเนอร์ ตราบใดที่คุณยังคงเคยชินกับการแก้ไขทุกรุ่นของมุมมองแทนที่จะเป็นแบบnew()'ingนั้นมันควรจะทำให้การแก้ปัญหาการพึ่งพาทั้งหมดง่ายขึ้นมาก


0

บางครั้งการไปนิยามที่ง่ายที่สุดแทนที่จะเป็นตัวอย่างแบบเต็ม: http://en.wikipedia.org/wiki/Model_View_ViewModel บางทีการอ่านตัวอย่าง ZK Java นั้นให้ความสว่างมากกว่า C # หนึ่ง

บางครั้งฟังสัญชาตญาณของคุณ ...

การมี ViewModels จำนวนมากที่มีทั้งสภาวะ / พฤติกรรมมีกลิ่นของการออกแบบหรือไม่?

โมเดลของคุณเป็นวัตถุต่อการแมปตารางหรือไม่ บางที ORM อาจช่วยทำแผนที่วัตถุในโดเมนขณะจัดการธุรกิจหรืออัปเดตหลายตาราง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.