การออกแบบคลาสที่เน้นวัตถุ


12

ฉันสงสัยเกี่ยวกับการออกแบบคลาสเชิงวัตถุที่ดี โดยเฉพาะอย่างยิ่งฉันมีเวลาตัดสินใจยากระหว่างตัวเลือกเหล่านี้:

  1. วิธีการคงที่ vs อินสแตนซ์
  2. method ที่ไม่มีพารามิเตอร์หรือ return value vs method กับพารามิเตอร์และ return value
  3. ฟังก์ชันการใช้วิธีการที่ทับซ้อนกัน vs ที่แตกต่างกัน
  4. วิธีส่วนตัวและสาธารณะ

ตัวอย่างที่ 1:

การใช้งานนี้ใช้วิธีการแบบอินสแตนซ์โดยไม่มีค่าส่งคืนหรือพารามิเตอร์โดยไม่มีการซ้อนทับฟังก์ชันการทำงานและวิธีการทั้งหมดสาธารณะ

XmlReader reader = new XmlReader(url);
reader.openUrl();
reader.readXml();
Document result = reader.getDocument();

ตัวอย่างที่ 2:

การใช้งานนี้ใช้วิธีการคงที่มีค่าตอบแทนและพารามิเตอร์ที่มีฟังก์ชั่นที่ทับซ้อนกันและวิธีการส่วนตัว

Document result = XmlReader.readXml(url); 

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

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

ฉันควรทำตามหลักการใดเพื่อทำการเขียนโปรแกรมเชิงวัตถุที่เหมาะสม


3
สิ่งคงที่ไม่ดีเมื่อคุณทำหลายเธรด วันก่อนฉันมี XMLWriter แบบคงที่เช่น XMLWriter.write (data, fileurl) อย่างไรก็ตามเนื่องจากมี FileStream แบบสแตติกส่วนตัวการใช้คลาสนี้จากหลายเธรดในเวลาเดียวกันทำให้เธรดที่สองเขียนทับเธรดแรก FileStream ทำให้เกิดข้อผิดพลาดซึ่งหายากมาก คลาสแบบสแตติกที่มีสมาชิกแบบสแตติก + มัลติเธรดเป็นสูตรสำหรับภัยพิบัติ
ต่อ Alexandersson

1
@Paxinum ปัญหาที่คุณอธิบายเป็นปัญหาสถานะไม่ใช่ปัญหา "คงที่" หากคุณใช้ซิงเกิลตันกับสมาชิกที่ไม่คงที่คุณจะมีปัญหาเดียวกันกับมัลติเธรด
mike30

2
@Per Alexandersson วิธีการคงไม่เลวในความสัมพันธ์กับการเกิดพร้อมกัน สถานะคงไม่ดี นี่คือเหตุผลที่การเขียนโปรแกรมทำงานได้ซึ่งวิธีการทั้งหมดเป็นแบบคงที่ทำงานได้ดีในสถานการณ์ที่เกิดขึ้นพร้อมกัน
Yuli Bonner

คำตอบ:


11

ตัวอย่างที่ 2 ค่อนข้างแย่สำหรับการทดสอบ ... และฉันไม่ได้หมายความว่าคุณไม่สามารถทดสอบ internals ได้ คุณยังไม่สามารถแทนที่XmlReaderวัตถุของคุณด้วยวัตถุจำลองเนื่องจากคุณไม่มีวัตถุเลย

ตัวอย่างที่ 1 ใช้งานยากโดยไม่จำเป็น เกี่ยวกับอะไร

XmlReader reader = new XmlReader(url);
Document result = reader.getDocument();

ซึ่งไม่ยากกว่าการใช้วิธีการคงที่ของคุณ

สิ่งต่างๆเช่นการเปิด URL การอ่าน XML การแปลงไบต์เป็นสตริงการแยกวิเคราะห์การปิดซ็อกเก็ตและอะไรก็ตามที่ไม่น่าสนใจ การสร้างวัตถุและการใช้เป็นสิ่งสำคัญ

ดังนั้น IMHO การออกแบบ OO ที่เหมาะสมคือการเปิดเผยสองสิ่งให้เป็นสาธารณะ (เว้นแต่ว่าคุณต้องการขั้นตอนกลางด้วยเหตุผลบางอย่าง) คงที่คือความชั่วร้าย


