อย่าประกาศอินเตอร์เฟสสำหรับวัตถุที่ไม่เปลี่ยนรูป


27

อย่าประกาศอินเตอร์เฟสสำหรับวัตถุที่ไม่เปลี่ยนรูป

[แก้ไข] เมื่อวัตถุที่เป็นปัญหาแสดงถึง Data Transfer Objects (DTOs) หรือ Plain Old Data (PODs)

นั่นเป็นแนวทางที่สมเหตุสมผลหรือไม่?

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

โชคไม่ดีที่อินเทอร์เฟซเริ่มแพร่หลายรหัส (และไม่ใช่เพียงรหัสของฉันที่ฉันกังวล) คุณเลิกใช้งานอินเทอร์เฟซแล้วต้องการส่งไปยังโค้ดที่ต้องการสมมติว่าสิ่งที่ส่งผ่านไปนั้นไม่สามารถเปลี่ยนแปลงได้

เนื่องจากปัญหานี้ฉันจึงพิจารณาไม่ประกาศส่วนต่อประสานสำหรับวัตถุที่ไม่เปลี่ยนรูป

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

หรือมีรูปแบบอื่นที่ฉันควรใช้เพื่อหลีกเลี่ยงปัญหา "อินเตอร์เฟซการแพร่กระจาย" ฉันเห็น?

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

[แก้ไข]

เพื่อให้บริบทมากขึ้นด้วยเหตุผลของฉันที่ต้องการทำให้วัตถุไม่เปลี่ยนรูปให้ดูโพสต์บล็อกนี้จาก Eric Lippert:

http://blogs.msdn.com/b/ericlippert/archive/tags/immutability/

ฉันควรชี้ให้เห็นว่าฉันกำลังทำงานกับแนวคิดระดับล่างบางอย่างที่นี่เช่นรายการที่จัดการ / ส่งต่อในคิวงานแบบมัลติเธรด สิ่งเหล่านี้คือ DTO

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


ติดตาม

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

มีประเด็นอื่น ๆ ที่เกี่ยวข้องกับเรื่องนี้ที่ฉันต้องการถามเกี่ยวกับ; สิ่งที่สะดุดตาที่ฉันเรียกว่า "Deep or Shallow Immutability" (ศัพท์เฉพาะที่ฉันขโมยมาจาก Deep and Shallow cloning) - แต่นั่นเป็นคำถามอีกครั้ง


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

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

3
ฉันสับสนทำไมไม่ปล่อยให้ผู้ตั้งค่าปิดอินเทอร์เฟซ แต่ในทางกลับกันฉันเบื่อที่จะเห็นส่วนต่อประสานสำหรับวัตถุที่เป็นวัตถุโดเมนจริง ๆ และ / หรือ DTO ที่ต้องการโรงงานสำหรับวัตถุเหล่านั้น ... ทำให้เกิดความไม่ลงรอยกันทางปัญญาสำหรับฉัน
Michael Brown

2
สิ่งที่เกี่ยวกับอินเทอร์เฟซสำหรับคลาสที่ไม่เปลี่ยนรูปทั้งหมด ? ยกตัวอย่างเช่นชวาจำนวนชั้นช่วยให้หนึ่งในการกำหนดList<Number>ซึ่งสามารถเก็บไว้Integer, Float, Long, BigDecimalฯลฯ ... ซึ่งทั้งหมดจะไม่เปลี่ยนรูปตัวเอง

1
@ MikeBrown ฉันคิดว่าเพียงเพราะอินเตอร์เฟสแสดงนัยถึงการเปลี่ยนแปลงไม่ได้ไม่ได้หมายความว่าการใช้บังคับมัน คุณสามารถปล่อยให้เป็นแบบแผน (เช่นเอกสารอินเทอร์เฟซที่ไม่สามารถเปลี่ยนแปลงได้เป็นข้อกำหนด) แต่คุณสามารถจบลงด้วยปัญหาที่น่ารังเกียจบางอย่างหากมีคนละเมิดการประชุม
vaughandroid

คำตอบ:


17

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

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

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

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

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


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

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

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

@ เควินฉันคิดว่า แต่ด้วยความสะดวกสบายที่ทันสมัยของคุณสมบัติอัตโนมัติมันง่ายมากที่จะทำให้เป็นคุณสมบัติทำไมไม่? ฉันคิดว่าถ้าประสิทธิภาพและประสิทธิภาพมีความกังวลสูงสุดบางทีนั่นอาจเป็นเรื่องสำคัญ ไม่ว่าในกรณีใด ๆ คำถามคือ "ตรรกะ" ระดับใดที่คุณอนุญาตใน DTO แม้ว่าคุณจะใช้ตรรกะการตรวจสอบความถูกต้องบางอย่างในคุณสมบัติของมันก็จะไม่มีปัญหาในการทดสอบหน่วยตราบใดที่มันไม่มีการพึ่งพาที่จะต้องมีการเยาะเย้ย ตราบใดที่ DTO ไม่ได้ใช้วัตถุทางธุรกิจใด ๆ แล้วมันก็จะปลอดภัยที่จะมีตรรกะเล็ก ๆ น้อย ๆ อยู่ภายในเพราะมันจะยังคงสามารถทดสอบได้
Steven Doggart

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

