วิศวกรรมซอฟต์แวร์

ถาม - ตอบสำหรับมืออาชีพนักวิชาการและนักเรียนที่ทำงานในวงจรการพัฒนาระบบ

3
การสร้างเลเยอร์ของสิ่งที่เป็นนามธรรมเหนือเลเยอร์ ORM
ฉันเชื่อว่าถ้าคุณมีที่เก็บของคุณใช้ ORM ซึ่งมันมีนามธรรมเพียงพอจากฐานข้อมูล อย่างไรก็ตามที่ที่ฉันทำงานอยู่ตอนนี้บางคนเชื่อว่าเราควรมีเลเยอร์ที่เป็นนามธรรม ORM ในกรณีที่เราต้องการเปลี่ยน ORM ในภายหลัง มันจำเป็นจริงๆหรือเป็นเรื่องง่ายที่จะสร้างเลเยอร์ที่สามารถใช้งานกับ ORM จำนวนมากได้หรือไม่? แก้ไข เพียงเพื่อให้รายละเอียดเพิ่มเติม: เรามีคลาส POCO และคลาสเอนทิตีที่แมปกับ AutoMapper คลาสเอนทิตีถูกใช้โดยเลเยอร์ Repository เลเยอร์ที่เก็บจากนั้นใช้เลเยอร์เพิ่มเติมของสิ่งที่เป็นนามธรรมเพื่อสื่อสารกับ Entity Framework เลเยอร์ธุรกิจไม่มีทางเข้าถึงโดยตรงไปยัง Entity Framework แม้ว่าจะไม่มีเลเยอร์เพิ่มเติมของสิ่งที่เป็นนามธรรมเหนือ ORM สิ่งนี้จำเป็นต้องใช้เลเยอร์บริการที่ผู้ใช้เลเยอร์พื้นที่เก็บข้อมูล ในทั้งสองกรณีชั้นธุรกิจจะถูกแยกออกจาก ORM โดยสิ้นเชิง อาร์กิวเมนต์หลักคือสามารถเปลี่ยน ORM ได้ในอนาคต เนื่องจากมันแปลเป็นภาษาท้องถิ่นภายในเลเยอร์ Repository สำหรับฉันมันแยกกันอยู่แล้วและฉันไม่เห็นว่าทำไมเลเยอร์ abstraction เพิ่มเติมจึงต้องมีรหัส "คุณภาพ"
12 database  orm 

7
หลักการการเปลี่ยนโครงสร้างและเปิด / ปิด
ฉันเพิ่งอ่านเว็บไซต์เกี่ยวกับการพัฒนาโค้ดที่สะอาด (ฉันไม่ได้ใส่ลิงค์ไว้ที่นี่เพราะไม่ใช่ภาษาอังกฤษ) หนึ่งในหลักการที่โฆษณาโดยไซต์นี้คือหลักการเปิดปิด : ส่วนประกอบซอฟต์แวร์แต่ละรายการควรเปิดเพื่อขยายและปิดเพื่อการปรับเปลี่ยน เช่นเมื่อเรานำไปใช้และทดสอบคลาสเราควรแก้ไขเพื่อแก้ไขข้อบกพร่องหรือเพื่อเพิ่มฟังก์ชั่นใหม่ (เช่นวิธีการใหม่ที่ไม่มีผลต่อคลาสที่มีอยู่) ไม่ควรเปลี่ยนฟังก์ชันการทำงานและการใช้งานที่มีอยู่ ผมปกติใช้หลักการนี้ด้วยการกำหนดอินเตอร์เฟซและระดับการดำเนินงานที่สอดคล้องกันI Aเมื่อชั้นเรียนAมีเสถียรภาพ (ดำเนินการและทดสอบ) ปกติแล้วฉันจะไม่แก้ไขมากเกินไป (อาจไม่เลย) เช่น หากข้อกำหนดใหม่มาถึง (เช่นประสิทธิภาพหรือการใช้อินเทอร์เฟซใหม่ทั้งหมด) ที่ต้องมีการเปลี่ยนแปลงโค้ดอย่างมากฉันจะเขียนการใช้งานใหม่Bและใช้ต่อไปAตราบเท่าที่Bยังไม่ครบกำหนด เมื่อBครบกำหนดแล้วสิ่งที่จำเป็นต้องมีก็คือเปลี่ยนวิธีการIสร้างอินสแตนซ์ หากความต้องการใหม่แนะนำการเปลี่ยนแปลงอินเตอร์เฟซเป็นอย่างดีฉันกำหนดอินเตอร์เฟซใหม่และการดำเนินงานใหม่I' A'ดังนั้นI, Aมีแช่แข็งและยังคงอยู่ในการดำเนินการสำหรับระบบการผลิตเป็นเวลานานเป็นI'และA'มีไม่เพียงพอที่มั่นคงเพื่อแทนที่พวกเขา ดังนั้นในมุมมองของการสังเกตเหล่านี้ฉันรู้สึกประหลาดใจเล็กน้อยที่หน้าเว็บนั้นแนะนำให้ใช้การปรับโครงสร้างที่ซับซ้อน "... เนื่องจากไม่สามารถเขียนโค้ดโดยตรงในรูปแบบสุดท้าย" ไม่มีความขัดแย้ง / ความขัดแย้งระหว่างการบังคับใช้หลักการเปิด / ปิดและแนะนำให้ใช้การปรับโครงสร้างที่ซับซ้อนเป็นวิธีปฏิบัติที่ดีที่สุดหรือไม่? หรือความคิดในที่นี้คือเราสามารถใช้ refactorings ที่ซับซ้อนในระหว่างการพัฒนาคลาสAแต่เมื่อคลาสนั้นได้รับการทดสอบสำเร็จแล้วควรจะถูกแช่แข็งหรือไม่

