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

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

4
วิธีที่สะอาดที่สุดในการเขียนซอฟต์แวร์ที่มีขั้นตอนตามหลักเหตุผลในภาษา OO
ฉันเป็นวิศวกรไฟฟ้าและฉันไม่รู้ว่าฉันทำอะไรอยู่ โปรดบันทึกผู้ดูแลรหัสของฉันในอนาคต เมื่อเร็ว ๆ นี้ฉันได้ทำงานกับโปรแกรมขนาดเล็กจำนวนมาก (ใน C #) ซึ่งฟังก์ชั่นการใช้งานเป็น "ขั้นตอน" ตามหลักเหตุผล ตัวอย่างเช่นหนึ่งในนั้นคือโปรแกรมที่รวบรวมข้อมูลจากฐานข้อมูลต่าง ๆ ใช้ข้อมูลนั้นเพื่อสร้างเรียงลำดับของหน้าสรุปพิมพ์และจากนั้นออก ตรรกะที่จำเป็นสำหรับทั้งหมดนั้นอยู่ที่ประมาณ 2,000 บรรทัด แน่นอนฉันไม่ต้องการสิ่งทั้งหมดในที่เดียวmain()แล้ว "ทำความสะอาด" กับ#regions เป็นนักพัฒนาก่อนหน้านี้ได้ทำ (ตัวสั่น) นี่คือบางสิ่งที่ฉันได้ลองไปแล้วโดยที่ไม่พึงพอใจมาก: สร้างยูทิลิตี้แบบคงที่สำหรับการใช้งานแต่ละบิตอย่างคร่าวๆเช่น DatabaseInfoGetter, SummaryPageGenerator และ PrintUtility ทำให้ฟังก์ชั่นหลักดูเหมือนว่า: int main() { var thisThing = DatabaseInfoGetter.GetThis(); var thatThing = DatabaseInfoGetter.GetThat(); var summary = SummaryPageGenerator.GeneratePage(thisThing, thatThing); PrintUtility.Print(summary); } สำหรับโปรแกรมหนึ่งฉันยังไปกับอินเตอร์เฟส int main() …

8
การเปิดและปิดคุณสมบัติ UI (หรืออื่น ๆ ) ขึ้นอยู่กับวันที่ - รหัสกลิ่นหรือไม่
เรามีระบบอันยิ่งใหญ่ที่เขียนใน ASP.NET 2.0 ที่เราต้องเพิ่มฟังก์ชั่นบางอย่าง ปัญหาคือผลิตภัณฑ์บางอย่างมีคุณสมบัติ UI ที่จะต้องเปิดใช้งานสำหรับธุรกิจที่เริ่มต้นหลังจากวันที่แน่นอน (และอื่น ๆ ปิด) ในขณะที่หน้าจะต้องเหมือนกันสำหรับธุรกิจที่มีอยู่ ฉันกำลังผลักดันให้มีการเขียนหน้าใหม่สำหรับธุรกิจใหม่เนื่องจากฉันพบความคิดเกี่ยวกับสวิตช์ JavaScript UI ที่อิงตามวันที่และการผสมตัวควบคุมเว็บสำหรับธุรกิจเก่าและใหม่ให้เป็น "ไม่เรียบร้อย" (สำหรับคำที่ดีกว่า ) การฝึกฝนให้มี UI ตามเวลาเป็นคุณลักษณะที่เป็นที่ยอมรับอย่างกว้างขวางและหากไม่เป็นเช่นนั้นความเสี่ยงที่ทราบกันดีในการใฝ่หาแนวทางปฏิบัตินั้นคืออะไร?

5
การเขียนรหัสที่สามารถทดสอบได้เทียบกับการหลีกเลี่ยงความเอนเอียงแบบเก็งกำไร
ฉันอ่านข้อความในบล็อกเมื่อเช้านี้และพบสิ่งนี้ : ถ้าคลาสเดียวที่ใช้อินเทอร์เฟซลูกค้าคือ CustomerImpl คุณไม่มีความหลากหลายและความสามารถในการสับเปลี่ยนได้จริง ๆ เนื่องจากไม่มีวิธีใดที่จะทดแทน runtime ได้เลย มันเป็นเรื่องธรรมดาทั่วไป นั่นเป็นเหตุผลสำหรับฉันเมื่อการใช้งานอินเทอร์เฟซเพิ่มความซับซ้อนและหากมีเพียงการใช้เพียงครั้งเดียวอย่างใดอย่างหนึ่งอาจยืนยันว่ามันเพิ่มความซับซ้อนที่ไม่จำเป็น การเขียนโค้ดที่มีความเป็นนามธรรมมากกว่าที่ควรจะเป็นมักจะถูกพิจารณาว่าเป็นกลิ่นของรหัสที่เรียกว่า "การเก็งกำไรทั่วไป" (หรือที่กล่าวถึงในโพสต์) แต่ถ้าฉันติดตาม TDD ฉันไม่สามารถสร้างการทดสอบเป็นสองเท่าได้อย่างง่ายดายโดยไม่ต้องคำนึงถึงการเก็งกำไรไม่ว่าจะอยู่ในรูปแบบของการใช้อินเทอร์เฟซหรือตัวเลือก polymorphic อื่น ๆ ของเรา ดังนั้นเราจะคืนดีการแลกเปลี่ยนนี้ได้อย่างไร มันคุ้มค่าหรือไม่ที่จะเป็นการเก็งกำไรโดยทั่วไปเพื่ออำนวยความสะดวกในการทดสอบ / TDD? หากคุณใช้การทดสอบเป็นสองเท่าให้นับเป็นการนำไปใช้ครั้งที่สองและทำให้ความคิดทั่วๆไปไม่เป็นการเก็งกำไรอีกต่อไป? คุณควรพิจารณากรอบการเยาะเย้ยเฮฟวี่เวทที่ช่วยให้ผู้เยาะเย้ยเป็นรูปธรรมมากขึ้น (เช่นโมลเทียบกับ Moq ใน C # โลก) หรือไม่ หรือคุณควรทดสอบกับชั้นเรียนที่เป็นรูปธรรมและเขียนสิ่งที่อาจพิจารณาว่าเป็นการทดสอบ "การรวม" จนกว่าจะถึงเวลาที่การออกแบบของคุณต้องมีความหลากหลาย ฉันอยากรู้อยากเห็นที่จะอ่านคนอื่นจะใช้เวลาในเรื่องนี้ - ขอบคุณล่วงหน้าสำหรับความคิดเห็นของคุณ

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

4
วิธีนี้ในการเรียกฟังก์ชั่นเป็นการฝึกที่ไม่ดีหรือไม่?
ฉันมีรหัสต่อไปนี้: public void moveCameraTo(Location location){ moveCameraTo(location.getLatitude(), location.getLongitude()); } public void moveCameraTo(double latitude, double longitude){ LatLng latLng = new LatLng(latitude, longitude); moveCameraTo(latLng); } public void moveCameraTo(LatLng latLng){ GoogleMap googleMap = getGoogleMap(); cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, INITIAL_MAP_ZOOM_LEVEL); googleMap.moveCamera(cameraUpdate); } ฉันคิดว่าด้วยวิธีนี้ฉันกำจัดความรับผิดชอบในการรู้ว่าสิ่งที่อยู่LatLngในชั้นเรียนอื่นเช่น และคุณไม่จำเป็นต้องเตรียมข้อมูลก่อนเรียกฟังก์ชั่น คุณคิดอย่างไร? วิธีนี้มีชื่อหรือไม่? เป็นการฝึกที่ไม่ดีจริง ๆ หรือ?

4
ทำใหม่ฟังก์ชั่นกลับรหัสจำนวนเต็มที่แสดงถึงสถานะที่แตกต่างกัน
ฉันได้รับรหัสอันยิ่งใหญ่ที่ฉันได้รวมตัวอย่างสั้น ๆ ของด้านล่าง มีชื่อสำหรับรูปแบบการต่อต้านนี้โดยเฉพาะหรือไม่? มีคำแนะนำอะไรบ้างสำหรับการปรับโครงสร้างนี้ // 0=Need to log in / present username and password // 2=Already logged in // 3=Inactive User found // 4=Valid User found-establish their session // 5=Valid User found with password change needed-establish their session // 6=Invalid User based on app login // 7=Invalid User based …

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); …

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