7

ฉันเคยทำให้ยุ่งยากมากเกี่ยวกับการทำให้รหัสของฉันคงกระพันที่จะใช้ในทางที่ผิด ฉันสร้างอินเทอร์เฟซแบบอ่านอย่างเดียวเพื่อซ่อนสมาชิกที่กลายพันธุ์เพิ่มข้อ จำกัด มากมายให้กับลายเซ็นทั่วไปของฉันและอื่น ๆ มันกลับกลายเป็นว่าส่วนใหญ่ฉันตัดสินใจออกแบบเพราะฉันไม่ไว้ใจเพื่อนร่วมงานในจินตนาการ "บางทีสักวันหนึ่งพวกเขาจะจ้างผู้ชายระดับเริ่มต้นใหม่และเขาจะไม่รู้ว่าคลาส XYZ นั้นไม่สามารถอัปเดต DTO ABC ได้โอ้ไม่!" บางครั้งฉันก็มุ่งเน้นไปที่ปัญหาที่ผิดพลาดโดยไม่สนใจทางออกที่ชัดเจน - ไม่เห็นป่าผ่านต้นไม้

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

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


ฉันมักจะบันทึกอินเตอร์เฟซสำหรับเมื่อฉันต้องการฉีดพึ่งพาสำหรับการทดสอบหน่วย
Travis Parks

5

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

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


2

รหัสกลายเป็นเรื่องง่ายกว่ามากในหลาย ๆ กรณีเมื่อคุณรู้ว่ามีบางอย่างไม่เปลี่ยนรูป - ซึ่งคุณทำไม่ได้ถ้าคุณได้รับอินเทอร์เฟซ

ฉันไม่คิดว่าเป็นปัญหาที่ผู้ดำเนินการเข้าถึงต้องกังวล ถ้าinterface Xตั้งใจว่าจะไม่เปลี่ยนรูปมันก็ไม่ได้เป็นความรับผิดชอบของผู้ดำเนินการเพื่อให้แน่ใจว่าพวกเขาใช้อินเทอร์เฟซในแบบที่ไม่เปลี่ยนรูปแบบ?

อย่างไรก็ตามในใจของฉันไม่มีสิ่งใดที่เป็นอินเทอร์เฟซที่ไม่เปลี่ยนรูป - สัญญารหัสที่ระบุโดยส่วนต่อประสานจะใช้กับวิธีการเปิดเผยของวัตถุเท่านั้นและไม่มีอะไรเกี่ยวกับภายในของวัตถุ

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


1
คุณสามารถยกตัวอย่างการใช้ความไม่เปลี่ยนแปลงในฐานะมัณฑนากรได้หรือไม่?
vaughandroid

ไม่ใช่เรื่องไม่สำคัญฉันไม่คิด แต่เป็นการออกกำลังกายทางความคิดที่ค่อนข้างง่าย - ถ้าMutableObjectมีnวิธีที่เปลี่ยนสถานะและmวิธีการที่ส่งคืนสถานะImmutableDecoratorสามารถดำเนินการต่อเพื่อเปิดเผยวิธีการที่ส่งคืนสถานะ ( m) และขึ้นอยู่กับสภาพแวดล้อม โยนข้อยกเว้นเมื่อหนึ่งในวิธีการไม่แน่นอนที่เรียกว่า
Jonathan Rich

ฉันไม่ชอบการแปลงความแน่นอนในการคอมไพล์เป็นความเป็นไปได้ของข้อยกเว้นรันไทม์ ...
Matthew Watson

ตกลง แต่ ImmutableDecorator จะรู้ได้อย่างไรว่าวิธีการที่ระบุเปลี่ยนสถานะหรือไม่?
vaughandroid

คุณไม่สามารถมั่นใจได้ในกรณีใด ๆ หากคลาสที่ใช้อินเทอร์เฟซของคุณไม่เปลี่ยนรูปโดยคำนึงถึงวิธีการที่กำหนดโดยส่วนต่อประสานของคุณ @ Baqueta มัณฑนากรจะต้องมีความรู้ในการใช้คลาสฐาน
Jonathan Rich

0

คุณเลิกใช้งานอินเทอร์เฟซแล้วต้องการส่งไปยังโค้ดที่ต้องการสมมติว่าสิ่งที่ส่งผ่านไปนั้นไม่สามารถเปลี่ยนแปลงได้

