เป็นไปได้หรือไม่ที่จะเขียนซอฟต์แวร์ที่ไม่จำเป็นต้องแก้ไขอย่างต่อเนื่อง?


23

ฉันเขียนซอฟต์แวร์เป็นจำนวนมากในหลายภาษาและฉันยังได้เขียนฮาร์ดแวร์สำหรับใช้กับ FPGA โดยใช้ Verilog และ VHDL

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

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

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

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


8
คุณดูเหมือนจะอธิบายOCP
Oded

สิ่งที่หลักการเปิดปิดนี้ดูดี! มีใครใช้สิ่งนี้สำเร็จหรือไม่
นาธานฟาร์ริงตัน

2
@NathanFarrington: รูปแบบการออกแบบส่วนใหญ่ (ตามที่อธิบายโดยGOF ) กำลังติดตาม OCP ตัวอย่างหนึ่งที่จะเป็นแบบแม่แบบวิธี
Spoike

2
@NathanFarrington หลักการ open-closed เป็นหลักการทั่วไปที่นักพัฒนาซอฟต์แวร์ใช้ในการออกแบบซอฟต์แวร์
Jesper

1
ฉันคิดว่าหลาย ๆ โปรแกรมที่เราใช้ในวันนี้ทำโดยใช้บิตและชิ้นส่วนซึ่งเป็นสำเนาของคาร์บอนไปยังโค้ดที่เขียนเมื่อ 20 ปีที่แล้ว
ลโลว์

คำตอบ:


16

อาจจะมีบางอย่างที่เกี่ยวข้องกับอินเตอร์เฟสและการทดสอบที่ดีเช่นฮาร์ดแวร์?

ความคิดของฉัน!

โมดูลที่ออกแบบมาอย่างดีพร้อมอินเทอร์เฟซที่ชัดเจนมักจะสมบูรณ์แบบเป็นหลัก ลองนึกถึงบางสิ่งที่เหมือนStringคลาสของ Java มันเป็นโปรแกรมคอมพิวเตอร์ แต่มันมีอินเตอร์เฟสที่คมชัด ไม่มีข้อบกพร่องที่รู้จักในนั้น มันทำในสิ่งที่ควรจะทำอย่างสมบูรณ์แบบ แน่นอนว่ามันได้รับการทดสอบอย่างกว้างขวางในช่วง 15 ปีที่ผ่านมาและเนื่องจากโปรแกรมทั้งหมดใช้Stringเป็นหน่วยการสร้างพื้นฐานข้อบกพร่องใด ๆ ในนั้นจะสังเกตเห็นได้อย่างรวดเร็ว "นิสัยใจคอ" ใด ๆ - ไม่ใช่ข้อบกพร่องอย่างเคร่งครัด แต่รายละเอียดการออกแบบที่ควรระวัง - เช่นที่อธิบายไว้ที่นี่http://www.jwz.org/doc/java.htmlเป็นที่รู้จักกันดีในตอนนี้ บัญชี.

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

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

อาจไม่มี bullet เงิน แต่เป็นการผสมผสานที่ดีระหว่างแนวปฏิบัติที่ดีที่สุดซึ่งรวมถึง แต่ไม่ จำกัด เพียง:

  • โมดูลที่ง่ายและเป็นอิสระ ในคำอื่น ๆ การมีเพศสัมพันธ์ต่ำและการทำงานร่วมกันสูง
  • การเปลี่ยนไม่ได้ สำคัญอย่างยิ่งกับการเติบโตพร้อมกัน

