ฉันจะเอาชนะอัมพาตโดยการวิเคราะห์ได้อย่างไรเมื่อเขียนโค้ด?


37

เมื่อฉันเริ่มโครงการใหม่ฉันมักจะเริ่มคิดเกี่ยวกับรายละเอียดของการดำเนินการทันที "ฉันจะวาง DataBaseHandler ไว้ที่ไหนฉันควรใช้มันอย่างไรคลาสที่ต้องการใช้มันขยายจาก Abstractclass superclass บางส่วน .. ฉันควรใช้อินเทอร์เฟซหรือไม่ฉันจะใช้อินเทอร์เฟซในระดับใด วิธีในการส่งคำขอและการแยกวิเคราะห์ข้อมูล "

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

แล้วถ้าฉันพยายามจะพูดว่า "ขันมันให้เสร็จแล้ว!" ฉันก็ชนกำแพงอิฐอย่างรวดเร็วเพราะรหัสของฉันไม่ได้จัดระเบียบฉันผสมระดับนามธรรมต่าง ๆ เป็นต้น

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

- -แก้ไข - -

นี่เป็นประเภทของคำถามที่ตอบรับยากแล้ว แต่ต้องการได้รับคำติชมเพิ่มเติมดูว่ามีฉันทามติบ้างไหม TDD ฟังดูเจ๋งจริงๆและตรงไปตรงมาฉันหมายถึงการเพิ่มความเร็วในการใช้ JUnit ฯลฯ ในเวลาเดียวกันแฟน ๆ ของ TDD คิดอย่างไรเกี่ยวกับความจริงที่ว่าจุดที่ถูกต้องตามกฎหมายที่เกี่ยวข้องกับการแก้ไข TDD ของฉัน ปัญหาเฉพาะคือ TDD ไม่ได้ตอบคำถามการออกแบบ แน่นอนว่าฉันเห็นด้วยกับ TDD จะช่วยฉันกำหนดสิ่งที่ฉันต้องการจะทำและจากนั้นฉันสามารถค่อยๆทำตามวิธีได้ แต่มีรูปแบบ / โครงสร้างการออกแบบโดยรวมที่แตกต่างกันมากมายที่ทุกคนสามารถผ่านการทดสอบหน่วยได้ นั่นเป็นเพียงแค่มันทดสอบหน่วยเดียว ฉันคิดว่าฉันสับสนเล็กน้อย ... ฉันไม่รู้แล้ว บางทีฉัน'

ขอบคุณ!


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

นี่เป็นคำถามที่ยอดเยี่ยม นี่คือกับดักที่ฉันมีความผิดที่ตกลงไปเช่นกัน
Corv1nus

คำตอบ:


16

ฉันแนะนำอีกครั้งโดยใช้Test-Driven-Developmentมันต้องใช้ความคุ้นเคยโดยเฉพาะอย่างยิ่งเมื่อทำงานกับ IDE ที่ดีเช่น eclipse แต่ข้อดีนั้นดีมาก

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

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

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

ตัวอย่างจาวาสั้น ๆ :
ฉันต้องการพัฒนาโปรแกรมที่อ่านและเขียนข้อความจาก db

ดังนั้นฉันเริ่มต้นด้วยการกระทำแรกที่กำหนดไว้อย่างดีฉันต้องการ DB:

@Test
public void testDB() {
  DB db = DbConnector.getDB(address);
  assertNotNull(db);
}

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

ฉันไม่ได้เพิ่มสิ่งต่อไปที่ฉันอยากทำโหลดข้อความจากฐานข้อมูล:

@Test
public void testDB() {
  DB db = DbConnector.getDB(address);
  assertNotNull(db);
  String message = db.fetchMessage(key);
  assertEquals("hello world", message);
}

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

@Test
public void testDB() {
  DB db = DbConnector.getDB(address);
  assertNotNull(db);
  String message = db.fetchMessage(key);
  assertEquals("hello world", message);
  message = "foo bar";
  db.storeMessage(message);
  message = db.fetchMessage();
  assertEquals("foo bar", message);
}

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


4
และกองกำลัง TDD คุณ refactor มากดังนั้นคุณจะได้รับเข้าสู่โหมดการทำงานของ refactoring อย่างต่อเนื่องซึ่งจะช่วยในการฝ่ากำแพงอิฐรหัส messed เช่นprogrammers.stackexchange.com/questions/86364/...กล่าวถึง
ประจบประแจง

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

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

5
อืมมันดูเหมือนกับแฟนคลับของ TDD ..... เกิดอะไรขึ้นกับการใช้ปากกาและกระดาษในการร่างสถาปัตยกรรม? หรือฉันเป็นแฟชั่นเก่าและไม่ "
ทันสมัย

1
ปากกาและกระดาษ (หรือไวท์บอร์ด) เป็นสิ่งที่ดี ร่างแผนโดยรวมเป็นภาพรวม ถ้ามันไม่พอดีกับกระดาษมันซับซ้อนเกินไป เมื่อคุณมีแผนภาพใหญ่คุณสามารถยุ่งกับ BDD เยาะเย้ยและอื่น ๆ
Donal Fellows

10

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

นั่นไม่ได้หมายความว่าจะไม่มีการวางแผนมากนัก แต่มันเกิดขึ้นอย่างรวดเร็วและบ่อยขึ้นเหมือนดูเดิลบนเศษเหล็กหรือในหัวของฉัน โดยรวมแล้วบางครั้งฉันเรียกกระบวนการทำซ้ำขนาดเล็กนี้เพราะพวกเขาใช้เวลา 5-20 นาทีในแต่ละครั้งและจากประสบการณ์ใช้เวลา 2-3 ปีกว่าจะเสร็จสิ้นสิ่งที่ฉันกำลังทำอยู่ (ขึ้นอยู่กับสิ่งที่ฉันกำลังทำ)

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