1
หากคุณมีตรรกะบางอย่างที่ต้องแชร์ระหว่างสองคอนโทรลเลอร์คุณเก็บไว้ที่ไหน?
ฉันมีชุดของฟังก์ชั่นวัตถุประสงค์เดียวที่ฉันต้องการในตัวควบคุมแยกกันสองตัว ตอนนี้ฉันเพิ่งมีรหัสที่ซ้ำกันและฉันต้องการที่จะกำจัดมัน รหัสนี้เป็นส่วนหนึ่งของคอนโทรลเลอร์และไม่ได้อยู่ในเลเยอร์บริการของฉัน คุณจะวางไว้ที่ไหน
10 mvc  code-smell 

2
การทดสอบหน่วย:“ มันเป็นกลิ่นรหัสหากคุณทำการปรับโครงสร้างใหม่และไม่มีผู้ทำงานร่วมกัน”?
ฉันกำลังอ่านศิลปะของการทดสอบหน่วยโดย Roy Osherove ฉันอยู่ที่หัวข้อ 7.2 การเขียนแบบทดสอบที่คงไว้ซึ่งผู้เขียนมีหมายเหตุเกี่ยวกับกลิ่นรหัสนี้: หมายเหตุ: เมื่อคุณ refactor สถานะภายในที่จะมองเห็นได้จากการทดสอบภายนอกอาจถือได้ว่าเป็นกลิ่นรหัส (สัญญาณว่ามีบางอย่างผิดปกติในการออกแบบหรือตรรกะของรหัส) มันไม่ได้เป็นกลิ่นรหัสเมื่อคุณ refactoring เปิดเผยผู้ทำงานร่วมกัน มันเป็นกลิ่นรหัสหากคุณทำการปรับโครงสร้างใหม่และไม่มีผู้ทำงานร่วมกัน แก้ไข : สิ่งที่ผู้เขียนหมายถึงโดย "ผู้ทำงานร่วมกัน" คือการพึ่งพา ตัวอย่างบางส่วนของเขาสำหรับการพึ่งพาคือคลาสที่เข้าถึงฐานข้อมูลหรือเข้าถึงระบบไฟล์ของระบบปฏิบัติการ นี่คือที่ซึ่งเขากำหนดต้นขั้วและเริ่มใช้คำทำงานร่วมกัน: ต้นขั้วเป็นแทนควบคุมที่มีอยู่การพึ่งพา (หรือ ทำงานร่วมกัน ) ในระบบ ผู้เขียนไม่มีตัวอย่างของกลิ่นรหัสนี้และฉันมีปัญหาในการทำความเข้าใจ / นึกภาพว่ามันจะเป็นอย่างไร บางคนสามารถอธิบายสิ่งนี้ได้มากกว่านี้เล็กน้อยและอาจเป็นตัวอย่างที่ชัดเจน?