9
รหัสทดสอบคัดลอกและวาง: วิธีนี้แย่แค่ไหน?
งานปัจจุบันของฉันส่วนใหญ่เขียนโค้ดทดสอบ GUI สำหรับแอปพลิเคชันต่างๆที่เราใช้งาน อย่างไรก็ตามฉันพบว่าฉันมักจะคัดลอกและวางรหัสจำนวนมากในการทดสอบ เหตุผลสำหรับเรื่องนี้คือพื้นที่ที่ฉันทดสอบมีแนวโน้มที่จะคล้ายกันมากพอที่จะต้องมีการทำซ้ำ แต่ก็ไม่ได้คล้ายกันมากพอที่จะใส่รหัสลงในเมธอดหรือวัตถุ ฉันพบว่าเมื่อฉันพยายามใช้คลาสหรือวิธีการเพิ่มเติมอย่างกว้างขวางการทดสอบจะยุ่งยากมากขึ้นในการบำรุงรักษาและบางครั้งก็ยากที่จะเขียนตั้งแต่แรก แต่ฉันมักจะคัดลอกโค้ดทดสอบขนาดใหญ่จำนวนหนึ่งจากส่วนหนึ่งแล้ววางลงในอีกส่วนหนึ่งและทำการเปลี่ยนแปลงเล็กน้อยตามที่ฉันต้องการ ฉันไม่ได้ใช้วิธีการเข้ารหัสที่มีโครงสร้างมากขึ้นเช่นการใช้หลักการหรือฟังก์ชั่น OO มากขึ้น ผู้เขียนโค้ดคนอื่นรู้สึกเช่นนี้เมื่อเขียนรหัสทดสอบหรือไม่? เห็นได้ชัดว่าฉันต้องการที่จะปฏิบัติตามหลักการ DRY และ YAGNI แต่ฉันพบว่ารหัสทดสอบ (รหัสทดสอบอัตโนมัติสำหรับการทดสอบ GUI ต่อไป) สามารถทำให้หลักการเหล่านี้ยากที่จะปฏิบัติตาม หรือฉันต้องการเพียงแค่ฝึกฝนการเข้ารหัสและระบบโดยรวมที่ดีขึ้นในการทำสิ่งต่าง ๆ ? แก้ไข: เครื่องมือที่ฉันใช้คือ SilkTest ซึ่งเป็นภาษาที่เป็นกรรมสิทธิ์ที่ชื่อว่า 4Test เช่นกันการทดสอบเหล่านี้ส่วนใหญ่ใช้สำหรับเดสก์ท็อปของ Windows แต่ฉันได้ทำการทดสอบเว็บแอปโดยใช้การตั้งค่านี้เช่นกัน