1
+1 สำหรับการพูดถึงการเขียน เมื่อเร็ว ๆ นี้ฉันเพิ่งใช้วิธีการปรับโครงสร้างบ่อยครั้งจากการเข้ารหัสและนำไปใช้กับการเขียน ทำงานได้ดีมากสำหรับฉัน
Zsolt Török

2

บางสิ่งที่อาจใช้งานได้:

  • ระบุปัญหาหลักที่คุณพยายามแก้ไข - อะไรคือสิ่งที่คุณต้องการทำ ใช้งานเพียงแค่นั้นและรหัสสนับสนุนขั้นต่ำสุดที่จะทำให้มันรัน เมื่อมันได้ผลตามความพึงพอใจของคุณให้สร้างซ้ำ ๆ ซ้ำ ๆ โดยไม่ต้องใช้ความเมตตาในแต่ละขั้นตอน
  • ดูว่ากระบวนทัศน์การเขียนโปรแกรมอื่น ๆ เหมาะกับคุณหรือไม่ แม้จะมีข้อดีทั้งหมดของมัน แต่การเขียนโปรแกรมเชิงวัตถุไม่ใช่คำตอบของปัญหาทั้งหมดและสมองของโปรแกรมเมอร์ไม่ได้ทำงานอย่างนั้น เลือกภาษาทำงาน (บริสุทธิ์) เขียนโค้ดโพรซีเดอร์ ดำดิ่งลงไปถึงระดับฮาร์ดแวร์และทำ C หรืออาจจะเป็นแอสเซมเบลอร์ ฯลฯ บางภาษาที่อาจทำให้คุณนึกไม่ถึง (สมมติว่าคุณกำลังใช้ภาษา C ++ / Java / C # / VB / ... ): Haskell, ML, Lisp (ภาษาต่าง ๆ ให้เลือก), Erlang, Prolog, Smalltalk, Javascript (หากคุณปล่อยให้มันพยายามทำตัวเหมือน Java และโอบกอดธรรมชาติการปิดของมันแทน), C, Pascal, awk และอาจเป็นโหลมากกว่า คุณสมบัติที่สำคัญคือพวกเขาจะต้องแตกต่างจากที่คุณใช้ตอนนี้ นี่ไม่ใช่สิ่งที่คุณต้องการทำในโครงการขนาดใหญ่ที่มีเงินเดิมพันมากมาย
  • ใช้วิธีการออกแบบที่แตกต่างอย่างสิ้นเชิง ดูว่าคุณสามารถรับการออกแบบจากมุมที่แตกต่าง ฉันคิดว่าคุณมักจะเริ่มออกแบบโดยการจัดชั้นเรียนของคุณ คุณเริ่มด้วยโครงสร้างข้อมูลสำหรับการเปลี่ยนแปลงอย่างไร หรือวิธีการที่คุณออกแบบ UI ก่อนวาดรูปแบบการป้อนข้อมูลอย่างแท้จริงก่อนที่จะออกแบบฟังก์ชั่นใด ๆ

1

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

หลังจากนั้นจะเป็นประโยชน์ต่อการใช้วิธี TDD หรือ BDD ที่ Asaf กล่าวถึงเพื่อดำเนินการตามโครงการต่อไป


+1 ฉันเห็นด้วย วางแผนที่จะทิ้งความพยายามครั้งแรก ถือว่าเป็นประสบการณ์การเรียนรู้ ฉันถูกโยนไปมากถึงหกก่อนที่ฉันคิดว่าฉันต้องการที่จะติดกับเจ็ด
Mike Dunlavey

1

คุณไม่ต้องการมันดังนั้นอย่าคิดมากตอนแรก

ลงทุนเวลามากขึ้นเพื่อกำหนดให้เข้าใจเป้าหมายและปัญหา

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


0

ฉันจะสมมติว่าเรากำลังดูโครงการขนาดกลาง
ฉันจะเริ่มต้นด้วยการไปบนกระดานวาดภาพ คุณควรเตรียมความพร้อมด้านการใช้งานและไม่ใช้งานให้พร้อมก่อนดำเนินการ ก่อนอื่นคุณจะพบกับสถาปัตยกรรมซอฟต์แวร์เช่นดูรูปแบบสถาปัตยกรรมที่เหมาะสมกับความต้องการของคุณ
เมื่อคุณตัดสินใจว่าสถาปัตยกรรมของคุณมีลักษณะอย่างไรคุณควรเข้าสู่การออกแบบระดับต่ำ i ดู e เอนทิตีชั้นเรียนและฟังก์ชั่นทั้งหมด . ที่นี่คุณจะลองและระบุรูปแบบการออกแบบที่เหมาะสมอีกครั้งในกระบวนการคุณจะรู้ว่าคลาสพื้นฐานของคุณคืออะไรและอินเทอร์เฟซที่คุณต้องการ
จากนั้นคุณสามารถสร้างกรอบงานและทดสอบแบบรวดเร็วเพื่อดูว่าสิ่งนี้ ตอบสนองทุกความต้องการของคุณ
ฉันจะไปกับการทดสอบพัฒนาตามที่ @Asaf ได้แนะนำ

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


0

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

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

  • จัดวางช่วงเวลาที่เหมาะสมในการทำโครงการโดยไม่ต้องใช้คอมพิวเตอร์ ลองนึกภาพสิ่งที่คุณพยายามจะทำให้สำเร็จและมองหาเซนเซนที่เหนือระดับ OO / Design Madness


0

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

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


0

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

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

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