คำถามติดแท็ก clean-code

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

6
คุณจะหลีกเลี่ยงการวนซ้ำอย่างไม่สิ้นสุดผ่านการออกแบบที่ดีที่สุดที่เท่ากันได้อย่างไร
อาจจะเหมือนหลาย ๆ คนฉันมักพบว่าตัวเองปวดหัวกับปัญหาการออกแบบซึ่งตัวอย่างเช่นมีรูปแบบการออกแบบ / วิธีการบางอย่างที่ดูเหมือนจะเหมาะกับปัญหาและมีประโยชน์ตามที่ต้องการ บ่อยครั้งที่มีข้อแม้บางอย่างซึ่งทำให้เป็นการยากที่จะใช้รูปแบบ / วิธีการโดยไม่ต้องทำงานใด ๆ ซึ่งจะส่งผลเสียต่อรูปแบบ / วิธีการ ฉันสามารถจบการวนซ้ำได้ง่ายในหลายรูปแบบ / วิธีการเพราะสามารถคาดเดาได้ว่าเกือบทั้งหมดมีข้อแม้ที่สำคัญมากในสถานการณ์จริงซึ่งไม่มีวิธีแก้ปัญหาที่ง่าย ตัวอย่าง: ฉันจะให้คุณตัวอย่างตามสมมุติบนพื้นฐานของจริงฉันเพิ่งพบ สมมติว่าฉันต้องการใช้การเรียงซ้อนมากกว่าการสืบทอดเนื่องจากลำดับชั้นการสืบทอดได้ขัดขวางความสามารถในการปรับขนาดของรหัสในอดีต ฉันอาจ refactor รหัส แต่แล้วพบว่ามีบริบทบางอย่างที่ superclass / baseclass เพียงต้องการเรียกฟังก์ชันการทำงานใน subclass แม้จะพยายามหลีกเลี่ยง วิธีที่ดีที่สุดถัดไปดูเหมือนว่าจะใช้รูปแบบผู้แทน / ผู้สังเกตการณ์ครึ่งและรูปแบบองค์ประกอบครึ่งเพื่อให้ซูเปอร์คลาสสามารถมอบหมายพฤติกรรมหรือเพื่อให้คลาสย่อยสามารถสังเกตเห็นเหตุการณ์ซูเปอร์คลาส จากนั้นชั้นเรียนจะสามารถปรับขนาดได้และบำรุงรักษาน้อยลงเพราะมันไม่ชัดเจนว่าควรจะขยายเวลาออกไปอย่างไรนอกจากนี้ยังเป็นการยากที่จะขยายผู้ฟัง / ผู้เข้าร่วมประชุมที่มีอยู่ ข้อมูลก็ไม่ได้ถูกซ่อนไว้อย่างดีเพราะใคร ๆ ก็เริ่มต้องการทราบถึงการนำไปปฏิบัติเพื่อดูวิธีการขยายซูเปอร์คลาส (เว้นแต่คุณจะใช้ความคิดเห็นอย่างกว้างขวาง) ดังนั้นหลังจากนี้ฉันอาจเลือกที่จะเพียงแค่ใช้ผู้สังเกตการณ์หรือผู้ได้รับมอบหมายอย่างสมบูรณ์เพื่อหลีกเลี่ยงข้อเสียที่มาพร้อมกับการผสมผสานวิธีการต่างๆ อย่างไรก็ตามสิ่งนี้มาพร้อมกับปัญหาของตัวเอง ตัวอย่างเช่นฉันอาจพบว่าฉันต้องมีผู้สังเกตการณ์หรือผู้รับมอบสิทธิ์เพื่อเพิ่มจำนวนพฤติกรรมจนกระทั่งฉันต้องมีผู้สังเกตการณ์ / ผู้ได้รับมอบหมายสำหรับพฤติกรรมทุกอย่าง ทางเลือกหนึ่งอาจจะมีเพียงผู้ฟัง / ผู้รับมอบสิทธิ์ที่ใหญ่สำหรับพฤติกรรมทั้งหมด แต่จากนั้นคลาสที่ใช้งานจะจบลงด้วยวิธีการที่ว่างเปล่ามากมายเป็นต้น จากนั้นฉันอาจลองวิธีอื่น แต่ก็มีปัญหามากมายเช่นกัน จากนั้นคนต่อไปและอีกคนหนึ่งหลังจาก …