เป็นที่น่าสังเกตว่าทั้งสองประเด็นมุ่งลดความซับซ้อน นั่นคือประเด็นสำคัญ เอนโทรปีมีแนวโน้มที่จะเพิ่มขึ้นเสมอและหากเราไม่ต่อสู้เราจะจมน้ำตายในความซับซ้อน นอกจากนี้ยังเป็นที่น่าสนใจที่จะเห็นว่าในช่วงไม่กี่ปีที่ผ่านมาภาษาการเขียนโปรแกรมได้รับการพัฒนาไปสู่การส่งเสริมหรือบังคับใช้การปฏิบัติดังกล่าวข้างต้น โดยเฉพาะอย่างยิ่งการเพิ่มขึ้นของฟังก์ชั่นภาษาก็คือฟังก์ชั่นที่บริสุทธิ์ส่งกลับค่าเดียวกันสำหรับการป้อนข้อมูลเดียวกันเสมอไม่มีสถานะในพวกเขา จากนั้นคุณเพียงแค่เขียนฟังก์ชั่นล้วน ๆ ที่รับและส่งคืนค่าที่ไม่เปลี่ยนรูปแบบและ จำกัด การเปลี่ยนแปลงที่หลีกเลี่ยงไม่ได้ไปยังสถานที่เล็ก ๆ ที่กำหนดไว้อย่างดีแทนที่จะกระจายไปทั่ว ลองดูสิ: http://clojure.org/state


1
jwz ไม่เห็นด้วยค่อนข้างมากว่าคลาส String นั้นไม่มีข้อผิดพลาด

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

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

1
@ JoonasPulakka: ใช่ถ้ามีการสรุปหนึ่งบรรทัดของซอฟต์แวร์มันอาจจะเป็น "มีข้อผิดพลาดอื่นอยู่เสมอ" :-) และฉันคิดว่านั่นเป็นหนึ่งในคะแนนของนาธาน
Ross Patterson

1
Joonas คุณชนะ ฉันเริ่มเรียน Clojure ดูเหมือนว่าวิธีที่ดีที่สุดที่จะทำให้การเขียนโปรแกรมสนุกอีกครั้ง
นาธานฟาร์ริงตัน

9

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

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

แน่นอนคุณควรตรวจสอบทดสอบขับเคลื่อนการพัฒนา


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

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

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

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

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

6

ฉันจะแสดงความคิดเห็นในข้อสังเกตของคุณหวังว่าคุณจะได้รับคำตอบจากความคิดเห็นเหล่านี้

หนึ่งในความผิดหวังหลักของฉันกับซอฟต์แวร์คือมันไม่เคย "ทำ"

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

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

แน่นอนการสร้างโมดูลอิสระควรลดการพึ่งพา สิ่งนี้จะต้องได้รับการพิจารณาเมื่อคุณออกแบบซอฟต์แวร์ คุณต้องพิจารณาการแยกข้อกังวลเลเยอร์เทียร์ตัวควบคุมอินเทอร์เฟซ ฯลฯ

"ฉันจะมีความสนุกสนานในการเขียนซอฟต์แวร์มากขึ้นได้อย่างไรโดยไม่แนะนำบั๊กให้เป็นรหัสการทำงาน

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

2 - ทำให้ผู้ใช้ของคุณเข้าใจปรัชญาที่ยาวนานนี้

3- วางแผนการใช้งานอย่างระมัดระวัง

4- การออกแบบก่อนรหัส

5- ใช้การออกแบบทั่วไปตามความเหมาะสม

ต้นแบบการใช้งาน 6 ชิ้นเป็นเครื่องมือยืนยันการออกแบบ


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

4

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

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

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

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

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


ฉันอยากรู้อยากเห็นคุณเขียนว่าการทดสอบมีความสำคัญ แต่ก็ทำให้มึนงง
นาธานฟาร์ริงตัน

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

3

หนึ่งในความผิดหวังหลักของฉันกับซอฟต์แวร์คือมันไม่เคย "ทำ" มีคุณสมบัติเพิ่มอยู่เสมอ

ถ้านั่นทำให้คุณหงุดหงิดลองพิจารณาอาชีพอื่นดู อย่างจริงจัง.

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

บ่อยครั้งเมื่อเพิ่มคุณสมบัติมันจะแนะนำบั๊กที่อื่นซึ่งใช้งานได้ดีมาก่อน

