สร้างแอปพลิเคชันบริการแบบแยกส่วน


11

ฉันกำลังมองหาการสร้างโซลูชันใหม่ที่เป็นแบบแยกส่วนโดยธรรมชาติและต้องการสร้างโครงสร้างที่รองรับการออกแบบนั้นเพื่อให้สามารถขยายตัวในอนาคตได้อย่างง่ายดายแยกข้อกังวลออกใบอนุญาตโดยโมดูล ฯลฯ สิ่งที่ฉันทำส่วนใหญ่คือ พบได้บนเว็บเกี่ยวกับแอปพลิเคชันแบบแยกส่วนหรือคอมโพสิตคือ UI เป็นศูนย์กลางมุ่งเน้นไปที่ Silverlight, WPF และอื่น ๆ ในกรณีของฉันฉันกำลังพัฒนาแอพพลิเคชั่นบริการ WCF ที่นักพัฒนาอื่น ๆ

พื้นหลัง

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

ฉันเริ่มต้นการออกแบบโดยดูที่ API ที่เปิดเผยโดยแอปพลิเคชันบริการ เป็นที่ชัดเจนว่าบริการสามารถแยกออกไปตามสายโมดูลาร์ที่ฉันกำลังพิจารณา ตัวอย่างเช่นฉันจะมี FinanceService, InventoryService, PersonnelService และบริการอื่น ๆ ที่จัดกลุ่มการดำเนินงานบริการของฉันเพื่อให้มีการทำงานร่วมกันสูงใน API ในขณะที่การมีเพศสัมพันธ์ต่ำดังนั้นลูกค้าจะต้องใช้บริการที่เกี่ยวข้องกับแอปพลิเคชันของตน

ฉันรู้สึกว่าฉันสามารถมีโมดูลแยกต่างหากสำหรับแต่ละบริการเหล่านี้เช่น MyApp.Finance, MyApp.Inventory, My.Personnel และอื่น ๆ ความกังวลแบบตัดขวางและประเภทที่แชร์จะอยู่ในชุดประกอบ MyApp ที่ใช้ร่วมกัน จากที่นี่ฉันจะได้รับการผูกเล็กน้อย

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

ใน MyApp.ServiceHost ฉันจะสร้างไฟล์โฮสต์บริการ (.svc) ที่สอดคล้องกับแต่ละโมดูล FinanceService.svc เช่น โฮสต์บริการต้องการชื่อของบริการที่สอดคล้องกับข้อมูลในไฟล์กำหนดค่าที่มีส่วนต่อประสานที่กำหนดสัญญาบริการ จากนั้นการกำหนดค่า IoC จะใช้ในการทำแผนที่การนำอินเตอร์เฟสไปใช้อย่างเป็นรูปธรรม

1. เลเยอร์บริการควรใช้ API และมอบสิทธิ์ให้กับโมดูลหรือโมดูลควรมีอยู่ในตัวเอง (ในนั้นจะมีทุกอย่างที่เกี่ยวข้องกับโมดูลนั้นรวมถึงการใช้งานบริการ)

วิธีหนึ่งในการเข้าถึงปัญหาคือมี "โมดูล" MyApp.Services ซึ่งมีการใช้งานสัญญาบริการ แต่ละคลาสเซอร์วิสจะมอบหมายให้โมดูลอื่นที่เหมาะสมซึ่งมีตรรกะโดเมนสำหรับการดำเนินการ ตัวอย่างเช่นคลาส FinanceService WCF ใน MyApp.Services มอบสิทธิ์ให้แก่อินเทอร์เฟซอื่นซึ่งถูกนำไปใช้ในโมดูลการเงินเพื่อดำเนินการ สิ่งนี้จะช่วยให้ฉันสามารถบำรุงรักษาส่วนบริการที่บางและ 'plug-in' เพื่อนำไปใช้งานกับบริการและกำจัดความต้องการให้โมดูลกังวลเกี่ยวกับ WCF เช่น

ในทางตรงกันข้ามมันอาจจะดีกว่าที่จะมีแต่ละโมดูลในตัวเองว่ามันมีอินเตอร์เฟซและการใช้งาน โฮสต์บริการอ้างถึงส่วนต่อสัญญาบริการที่พบในโมดูลและ IoC ได้รับการกำหนดค่าให้ใช้การใช้งานที่เหมาะสมจากโมดูลเช่นกัน ซึ่งหมายความว่าการเพิ่มโมดูลใหม่สามารถทำได้โดยไม่ต้องเปลี่ยนเลเยอร์บริการอื่นนอกเหนือจากการเพิ่มไฟล์. svc ใหม่และข้อมูลการกำหนดค่า IoC

ฉันกำลังคิดเกี่ยวกับผลกระทบถ้าฉันเปลี่ยนจาก WCF มาตรฐานเป็นส่วนติดต่อบริการ RESTful หรืออาจไปที่บริการ RIA หรืออะไรบางอย่าง หากแต่ละโมดูลมีการปฏิบัติตามสัญญาการบริการฉันต้องทำการเปลี่ยนแปลงในทุก ๆ โมดูลหากฉันเปลี่ยนเทคโนโลยีการบริการหรือวิธีการ แต่ถ้าซุ้มเป็นโมดูลของตัวเองแล้วฉันจะต้องสลับส่วนนั้นเพื่อทำการเปลี่ยนแปลง โมดูลนั้นจะต้องใช้ชุดสัญญาที่แตกต่างกัน (อินเทอร์เฟซ), อาจกำหนดไว้ในแอสเซมบลีที่ใช้ร่วมกัน ???