2
ไลบรารี C ++ 11 ที่รวบรวม (lib, dll และอื่น ๆ ) สามารถเชื่อมโยงกับคอมไพเลอร์ C ++ รุ่นเก่าได้หรือไม่?
สามารถคอมไพเลอร์ C ++ รุ่นเก่า (เช่น VS2008 และ gcc3.4) เชื่อมโยงกับไลบรารีภายนอกที่เขียนด้วย C ++ 11 ได้หรือไม่? ความคิดของฉันคือไฟล์ C ++ 11 .lib เป็นเพียงโค้ดไบต์ในขั้นตอนนี้และไม่ควรรบกวนคอมไพเลอร์รุ่นเก่าที่สร้างขึ้นมาตราบใดที่มันสามารถแก้ไขและเรียกใช้ได้ ฉันกำลังพัฒนาห้องสมุดขนาดเล็กซึ่ง API ยังควรสนับสนุนผู้ใช้ C ++ 03 ดังนั้นมองไปข้างหน้าฉันสงสัยว่ามันโอเคที่จะใช้ห้องสมุดของฉันโดยใช้คุณสมบัติที่เป็นประโยชน์std::unique_ptrเช่นนี้หรือไม่หรือฉันต้องติดกับboost::?
12 c++  c++11 

2
รหัส NOP บางอย่างนั้นแตกต่างจากรหัสอื่นหรือไม่?
ฉันอยากรู้เกี่ยวกับสิ่งนี้สมมติว่าฉันมี: 00000000001 90 nop 00000000002 90 nop 00000000003 90 nop มันทำงานเหมือนกันไหม 00000000001 0F1F00 nop dword [ds:rax] ตัวอย่างที่สองมีผลกระทบอะไรบ้างเมื่อเทียบกับตัวอย่างแรก
12 assembly 

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

2
CQRS + การจัดหากิจกรรม: (แก้ไขให้ถูกต้องหรือไม่) คำสั่งต่างๆจะสื่อสารกันแบบจุดต่อจุดในขณะที่การสื่อสารเหตุการณ์โดเมนผ่าน pub / sub?
โดยทั่วไปฉันพยายามจะคลุมหัวแนวคิดของCQRSและแนวคิดที่เกี่ยวข้อง แม้ว่า CQRS ไม่จำเป็นต้องรวมการส่งข้อความและการจัดหากิจกรรม แต่ดูเหมือนว่าจะเป็นการผสมผสานที่ดี ได้รับกรณีการใช้งานสำหรับการเปลี่ยนแปลงสถานะสำหรับบางสิ่ง (พูดเพื่ออัปเดตคำถามเกี่ยวกับ SO) คุณจะพิจารณาว่าโฟลว์ต่อไปนี้ถูกต้องหรือไม่ ระบบออกรวม UpdateQuestionCommand ซึ่งอาจแยกออกเป็นสองคำสั่งเล็ก: UpdateQuestion ซึ่งมีการกำหนดเป้าหมายที่ Root Aggregate คำถามและ UpdateUserAction (เพื่อนับคะแนน ฯลฯ ) กำหนดเป้าหมายที่ User Aggregate Root สิ่งเหล่านี้ส่งแบบอะซิงโครนัสโดยใช้การส่งข้อความแบบจุดต่อจุด รากรวมทำสิ่งของพวกเขาและถ้าทุกอย่างดำเนินไปได้ดีกับเหตุการณ์ QuestionUpdated และ UserActionUpdated ตามลำดับซึ่งมีสถานะที่ถูกเอาต์ซอร์ซไปยัง Event Store .. เพื่อที่จะยืนยัน yadayada ให้เสร็จสมบูรณ์ไม่ใช่จุดที่นี่จริงๆ เหตุการณ์เหล่านี้จะถูกวางในคิว pub / sub เพื่อออกอากาศ ผู้สมัครสมาชิกใด ๆ (ซึ่งมีแนวโน้มว่าจะมีหนึ่งหรือหลายโปรเจ็คเตอร์ที่สร้างมุมมองอ่าน) มีอิสระที่จะสมัครสมาชิกกับเหตุการณ์เหล่านี้ คำถามทั่วไป: เป็นวิธีปฏิบัติที่ดีที่สุดจริง ๆ หรือไม่ที่คำสั่งนั้นสื่อสารแบบจุดต่อจุด …