นั่นเป็นปัญหาคุณภาพ

สิ่งนี้ไม่ได้เกิดขึ้นในฮาร์ดแวร์ตราบใดที่อินเทอร์เฟซไม่ได้ถูกละเมิด

นั่นก็เป็นความจริงในซอฟต์แวร์

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

ใช่. คุณต้องฝึกการประกันคุณภาพจริง ๆ


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

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

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

@NathanFarrington: ซอฟต์แวร์ทัวริงคิดค้นเพื่อทำลายรหัสปริศนาที่เปลี่ยนแปลงตลอดเวลา "โดยการประกันคุณภาพคุณหมายถึงการทดสอบ" เท็จ ฉันหมายถึงการประกันคุณภาพ - ทุกแง่มุมของการพัฒนาควรมีมาตรฐานคุณภาพที่ควรได้รับ การทดสอบเป็นวิธีหนึ่ง (จำกัด ) ในการประเมินคุณภาพของสิ่งประดิษฐ์ชนิดหนึ่ง "รหัสมีการเปลี่ยนแปลง ... ซึ่งสามารถแนะนำข้อบกพร่อง" แก้ไข. นั่นคือความล้มเหลวของการประกันคุณภาพ - ไม่ใช่คุณสมบัติโดยธรรมชาติของซอฟต์แวร์
S.Lott

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

2

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

ฉันขอแนะนำให้คุณดูใน " วิธีการที่เป็นทางการ " เพื่อตรวจสอบความถูกต้องของการออกแบบและซอฟต์แวร์ เครื่องมือจำลองที่คุณใช้สำหรับการออกแบบฮาร์ดแวร์กำลังพยายามปิดบางสิ่งบางอย่าง ฉันไม่เชื่อว่าเครื่องมือสำหรับวิธีการที่เป็นทางการอยู่ใกล้กับการเป็นประโยชน์ในอุตสาหกรรมในเวลานี้และอุตสาหกรรมเดียวที่มีแรงจูงใจที่แข็งแกร่งที่จะปราศจากข้อบกพร่องคือavionicsและยา (น่าสนใจพอ FDA ระบุชัดเจนว่า "ซอฟต์แวร์นั้นแตกต่างกัน จากฮาร์ดแวร์ "ในลิงค์นั้น) นอกจากนี้หากคุณกำลังพัฒนาด้วย Verilog / VHDL แสดงว่าคุณกำลังติดอยู่กับตรรกะแบบไบนารี สิ่งนี้ช่วยลดความซับซ้อนลงอย่างมาก จะไม่มีฮาร์ดแวร์ที่เทียบเท่ากับปัญหา Y2K

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


1

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

ในโลกของซอฟต์แวร์เราเรียกมันว่า "module" a library และเราใช้มันในแบบเดียวกัน ห้องสมุดหลายแห่งถูกสร้างขึ้นจนถึงจุดที่พวกเขาทำงานได้ดีจากนั้นนั่งทำงานอย่างพอใจโดยไม่มีการเปลี่ยนแปลงจนกว่าสิ่งสำคัญจะนำไปสู่การแก้ไขครั้งต่อไป คิดว่าพวกเขาเป็นซอฟต์แวร์ที่ถูกกระถางด้วยอีพ็อกซี่ :-)

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

hogwash บางทีคุณอาจเป็นคนที่ดีกว่าคนอื่น ๆ ที่ไม่ใช่คนเหล็ก "บัดกรี" ฮาร์ดแวร์ แต่ฉันเคยเห็นการออกแบบวงจรที่ไม่ดีจำนวนมากชิปที่ล้มเหลว ( เช่นปัญหา "f00f" ที่มีชื่อเสียงของ Intel) แต่นั่นก็ไม่ได้ พูดกับฟิลด์โดยรวม และเมื่อเครื่อง faux-hard กลายเป็น "เบาลง" ปัญหาก็ยากที่จะป้องกันได้

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

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