-1 จริง ๆ แล้วคุณสามารถแทนที่ XmlReader ด้วยวัตถุจำลอง ไม่ต้องใช้กรอบโอเพนซอร์ส moick สมองตาย แต่ด้วยเกรดอุตสาหกรรมที่ดีที่คุณสามารถทำได้;) ค่าใช้จ่ายไม่กี่ร้อยเหรียญสหรัฐต่อนักพัฒนา แต่ทำงานอย่างมหัศจรรย์เพื่อทดสอบฟังก์ชันการปิดผนึกใน API ที่คุณเผยแพร่
TomTom

2
+1 ที่ไม่ย่อท้อกับยอดขายของ TomTom เมื่อฉันต้องการหนึ่งซับฉันควรเขียนบางอย่างเช่นDocument result = new XmlReader(url).getDocument();ทำไม? เพื่อให้ฉันสามารถอัปเกรดเป็นDocument result = whateverReader.getDocument();และได้whateverReaderมอบสิ่งอื่นให้ฉัน
candied_orange

6

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

ทุกอย่างมาถึงเป้าหมายของคุณ

คุณเป็นศิลปินและกระดาษเปล่า คุณสามารถวาดภาพเหมือนสีดำและสีขาวด้านข้างที่ละเอียดอ่อนด้วยดินสอหรือภาพวาดนามธรรมที่มีเส้นประสาทขนาดใหญ่ของเส้นประสาทผสม หรืออะไรก็ตามในระหว่าง

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

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

นรกสิ่งที่คุณอาจต้องทำคือเขียนโค้ด 4 หรือ 5 วิธีแตกต่างกันจากนั้นใส่หมวกผู้บริโภคของคุณและเขียนโค้ดที่ใช้ทั้ง 5 และดูว่ารู้สึกดีกว่ากัน หากคุณไม่สามารถทำเช่นนั้นได้สำหรับห้องสมุดทั้งหมดของคุณให้ทำเพื่อกลุ่มย่อย และคุณต้องเพิ่มทางเลือกเพิ่มเติมในรายการของคุณด้วยเช่นกันเกี่ยวกับอินเทอร์เฟซที่คล่องแคล่วหรือวิธีการทำงานที่มากขึ้นหรือพารามิเตอร์ที่มีชื่อหรือสิ่งที่ยึดตาม DynamicObject เพื่อให้คุณสามารถสร้าง "วิธีการหลอก" ที่มีความหมาย ออก?

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

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


1
นี่ก็หมายความว่าไม่มีความแตกต่างระหว่างแนวปฏิบัติที่ดีที่สุดและแนวปฏิบัติอื่น ๆ นอกเหนือจากที่ "รู้สึก" นี่คือวิธีที่คุณปิดท้ายด้วยลูกบอลโคลนที่ไม่สามารถรักษาได้ - เพราะสำหรับนักพัฒนาหลาย ๆ คนการเข้าถึงข้ามขอบเขตของคลาส ฯลฯ "รู้สึก" น่าอัศจรรย์เพียงอย่างเดียว
Amy Blankenship

@Amy Blankenship ฉันจะบอกอย่างแจ่มแจ้งว่าไม่มีใคร "วิธีที่ดีที่สุด" ในการเลือกตัวเลือกที่ OP ถาม มันขึ้นอยู่กับสิ่งหนึ่งล้านและมีอิสระเป็นล้านองศา อย่างไรก็ตามฉันคิดว่ามีสถานที่สำหรับ "วิธีปฏิบัติที่ดีที่สุด" และที่อยู่ในสภาพแวดล้อมของทีมที่มีตัวเลือกบางอย่างได้ทำไปแล้วและเราต้องการให้ทีมที่เหลืออยู่เพื่อให้สอดคล้องกับตัวเลือกก่อนหน้านี้ กล่าวอีกนัยหนึ่งในบริบทเฉพาะอาจมีเหตุผลที่จะติดป้ายกำกับสิ่งที่ "ปฏิบัติที่ดีที่สุด" แต่ OP ไม่ได้ให้บริบทใด ๆ เขากำลังสร้างบางสิ่งบางอย่างและ ...
Charlie ดอกไม้

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

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

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

3

ตัวเลือกที่สองนั้นดีกว่าเพราะคนใช้ง่ายกว่า (แม้ว่าจะเป็นเพียงคุณ) ก็จะง่ายขึ้นมาก