1
ปัญหาในการเข้าใจโค้ดที่ดูสะอาดตาในชีวิตจริง
ขณะนี้ฉันกำลังอ่านและทำงานผ่าน "รหัสสะอาด: หนังสือฝีมือซอฟต์แวร์เปรียว" โดย Robert C. Martin ผู้เขียนพูดถึงว่าฟังก์ชั่นควรทำสิ่งใดสิ่งหนึ่งเท่านั้นจึงค่อนข้างสั้น มาร์ตินเขียน: นี่ก็หมายความว่าบล็อกภายในถ้าคำสั่งคำสั่งอื่นในขณะที่คำสั่งและอื่น ๆ ควรมีความยาวหนึ่งบรรทัด อาจเป็นไปได้ว่าสายควรจะเรียกฟังก์ชั่น สิ่งนี้ไม่เพียงทำให้ฟังก์ชั่นการปิดล้อมมีขนาดเล็ก แต่ยังเพิ่มมูลค่าเอกสารเพราะฟังก์ชั่นที่เรียกว่าภายในบล็อกสามารถมีชื่อที่สื่อความหมายได้ดี นี่ก็หมายความว่าหน้าที่ไม่ควรใหญ่พอที่จะเก็บโครงสร้างที่ซ้อนกัน ดังนั้นระดับเยื้องของฟังก์ชันไม่ควรมากกว่าหนึ่งหรือสอง แน่นอนสิ่งนี้ทำให้ฟังก์ชั่นการอ่านและทำความเข้าใจง่ายขึ้น มันสมเหตุสมผล แต่ดูเหมือนขัดแย้งกับตัวอย่างของสิ่งที่ฉันเห็นว่าเป็นโค้ดที่สะอาด ใช้วิธีการต่อไปนี้เช่น: public static boolean millerRabinPrimeTest(final int n) { final int nMinus1 = n - 1; final int s = Integer.numberOfTrailingZeros(nMinus1); final int r = nMinus1 >> s; //r must be …
10 clean-code 

2
หลีกเลี่ยง getters และ setters โดยแสดงข้อมูลผู้ใช้
พื้นหลัง ฉันกำลังอ่าน "หนังสือรหัสสะอาด" และใน paralel ฉันกำลังทำงานกับวัตถุแบบคาลินิเทนิกกะตะเช่นบัญชีธนาคารและฉันติดอยู่กับกฎนั้น: กฎข้อที่ 9 ของวัตถุแบบคาลิสฟีนิกคือเราไม่ใช้ทะลุหรือเซ็ตเตอร์ ดูเหมือนจะสนุกมากและฉันเห็นด้วยกับหลักการนี้ ยิ่งไปกว่านั้นที่หน้า 98-99 ของ Clean Code ผู้เขียนอธิบายว่า getters / setters ทำลายสิ่งที่เป็นนามธรรมและเราไม่ต้องถามวัตถุของเรา แต่เราต้องบอกวัตถุของเรา มันทำให้รู้สึกที่สมบูรณ์แบบในใจของฉันและฉันเห็นด้วยกับหลักการนี้อย่างเต็มที่ ปัญหาเกิดขึ้นในทางปฏิบัติ บริบท ตัวอย่างเช่นฉันมีแอปพลิเคชันที่ฉันจะต้องแสดงรายชื่อผู้ใช้บางส่วนและเพื่อแสดงรายละเอียดผู้ใช้ ผู้ใช้ของฉันประกอบด้วย: -> Name --> Firstname --> String --> Lastname --> String -> PostalAddress --> Street --> String --> PostalCode --> String ปัญหา ฉันจะทำอย่างไรหรือฉันจะทำอย่างไรเพื่อหลีกเลี่ยง getters เมื่อฉันเพียงต้องการแสดงข้อมูลอย่างง่าย …

3
ทำความสะอาดรหัสและวัตถุไฮบริดและความอิจฉาของคุณสมบัติ
ดังนั้นฉันเพิ่งทำ refactorings สำคัญบางอย่างกับรหัสของฉัน หนึ่งในสิ่งสำคัญที่ฉันพยายามทำคือแยกชั้นเรียนออกเป็นวัตถุข้อมูลและวัตถุผู้ปฏิบัติงาน สิ่งนี้ได้รับแรงบันดาลใจเหนือสิ่งอื่นใดตามมาตราของClean Code นี้ : ผสมผสาน ความสับสนนี้บางครั้งนำไปสู่โครงสร้างข้อมูลแบบไฮบริดที่โชคร้ายนั่นคือวัตถุครึ่งหนึ่งและโครงสร้างข้อมูลครึ่งหนึ่ง พวกเขามีฟังก์ชั่นที่ทำสิ่งที่สำคัญและพวกเขายังมีตัวแปรสาธารณะหรือสาธารณะ accessors และ mutators ที่สำหรับทุก intents และวัตถุประสงค์ทำให้ตัวแปรส่วนตัวสาธารณะสาธารณะดึงดูดฟังก์ชั่นภายนอกอื่น ๆ ที่จะใช้ตัวแปรเหล่านั้นวิธีที่โปรแกรมขั้นตอนจะใช้ โครงสร้างข้อมูล. ลูกผสมดังกล่าวทำให้ยากที่จะเพิ่มฟังก์ชั่นใหม่ แต่ก็ทำให้มันยากที่จะเพิ่มโครงสร้างข้อมูลใหม่ พวกเขาเลวร้ายที่สุดของทั้งสองโลก หลีกเลี่ยงการสร้างพวกเขา พวกเขาบ่งบอกถึงการออกแบบที่ยุ่งเหยิงซึ่งผู้เขียนไม่แน่ใจหรือแย่กว่านั้นไม่รู้ว่าพวกเขาต้องการการปกป้องจากฟังก์ชั่นหรือประเภทใด เมื่อเร็ว ๆ นี้ฉันกำลังดูรหัสไปยังหนึ่งในวัตถุงานของฉัน (ที่เกิดขึ้นกับรูปแบบผู้เข้าชม ) และเห็นสิ่งนี้: @Override public void visit(MarketTrade trade) { this.data.handleTrade(trade); updateRun(trade); } private void updateRun(MarketTrade newTrade) { if(this.data.getLastAggressor() != newTrade.getAggressor()) { this.data.setRunLength(0); …

5
วิธีแก้ปัญหาที่ใช้งานได้จริงสำหรับปัญหานี้จะสะอาดเหมือนความจำเป็นหรือไม่?
ฉันมีแบบฝึกหัดใน Python ดังนี้: พหุนามได้รับเป็น tuple ของค่าสัมประสิทธิ์ดังกล่าวว่าอำนาจจะถูกกำหนดโดยดัชนีเช่น: (9,7,5) หมายถึง 9 + 7 * x + 5 * x ^ 2 เขียนฟังก์ชันเพื่อคำนวณค่าสำหรับ x ที่กำหนด ตั้งแต่ฉันเข้าสู่การเขียนโปรแกรมการทำงานเมื่อเร็ว ๆ นี้ฉันเขียน def evaluate1(poly, x): coeff = 0 power = 1 return reduce(lambda accu,pair : accu + pair[coeff] * x**pair[power], map(lambda x,y:(x,y), poly, range(len(poly))), 0) ซึ่งฉันคิดว่าอ่านไม่ได้ดังนั้นฉันจึงเขียน def …

7
เป็นสไตล์ที่ไม่ดีที่จะตรวจสอบสภาพซ้ำซ้อนหรือไม่?
ฉันมักจะไปที่ตำแหน่งในรหัสของฉันที่ฉันพบว่าตัวเองกำลังตรวจสอบเงื่อนไขที่เฉพาะเจาะจงซ้ำแล้วซ้ำอีก ฉันต้องการให้คุณตัวอย่างเล็ก ๆ : สมมติว่ามีไฟล์ข้อความที่มีบรรทัดที่ขึ้นต้นด้วย "a", บรรทัดที่ขึ้นต้นด้วย "b" และบรรทัดอื่น ๆ และจริง ๆ แล้วฉันต้องการทำงานกับสองบรรทัดแรกเท่านั้น รหัสของฉันจะมีลักษณะเช่นนี้ (ใช้ python แต่อ่านมันเป็นรหัสเทียม): # ... clear_lines() # removes every other line than those starting with "a" or "b" for line in lines: if (line.startsWith("a")): # do stuff elif (line.startsWith("b")): # magic else: # this else is …

4
รูปแบบการออกแบบสำหรับการจัดการการตอบสนอง
ส่วนใหญ่เวลาที่ฉันเขียนโค้ดบางอย่างที่จัดการการตอบสนองสำหรับการเรียกใช้ฟังก์ชันบางฉันได้รับโครงสร้างรหัสต่อไปนี้: ตัวอย่าง: นี่คือฟังก์ชันที่จะจัดการการรับรองความถูกต้องสำหรับระบบเข้าสู่ระบบ class Authentication{ function login(){ //This function is called from my Controller $result=$this->authenticate($username,$password); if($result=='wrong password'){ //increase the login trials counter //send mail to admin //store visitor ip }else if($result=='wrong username'){ //increase the login trials counter //do other stuff }else if($result=='login trials exceeded') //do some stuff }else if($result=='banned ip'){ …

6
รหัสใดควรรวมอยู่ในคลาสนามธรรม?
เมื่อเร็ว ๆ นี้ฉันมีปัญหาเกี่ยวกับการใช้คลาสที่เป็นนามธรรม บางครั้งคลาสนามธรรมจะถูกสร้างขึ้นล่วงหน้าและทำงานเป็นแม่แบบของวิธีการเรียนที่ได้รับจะทำงาน ซึ่งหมายความว่ามากหรือน้อยที่พวกเขามีฟังก์ชั่นระดับสูงบางอย่าง แต่ออกรายละเอียดบางอย่างที่จะดำเนินการโดยชั้นเรียนที่ได้รับ ชั้นนามธรรมกำหนดความต้องการรายละเอียดเหล่านี้โดยการวางวิธีการบางอย่างที่เป็นนามธรรม ในกรณีเช่นนี้คลาสนามธรรมจะทำงานเหมือนกับพิมพ์เขียวคำอธิบายระดับสูงของฟังก์ชันหรือสิ่งที่คุณต้องการเรียกใช้ ไม่สามารถใช้ด้วยตนเองได้ แต่ต้องมีความเชี่ยวชาญในการกำหนดรายละเอียดที่ถูกทิ้งไว้จากการใช้งานระดับสูง บางครั้งมันเกิดขึ้นที่คลาสนามธรรมถูกสร้างขึ้นหลังจากการสร้างคลาส "ที่ได้รับ" บางส่วน (เนื่องจากคลาสแม่ / นามธรรมไม่ได้อยู่ที่นั่นพวกเขายังไม่ได้รับมา แต่คุณรู้ว่าฉันหมายถึงอะไร) ในกรณีเหล่านี้คลาสนามธรรมมักจะใช้เป็นสถานที่ที่คุณสามารถใส่รหัสทั่วไปใด ๆ ที่คลาสที่ได้รับปัจจุบันมี หลังจากทำการสังเกตข้างต้นฉันสงสัยว่าในสองกรณีนี้ควรเป็นกฎ รายละเอียดใด ๆ ที่ควรจะถูกทำให้กระฉับกระเฉงขึ้นไปสู่ชั้นนามธรรมเพียงเพราะพวกเขากำลังเกิดขึ้นเป็นเรื่องธรรมดาในทุกชั้นเรียนที่ได้รับ? ควรใช้รหัสทั่วไปที่ไม่ได้เป็นส่วนหนึ่งของฟังก์ชั่นระดับสูงหรือไม่? รหัสที่อาจไม่มีความหมายสำหรับคลาสนามธรรมควรมีเพียงเพราะมันเกิดขึ้นเป็นเรื่องธรรมดาสำหรับคลาสที่ได้รับ? ขอยกตัวอย่าง: คลาสนามธรรม A มีเมธอด a () และเมธอด abstract aq () เมธอด aq () ทั้งคลาสที่ได้รับ AB และ AC ใช้เมธอด b () ควรย้าย b () ไปที่ …

1
“ TILT” หมายถึงอะไรในความคิดเห็น
ฉันกำลังอ่านClean Codeของ Robert C. Martin และวลีนั้นTILTลึกลับปรากฏขึ้นในตัวอย่างโค้ดบางอย่าง ตัวอย่าง (ใน Java โดยวิธี): ... public String errorMessage() { switch (status) { case ErrorCode.OK: // TILT - Should not get here. return ""; case ErrorCode.UNEXPECTED_ARGUMENT: return "Unexpected argument"; case ErrorCode.MISSING_ARGUMENT: return "Missing argument"; ... } ... จากบริบทนี้ฉันเดาTILTว่าจะกำหนดสถานะที่ไม่สามารถเข้าถึงได้และรวมไว้เพียงเพื่อทำให้คอมไพเลอร์ (ตัวอย่างเช่นในโค้ดด้านบนTILTปรากฏในErrorCode.OKกรณีเนื่องจากไม่ควรมีข้อความแสดงข้อผิดพลาดหากรัฐเป็นOK) แต่ ฉันไม่แน่ใจ. ไม่มีใครรู้ว่าสิ่งที่TILTหมายถึง / หมายถึง?

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

6
จะลดสวิตช์ในคำสั่ง switch ได้อย่างไร?
ดังนั้นฉันจึงสร้างวิธีการสร้างบรรทัดคำทักทายตามคนสองคนจากฐานข้อมูล มีพารามิเตอร์สี่ตัว ได้แก่ สองชื่อ ( name1และname2) และสองเพศ ( genderและgender2) สำหรับการรวมเพศทุกครั้งฉันมีเอาท์พุทที่แตกต่างกัน ตัวอย่างเช่น: ถ้าเพศ 1 คือM(ชาย) และเพศ 2 เป็นเช่นMกันผลลัพธ์ควรเป็นดังนี้: Dear Sir name1 and Sir name2, ในเวลานี้สวิตช์ของฉันมีลักษณะดังนี้: switch(gender1){ case 'M': switch(gender2){ case 'M': printf("Dear Sir %s and Sir %s", name1, name2); break; case 'W': printf("Dear Sir %s and Madame %s", name1, name2); break; …

3
ฉันควรใส่วิธีที่ทำให้การร้องขอ Http รับข้อมูลจากบริการเว็บในการพัฒนา iOS ที่ไหน
ฉันมี Model Car ในแอปพลิเคชัน iOS ของฉันซึ่งเป็นพารามิเตอร์เช่นชื่อ, ปี, ค่าและอื่น ๆ ถูกดึงมาจากบริการเว็บเพื่อเติมรายการด้วยข้อมูลรถยนต์ ฉันควรจะวางวิธีการแบบอะซิงโครนัสไปที่เซิร์ฟเวอร์และส่งกลับอาร์เรย์รถยนต์ (วิธีนี้แปลง JSON ไปเป็นอาร์เรย์รถยนต์แล้วหรือไม่) วิธีการปัจจุบันของฉันเป็นวิธีการคงที่ในชั้นเรียนรถยนต์ของฉันที่ได้รับ HttpClient (ดังนั้นฉันจึงสามารถทดสอบหน่วยมันเยาะเย้ยลูกค้า) และส่งคืน NSArray ของรถยนต์เป็นสิ่งที่ดีหรือไม่? พวกคุณทำอะไรในสถานการณ์นี้ ฉันกังวลเพราะเมื่อเร็ว ๆ นี้ฉันเริ่มอ่านโค้ดที่สะอาดซึ่งบอกว่า Class ควรทำสิ่งเดียวเท่านั้นและวิธีที่ฉันมีตอนนี้ดูเหมือนจะทำ 2 สิ่ง (เก็บข้อมูลเกี่ยวกับรถยนต์และรับรายการรถยนต์)

7
กำลังตรวจสอบว่าเมธอดส่งคืน false หรือไม่: กำหนดผลลัพธ์ให้กับตัวแปรชั่วคราวหรือทำให้การเรียกใช้เมธอดตรงตามเงื่อนไขหรือไม่
เป็นวิธีปฏิบัติที่ดีในการเรียกใช้เมธอดที่ส่งคืนค่าจริงหรือเท็จในคำสั่ง if หรือไม่? บางสิ่งเช่นนี้ private void VerifyAccount() { if (!ValidateCredentials(txtUser.Text, txtPassword.Text)) { MessageBox.Show("Invalid user name or password"); } } private bool ValidateCredentials(string userName, string password) { string existingPassword = GetUserPassword(userName); if (existingPassword == null) return false; var hasher = new Hasher { SaltSize = 16 }; bool passwordsMatch = hasher.CompareStringToHash(password, …
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.