ประเด็นสุดท้ายที่หนึ่ง: ซอฟต์แวร์มีรูปแบบทางการเงินที่แตกต่างจากฮาร์ดแวร์แม้กระทั่งฮาร์ดแวร์ที่ตั้งโปรแกรมไว้ ซอฟต์แวร์ที่ไม่ใช่ของผู้บริโภคส่วนใหญ่และซอฟต์แวร์สำหรับผู้บริโภคบางส่วนก็มีการจำหน่ายในลักษณะที่สนับสนุนการเปลี่ยนแปลง เมื่อคุณสามารถบอกธุรกิจได้ว่า "จ่ายเงินให้เรา $ 10,000 ตอนนี้บวก 18% ต่อปี" คุณสามารถขายผลิตภัณฑ์ได้ทุก ๆ สองสามปี แต่เพื่อพิสูจน์ความถูกต้องของค่าธรรมเนียมคุณต้องให้การเปลี่ยนแปลงที่ลูกค้าต้องการ อืม ... คิดถึงเส้นโค้งความล้าสมัยของฮาร์ดแวร์ของ Apple บางทีนี่อาจไม่ใช่ความแตกต่างเลย - ฮาร์ดแวร์แค่ทำให้คุณซื้อใหม่จริงๆ !


ไม่เคยพูดว่าฉันดีกว่าใคร ;-) เมื่อฮาร์ดแวร์มีข้อผิดพลาดมันจะกลายเป็นข่าว เมื่อซอฟต์แวร์มีข้อผิดพลาด ummm รอซอฟต์แวร์อยู่เสมอมีข้อบกพร่อง วิธีการใดที่เราไม่ได้ใช้เพราะราคาแพงเกินไปและไม่สนุก
นาธานฟาร์ริงตัน

0

ฉันจะมีซอฟต์แวร์การเขียนที่สนุกสนานได้มากขึ้นได้อย่างไรโดยไม่แนะนำบั๊กให้เป็นรหัสการทำงานและก้าวหน้าไปข้างหน้าอยู่เสมอ

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

http://en.wikipedia.org/wiki/Extreme_Programming

เมื่อคุณโต้ตอบกับฮาร์ดแวร์ฮาร์ดแวร์ต้องการค่า x และนั่นคือทั้งหมด (ในทางทฤษฎี) แต่เมื่อคุณมีปฏิสัมพันธ์กับผู้คนในวันนี้พวกเขาต้องการ x และในวันพรุ่งนี้พวกเขาต้องการ y และอื่น ๆ มันเป็นวิธีการเปลี่ยนแปลง bussines และความต้องการของผู้คน . เพราะ Persons! = machines ดังนั้นโค้ดที่ไม่เคยเปลี่ยนส่วนใหญ่จะเป็นไปไม่ได้

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


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

อย่างที่ฉันพูดเสมอว่ารหัสที่ดีที่สุดคือไม่มีรหัส :-)
H27studio

0

เป็นไปได้ไหมที่จะเขียนซอฟต์แวร์ด้วยวิธีเดียวกัน

ใช่แล้ว. ระวังให้ดีราวกับว่าคุณกำลังพัฒนาฮาร์ดแวร์ทดสอบทุกสิ่งที่คุณทำได้และซอฟต์แวร์ของคุณจะมีคุณภาพใกล้เคียงกัน

ยังไงก็ตามคุณยังไม่เคยได้ยินเรื่องของ HW มีข้อผิดพลาด SW มากและแก้ไขได้ยากกว่า (ไม่ใช่แค่อัพเกรดซอฟต์แวร์)


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

1
@NathanFarrington ซอฟต์แวร์มักจะซับซ้อนกว่า HW HW ได้รับการทดสอบอย่างละเอียดมากขึ้น SW สามารถเปลี่ยนแปลงได้ง่ายขึ้นดังนั้นผู้คนมักจะไม่ให้ความสนใจมากนัก
BЈовић

0

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

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


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

-1

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

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