สำหรับการทดสอบหน่วยฉันแค่ทดสอบอินเทอร์เฟซไม่ใช่ภายในถ้าคุณต้องการย้าย internals จากส่วนตัวเป็นการป้องกัน


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

จุดดี - ดีกว่า

3

1. คงเทียบกับอินสแตนซ์

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

และวิธีปฏิบัติที่แย่ที่สุดที่ฉันคิดได้ก็คือรัฐทั่วโลกรวมถึงสถิตยศาสตร์ที่คุณพูดถึงและซิงเกิลตันที่ทุกคนโปรดปราน ข้อความที่ตัดตอนมาจากการ Misko Hevery ของบทความคลาสสิกเกี่ยวกับเรื่องนี้

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

Spooky Action at a Distance คือเมื่อเรารันสิ่งหนึ่งที่เราเชื่อว่าถูกแยกออก (เนื่องจากเราไม่ได้ผ่านการอ้างอิงใด ๆ ) แต่การตอบโต้ที่ไม่คาดคิดและการเปลี่ยนแปลงสถานะเกิดขึ้นในตำแหน่งที่ห่างไกลของระบบซึ่งเราไม่ได้บอกวัตถุ สิ่งนี้สามารถเกิดขึ้นได้ผ่านสถานะสากล

คุณอาจไม่เคยคิดแบบนี้มาก่อน แต่เมื่อใดก็ตามที่คุณใช้สถานะคงที่คุณจะสร้างช่องทางการสื่อสารลับและไม่ทำให้ชัดเจนใน API Spooky Action at a Distance บังคับให้นักพัฒนาอ่านรหัสทุกบรรทัดเพื่อทำความเข้าใจกับการโต้ตอบที่อาจเกิดขึ้นลดประสิทธิภาพการทำงานของนักพัฒนาและสร้างความสับสนให้กับสมาชิกในทีมใหม่

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

2. วิธีการที่มีพารามิเตอร์อินพุตและค่าส่งคืนเทียบกับวิธีการที่ไม่มี

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

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

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

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

3. การทับซ้อนกับความแตกต่าง

ฉันไม่เข้าใจคำถาม ข้อได้เปรียบอะไรบ้างใน 2 วิธีที่ทับซ้อนกัน

4. ส่วนตัวกับสาธารณะ

อย่าเปิดเผยสิ่งที่คุณไม่จำเป็นต้องเปิดเผย อย่างไรก็ตามฉันไม่ใช่แฟนตัวยงของความเป็นส่วนตัวเช่นกัน ฉันไม่ใช่นักพัฒนา C # แต่เป็นนักพัฒนา ActionScript ฉันใช้เวลาส่วนใหญ่กับโค้ด Flex Framework ของ Adobe ซึ่งเขียนขึ้นประมาณปี 2550 และพวกเขาเลือกสิ่งที่ไม่ดีที่จะทำให้เป็นส่วนตัวซึ่งทำให้ฝันร้ายที่พยายามขยายคลาสของพวกเขา

ดังนั้นถ้าคุณคิดว่าคุณเป็นสถาปนิกที่ดีกว่านักพัฒนาของ Adobe ประมาณปี 2007 (จากคำถามของคุณฉันจะบอกว่าคุณมีเวลาอีกไม่กี่ปีก่อนที่คุณจะมีโอกาสที่จะเรียกร้องได้) คุณอาจต้องการเริ่มต้นเพื่อป้องกัน .


มีปัญหาบางอย่างกับตัวอย่างรหัสของคุณซึ่งหมายความว่าพวกเขาไม่ได้รับการออกแบบอย่างดีดังนั้นจึงไม่สามารถเลือก A หรือ B ได้

สำหรับสิ่งหนึ่งที่คุณอาจจะแยกการสร้างวัตถุของคุณจากการใช้งาน ดังนั้นคุณมักจะไม่มีnew XMLReader()สิทธิ์ติดกับตำแหน่งที่ใช้

นอกจากนี้ตามที่ @djna พูดว่าคุณควรสรุปวิธีการที่ใช้ในเครื่องอ่าน XML ของคุณดังนั้น API ของคุณ (ตัวอย่างเช่น) อาจทำให้เข้าใจง่ายขึ้นเพื่อ:

_document Document = reader.read(info);

ฉันไม่ทราบว่า C # ทำงานอย่างไร แต่เนื่องจากฉันทำงานกับเทคโนโลยีเว็บจำนวนมากฉันจึงสงสัยว่าคุณจะไม่สามารถส่งคืนเอกสาร XML ได้ทันที (ยกเว้นอาจเป็นสัญญาหรือประเภทในอนาคต วัตถุ) แต่ฉันไม่สามารถให้คำแนะนำคุณเกี่ยวกับวิธีจัดการโหลดแบบอะซิงโครนัสใน C #

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


2

มุ่งเน้นไปที่มุมมองของลูกค้า

IReader reader = new XmlReader.readXml(url);  // or injection, or factory or ...
Document document = reader.read();

วิธีการแบบคงที่มีแนวโน้มที่จะ จำกัด วิวัฒนาการในอนาคตลูกค้าของเรากำลังทำงานในแง่ของอินเทอร์เฟซที่มีให้โดยการใช้งานที่แตกต่างกันมาก

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

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


วิธีการที่มีการมองเห็นเริ่มต้นยังคงมองเห็นได้หรือไม่หากชุดทดสอบอยู่ในโครงการอื่น
siamii

Java ไม่ทราบเกี่ยวกับโครงการ โครงการเป็นโครงสร้าง IDE คอมไพเลอร์และ JVM ดูแพ็คเกจที่คลาสทดสอบและผู้ทดสอบอยู่ใน - แพ็กเกจเดียวกันอนุญาตให้มองเห็นค่าเริ่มต้นได้ ใน Eclipse ฉันใช้โครงการเดียวโดยมีสองไดเรกทอรีต้นทางที่ต่างกัน ฉันเพิ่งลองสองโครงการมันใช้งานได้

2

วิธีการคงที่ vs อินสแตนซ์

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

method ที่ไม่มีพารามิเตอร์หรือ return value vs method กับพารามิเตอร์และ return value

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

ฟังก์ชันการใช้วิธีการที่ทับซ้อนกัน vs ที่แตกต่างกัน

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

วิธีส่วนตัวและสาธารณะ

โดยทั่วไป getters, setters และ constructors ควรเป็นที่สาธารณะ ทุกสิ่งทุกอย่างที่คุณจะต้องพยายามรักษาความเป็นส่วนตัวเว้นแต่มีกรณีที่ชั้นเรียนอื่นต้องดำเนินการ วิธีการรักษาผิดนัดจะช่วยให้ภาคเอกชนรักษาEncapsulation กันไปสำหรับเขตข้อมูลรับใช้เป็นส่วนตัวเป็นค่าเริ่มต้น


1

ฉันจะไม่ตอบคำถามของคุณ แต่ฉันคิดว่ามีปัญหาเกิดขึ้นจากคำศัพท์ที่คุณใช้ เช่น

XmlReader.read => twice "read"

ฉันคิดว่าคุณต้องการ XML ดังนั้นฉันจะสร้างวัตถุ XML ที่สามารถสร้างจากประเภทข้อความ (ฉันไม่รู้ C # ... ใน Java เรียกว่า String) เช่น

class XML {
    XML(String text) { [...] }
}

คุณสามารถทดสอบได้และชัดเจน จากนั้นหากคุณต้องการโรงงานคุณสามารถเพิ่มวิธีการในโรงงาน (และสามารถคงที่เหมือนตัวอย่างที่ 2 ของคุณ) เช่น

class XML {
    XML(String text) { [...] }

    static XML fromUrl(url) { [...] }

}

0

คุณสามารถปฏิบัติตามกฎง่ายๆ ช่วยถ้าคุณเข้าใจเหตุผลของกฎ

วิธีการคงที่ vs อินสแตนซ์

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

method ที่ไม่มีพารามิเตอร์หรือ return value vs method กับพารามิเตอร์และ return value

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

ฟังก์ชันการใช้วิธีการที่ทับซ้อนกัน vs ที่แตกต่างกัน

ฉันไม่คิดว่านี่เป็นปัญหา วิธีการเรียกใช้วิธีการอื่นนั้นใช้ได้ถ้าสับสิ่งนี้เป็นชิ้นเล็กชิ้นน้อยทำงานได้อย่างชัดเจน

วิธีส่วนตัวและสาธารณะ

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

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