2. วิธีที่ดีที่สุดในการจัดการทรัพยากรการแชร์ระหว่างโมดูลและ / หรือการพึ่งพาระหว่างโมดูลคืออะไร?

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

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

...

ฉันใช้ตัวอย่างนี้โดยมีวัตถุประสงค์เพราะฉันทำงานมากกับระบบ ERP ที่หลากหลายและรู้ว่าพวกเขาได้รับการออกแบบด้วยโมดูลาร์ประเภทนี้ - ฉันไม่รู้ว่าจะทำอย่างไร ฉันยังไม่ได้กล่าวถึงอย่างชัดเจนข้างต้น แต่ฉันชอบที่จะทำตามหลักการออกแบบการขับเคลื่อนด้วยโดเมนในการสร้างโซลูชันและเชื่อว่าโมดูลาร์ประเภทนี้เหมาะกับพื้นที่นั้น

ความช่วยเหลือใด ๆ ที่ได้รับห่อหัวของฉันรอบนี้ชื่นชมอย่างมาก


1
ขอโทษ ไม่พบคำถามในทุกความคิด คำถามคืออะไร?
S.Lott

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

1
@SonOfPirate: ขออภัย ฉันหวังว่าคุณอาจใช้เวลาในการเน้นหรือเน้นคำถามเพื่อให้คนอื่นสามารถช่วยคุณได้
S.Lott

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

1
@SonOfPirate: "Architecture" เป็นเรื่องเกี่ยวกับโครงสร้างและสื่อสารโครงสร้างนั้นกับผู้พัฒนารายอื่น มันเริ่มต้นด้วยคำอธิบาย จะต้องบรรลุระดับของความชัดเจนและความโปร่งใสที่อนุญาตให้ผู้พัฒนารายอื่นทั้งหมด "รับ" และปฏิบัติตามหลักการออกแบบสถาปัตยกรรมในทุกสิ่งที่พวกเขาทำ
S.Lott

คำตอบ:


2

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

คุณจะต้องยอมรับการแลกเปลี่ยน นั่นคือทั้งหมดที่จะพูดกับคำถามของคุณจริง ๆ เป็นการปฏิบัติที่ดีในการเก็บเอนทิตีในแอสเซมบลีแยกต่างหากดังนั้นแอปพลิเคชันจำนวนมากจึงเก็บไว้ในไลบรารีที่ใช้ร่วมกัน แต่นั่นหมายความว่าไม่มีขอบเขตทางกายภาพทางธุรกิจ การค้นหาของคุณเองหมายถึงรหัสซ้ำซ้อนจำนวนมากซึ่งฉันจะใช้เฉพาะเมื่อคุณมีข้อกำหนดพิเศษในทั้งสองโมดูล แน่นอนว่าเมื่อมองจากมุมมองทางสถาปัตยกรรมโมดูลการเงินและโมดูลสินค้าคงคลังของคุณจะต้องแบ่งปันการพึ่งพา โมดูลการเงินมักขึ้นกับโมดูลสินค้าคงคลัง ถ้าข้อกำหนดอนุญาตให้คุณปล่อยให้โมดูลหนึ่งขึ้นอยู่กับอีกโมดูลหนึ่งฉันก็บอกได้ว่ามันโอเคที่จะสรุปเอนทิตีภายในโมดูลที่พวกเขาเป็นส่วนใหญ่ คุณ' จะต้องค้นหาสมดุลที่ดีระหว่างความแตกต่างทางกายภาพ (การพึ่งพาที่ใช้ร่วมกัน) และการบำรุงรักษา การพึ่งพาที่ใช้ร่วมกันมากเกินไปอาจทำให้ฝันร้ายของการบำรุงรักษาเวอร์ชัน นอกจากนี้ด้วย ORM จะมีปัญหาหากคุณต้องการแมปความสัมพันธ์ใหม่กับเอนทิตีที่มีอยู่หรือขยายออกจากโมดูลซึ่งขึ้นอยู่กับโมดูลที่มีเอนทิตี

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

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

ดังนั้นในระยะสั้นคุณจะต้องตัดสินใจว่าคุณต้องการอินเทอร์เฟซประเภทใด ต้นแบบมากขึ้นนำไปสู่สัญญาน้อยลงและในทางกลับกัน

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


เห็นด้วยกับสิ่งนี้ - การส่งข้อความ + pub / sub และ shared library สำหรับสัญญา dto (repo ภายใน nuget) ฉันสงสัยคำถามเดียวกันกับ @SonOfPirate จนกระทั่งบทความนี้วางไว้ในมุมมองของฉัน: msdn.microsoft.com/en-us/library/bb245678.aspx
diegohb
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.