2
มันเป็นกลิ่นรหัสหรือไม่ถ้าวัตถุรู้เจ้าของเป็นจำนวนมาก?
ในแอปพลิเคชัน Delphi 2007 ของเราเราใช้โครงสร้างต่อไปนี้มากมาย FdmBasic:=TdmBasicData(FindOwnerClass(AOwner,TdmBasicData)); FindOwnerClass เดินทางลำดับชั้นของเจ้าขององค์ประกอบปัจจุบันขึ้นไปเพื่อหาคลาสที่ระบุ (ในตัวอย่าง TdmBasicData) วัตถุที่เป็นผลลัพธ์จะถูกเก็บไว้ในตัวแปรฟิลด์ FdmBasic เราใช้สิ่งนี้เป็นหลักในการส่งดาต้าโมดูล ตัวอย่าง: เมื่อสร้างรายงานข้อมูลที่ได้จะถูกบีบอัดและจัดเก็บไว้ในเขตข้อมูล Blob ของตารางที่เข้าถึงผ่านดาต้าโมดูลแบบ TdmReportBaseData ในโมดูลที่แยกต่างหากของแอปพลิเคชันของเรามีฟังก์ชั่นเพื่อแสดงข้อมูลจากรายงานในรูปแบบเพจโดยใช้ ReportBuilder รหัสหลักของโมดูลนี้ (TdmRBReport) ใช้คลาส TRBTempdatabase เพื่อแปลงข้อมูล Blob ที่ถูกบีบอัดไปยังตารางต่าง ๆ ที่ใช้งานได้ใน Reportbuilder รันไทม์ Reportdesigner TdmRBReport มีการเข้าถึง TdmReportBaseData สำหรับข้อมูลที่เกี่ยวข้องกับรายงานทุกประเภท (ประเภทของรายงานการตั้งค่ารายงานการคำนวณ ฯลฯ ) TRBTempDatabase ถูกสร้างขึ้นใน TdmRBR พอร์ต แต่ต้องมีการเข้าถึง TdmReportBasedata ดังนั้นตอนนี้จะใช้การก่อสร้างด้านบน: constructor TRBTempDatabase.Create(aOwner: TComponent); begin inherited …

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

12
ตัวดำเนินการรวมคุณสมบัติสำหรับ C #
ตัวดำเนินการรวมค่า null ใน c # อนุญาตให้คุณย่อรหัสได้ if (_mywidget == null) return new Widget(); else return _mywidget; ลงไป: return _mywidget ?? new Widget(); ฉันพบว่าตัวดำเนินการที่มีประโยชน์ที่ฉันต้องการใน C # จะเป็นอันที่อนุญาตให้คุณส่งคืนคุณสมบัติของวัตถุหรือค่าอื่น ๆ ถ้าวัตถุนั้นเป็นโมฆะ ดังนั้นฉันต้องการแทนที่ if (_mywidget == null) return 5; else return _mywidget.Length; ด้วย: return _mywidget.Length ??! 5; ฉันอดไม่ได้ที่จะคิดว่าต้องมีเหตุผลบางอย่างที่ผู้ดำเนินการรายนี้จะไม่มีอยู่จริง มันเป็นกลิ่นรหัสหรือไม่? มีวิธีที่ดีกว่าในการเขียนนี้หรือไม่? (ฉันรู้ถึงรูปแบบวัตถุ null แต่ดูเหมือนว่าจะใช้เกินขีดเพื่อแทนที่รหัสสี่บรรทัดนี้)
9 c#  code-smell  null 
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.