ใน C # วิธีการที่คาดว่าวัตถุประเภท "ไม่เปลี่ยนรูป" ไม่ควรมีพารามิเตอร์ของประเภทอินเตอร์เฟสเนื่องจากอินเตอร์เฟส C # ไม่สามารถระบุสัญญาที่ไม่สามารถเปลี่ยนแปลงได้ ดังนั้นแนวทางที่คุณเสนอเองนั้นไม่มีความหมายใน C # เพราะคุณไม่สามารถทำได้ในตอนแรก (และภาษาในอนาคตจะไม่ทำให้คุณทำ)

คำถามของคุณเกิดจากความเข้าใจผิดที่ลึกซึ้งของบทความของ Eric Lippert เกี่ยวกับความไม่สามารถเปลี่ยนแปลงได้ Eric ไม่ได้กำหนดอินเตอร์เฟสIStack<T>และIQueue<T>เพื่อระบุสัญญาสำหรับสแต็กและคิวที่ไม่เปลี่ยนรูป พวกเขาทำไม่ได้ เขากำหนดไว้เพื่อความสะดวก อินเตอร์เฟสเหล่านี้ทำให้เขาสามารถกำหนดประเภทที่แตกต่างกันสำหรับสแต็กและคิวที่ว่างเปล่า เราสามารถเสนอการออกแบบที่แตกต่างและการนำไปปฏิบัติของกองซ้อนที่ไม่เปลี่ยนรูปได้โดยใช้ชนิดเดียวโดยไม่ต้องใช้ส่วนต่อประสานหรือแยกประเภทเพื่อเป็นตัวแทนของกองซ้อนที่ว่างเปล่า แต่รหัสผลลัพธ์จะไม่ดูสะอาดและมีประสิทธิภาพน้อยกว่าเล็กน้อย

ทีนี้มาดูการออกแบบของ Eric กัน วิธีการที่ต้องการสแต็กที่ไม่เปลี่ยนรูปจะต้องมีพารามิเตอร์ชนิดStack<T>มากกว่าอินเตอร์เฟสทั่วไปIStack<T>ซึ่งแสดงชนิดข้อมูลนามธรรมของสแต็กในความหมายทั่วไป ไม่ชัดเจนว่าจะทำอย่างไรเมื่อใช้กองซ้อนที่ไม่เปลี่ยนแปลงของ Eric และเขาไม่ได้พูดถึงเรื่องนี้ในบทความของเขา แต่เป็นไปได้ ปัญหาเกิดขึ้นกับชนิดของสแต็กเปล่า คุณสามารถแก้ไขปัญหานี้ได้ด้วยการทำให้แน่ใจว่าคุณจะไม่ได้รับสแต็กว่างเปล่า นี้สามารถมั่นใจได้โดยการผลักดันค่าดัมมี่เป็นค่าแรกในสแต็กและไม่เคย popping มัน วิธีนี้คุณสามารถส่งผลของการได้อย่างปลอดภัยPushและการPopStack<T>

การมีStack<T>เครื่องมือIStack<T>จะมีประโยชน์ คุณสามารถกำหนดวิธีการที่ต้องการสแต็กสแต็กใด ๆ ไม่จำเป็นต้องเป็นสแต็กที่ไม่เปลี่ยนรูป IStack<T>วิธีการเหล่านี้สามารถมีพารามิเตอร์ของชนิด สิ่งนี้ช่วยให้คุณสามารถส่งผ่านสแต็กที่ไม่เปลี่ยนรูปได้ เป็นการดีที่IStack<T>จะเป็นส่วนหนึ่งของไลบรารีมาตรฐานเอง ใน. NET ไม่มีIStack<T>แต่มีอินเทอร์เฟซมาตรฐานอื่น ๆ ที่กองซ้อนไม่เปลี่ยนรูปสามารถนำมาใช้ทำให้ชนิดมีประโยชน์มากขึ้น

IImmutableStack<T>การออกแบบทางเลือกและการดำเนินงานของสแต็คไม่เปลี่ยนรูปที่ผมเรียกว่าก่อนหน้านี้ไม่ใช้อินเตอร์เฟซที่เรียกว่า แน่นอนว่าการแทรก "ไม่เปลี่ยนรูป" ในชื่ออินเทอร์เฟซไม่ได้ทำให้ทุกประเภทที่ใช้มันไม่เปลี่ยนรูป อย่างไรก็ตามในอินเทอร์เฟซนี้สัญญาการเปลี่ยนแปลงไม่ได้เป็นเพียงคำพูด นักพัฒนาที่ดีควรเคารพมัน

หากคุณกำลังพัฒนาห้องสมุดขนาดเล็กภายในคุณสามารถเห็นด้วยกับทุกคนในทีมเพื่อให้เกียรติสัญญานี้และคุณสามารถใช้IImmutableStack<T>เป็นประเภทพารามิเตอร์ มิฉะนั้นคุณไม่ควรใช้ประเภทอินเตอร์เฟส

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

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