2
การใช้ Trie ที่มีประสิทธิภาพสำหรับสตริง Unicode
ฉันกำลังมองหาการใช้งาน String Trie ที่มีประสิทธิภาพ ส่วนใหญ่ฉันพบรหัสเช่นนี้: การใช้งานอ้างอิงใน Java (ต่อวิกิพีเดีย) ฉันไม่ชอบการใช้งานเหล่านี้ด้วยเหตุผลสองประการ: รองรับอักขระได้เพียง 256 ตัวเท่านั้น ฉันต้องครอบคลุมสิ่งต่าง ๆ เช่นไซริลลิก พวกเขาไม่มีประสิทธิภาพหน่วยความจำอย่างมาก แต่ละโหนดมีอาร์เรย์ของการอ้างอิง 256 รายการซึ่งเป็น 4096 ไบต์บนเครื่อง 64 บิตใน Java แต่ละโหนดเหล่านี้สามารถมีโหนดย่อยได้มากถึง 256 โหนดโดยมี 4096 ไบต์สำหรับการอ้างอิงแต่ละโหนด Trie แบบเต็มสำหรับสตริงอักขระ ASCII 2 ทุกตัวจะต้องมีขนาดเกิน 1MB สามสายอักขระ? 256MB สำหรับอาร์เรย์ในโหนดเท่านั้น และอื่น ๆ แน่นอนว่าฉันไม่ได้ตั้งใจที่จะมีสายอักขระทั้งหมด 16 ล้านสายใน Trie ของฉันดังนั้นพื้นที่ว่างจำนวนมากจึงสูญเปล่า อาร์เรย์เหล่านี้ส่วนใหญ่เป็นเพียงการอ้างอิงที่เป็นโมฆะเนื่องจากความจุของพวกมันมีจำนวนเกินกว่าจำนวนคีย์ที่แทรก และถ้าฉันเพิ่มยูนิโค้ด, อาร์เรย์จะมีขนาดใหญ่ขึ้น (ถ่านมีค่า 64k …
12 unicode  trie 

1
ใช้รูปแบบผู้เข้าชมที่มีลำดับชั้นวัตถุขนาดใหญ่
บริบท ฉันได้ใช้กับลำดับชั้นของวัตถุ (ต้นไม้นิพจน์) รูปแบบผู้เข้าชม "หลอก" (หลอกเพราะมันไม่ได้ใช้ส่งสองครั้ง): public interface MyInterface { void Accept(SomeClass operationClass); } public class MyImpl : MyInterface { public void Accept(SomeClass operationClass) { operationClass.DoSomething(); operationClass.DoSomethingElse(); // ... and so on ... } } การออกแบบนี้เป็นที่ตั้งคำถาม แต่ค่อนข้างสะดวกสบายเนื่องจากจำนวนการใช้งานของ MyInterface มีความสำคัญ (~ 50 หรือมากกว่า) และฉันไม่จำเป็นต้องเพิ่มการดำเนินการเพิ่มเติม การใช้งานแต่ละอย่างนั้นไม่ซ้ำกัน (เป็นนิพจน์หรือตัวดำเนินการที่แตกต่างกัน) และบางรายการเป็นคอมโพสิต (เช่นโหนดโอเปอเรเตอร์ที่จะมีโอเปอเรเตอร์ / โหนดใบไม้) Traversal …

5
วิธีการทดสอบไฟล์ jsp
ฉันกำลังพัฒนาแอปพลิเคชัน Java 6 EE และฉันกำลังทดสอบรหัส jsp ของฉันกับอีกอันหนึ่งด้วยเวอร์ชันการทดสอบของการเรียกใช้ฟังก์ชั่นและรหัสที่ใช้ในแอปพลิเคชันดั้งเดิม แต่ดูเหมือนจะหลวมและใช้งานไม่ได้ มีวิธีที่ดีในการทำแบบทดสอบนี้หรือไม่?

2
การจัดทำเอกสารภาษาการเขียนโปรแกรม: คู่มืออ้างอิง
เรากำลังดูเอกสารการปรับปรุงใหม่ในสายผลิตภัณฑ์ของเรา ส่วนหนึ่งของนั้นรวมถึงคู่มืออ้างอิงสำหรับภาษาการเขียนโปรแกรมที่ใช้เป็นส่วนหนึ่งของระบบ เมื่อเขียนคู่มืออ้างอิงสำหรับภาษาการเขียนโปรแกรมวิธีที่ดีที่สุดในการจัดโครงสร้างเพื่อให้เกิดประโยชน์สูงสุดต่อผู้ที่ใช้ภาษาใหม่คืออะไร? อะไรคือประเด็นสำคัญของคำหลักแต่ละคำที่บันทึกไว้? วากยสัมพันธ์ ลักษณะ อาร์กิวเมนต์ - ถ้ามี ส่งคืนค่า - ถ้ามี ตัวอย่างการใช้งาน? อื่น ๆ ที่ฉันหายไป? แนวคิด (เช่นกลยุทธ์การล็อกรายละเอียดที่เกี่ยวข้องกับประสิทธิภาพ) ควรมีการบันทึกไว้ในคู่มืออ้างอิงนี้หรือไม่หรือเป็นเอกสารแยกต่างหาก นี่คือการบริโภคภายนอก เรามีชุดเอกสารทั้งหมดแล้ว (ดู: http://www.rocketsoftware.com/u2/resources/technical-resources ) ทำงานในสิ่งที่เราควรทำแตกต่าง - ฉันมีความคิดอยู่แล้ว แต่เช่นเคยฉันพยายามไม่พึ่งพาความคิดเห็นของฉัน แต่เพียงผู้เดียว ผู้ชม: นักพัฒนาด้านเทคนิคใช้ฐานข้อมูลและเครื่องมือในการผลิตซอฟต์แวร์ในหลายอุตสาหกรรม

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

3
วิธีการหลักควรเป็นเพียงการสร้างวัตถุและการเรียกเมธอดเท่านั้น
เพื่อนของฉันบอกฉันว่าวิธีปฏิบัติที่ดีที่สุดคือคลาสที่มีmainเมธอดควรตั้งชื่อMainและมีmainเมธอดเท่านั้น นอกจากนี้mainวิธีการควรแยกวิเคราะห์อินพุตสร้างวัตถุอื่น ๆ และเรียกวิธีการอื่น ๆ Mainชั้นเรียนและmainวิธีการที่ไม่ควรจะทำอะไรก็ได้ โดยพื้นฐานสิ่งที่เขาพูดว่าคลาสที่มีmainเมธอดควรเป็นดังนี้ public class Main { public static void main(String[] args) { //parse inputs //create other objects //call methods } } มันเป็นวิธีปฏิบัติที่ดีที่สุด?

3
ฉันควรซ้อนฟังก์ชันในภาษาที่อนุญาตให้ทำเช่นนั้นหรือควรหลีกเลี่ยง
ใน JavaScript, PL / SQL และภาษาอื่น ๆ บางฟังก์ชั่นสามารถซ้อนกันเช่นประกาศในฟังก์ชั่นอื่น สิ่งนี้สามารถใช้เพื่อแบ่งฟังก์ชั่นขนาดใหญ่ออกเป็นชิ้นเล็ก ๆ แต่เก็บชิ้นส่วนเหล่านั้นไว้ในบริบทของฟังก์ชั่นที่ใหญ่กว่า function doTooMuch() { function doSomething () { ... } function doSomethingElse() { ... } function doYetAnotherThing() { ... } // doTooMuch body doSomething(); doSomethingElse(); doYetAnotherThing(); } ในบางกรณีเมื่อฟังก์ชั่นขนาดเล็กเหล่านั้นไม่ได้ใช้ตัวแปรท้องถิ่นของฟังก์ชั่นขนาดใหญ่สิ่งนี้สามารถเปลี่ยนเป็นเวอร์ชั่นที่ฟังก์ชั่นทั้งหมดไม่ถูกรบกวนได้ง่าย function doSomething () { ... } function doSomethingElse() { ... } function …

4
วัตถุธุรกิจภายใน Data Access Layer
ดังนั้นฉันจึงสร้าง data access layer ผ่านทาง TDD และได้เข้าหาข้อกังวลเล็กน้อย ฉันไม่ควรเริ่มต้นเส้นทางที่ผิดดังนั้นฉันคิดว่าฉันขอให้พวกคุณดูว่าความคิดของฉันสอดคล้องกับสถาปัตยกรรมที่สะอาดหรือไม่ วิธีการภายใน Data Access Layer ของฉัน (สั้นสำหรับ DAL) จะค่อนข้างง่าย พวกเขาเป็นไปตามขั้นตอนการจัดเก็บในฐานข้อมูล (ไม่มีวิธีอื่นในการโทรเข้าเพื่อรักษาความสะอาด) และพวกเขามีพารามิเตอร์เดียวกันกับที่ทำ พวกเขาเพียงแค่เชื่อมต่อกับฐานข้อมูลและส่งคืนผลลัพธ์แบบสอบถาม นี่คือตัวอย่างหนึ่ง: public int DeleteRecord(int recordId) { recordId.RequireThat("recordId").NotZeroOrLess(); List<SqlParameter> parameters = new List<SqlParameter>(); parameters.Add(new SqlParameter { ParameterName = "@RecordId", SqlDbType = SqlDbType.Int, Direction = ParameterDirection.Input, Value = recordId}); return this.ExecuteNonQuery("DeleteRecord", parameters.ToArray()); …

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