วิธี Parametrize เทียบกับตัวแปรทั่วโลก


10

ฉันมีคำถามง่าย ๆ ที่หลอกหลอนฉันซักพักเมื่อรหัสของฉันเริ่มขึ้น

พารามิเตอร์ควรถูกแทนที่ด้วยตัวแปรโกลบอลเมื่อพวกเขาผ่านเส้นทางยาวของการเรียกฟังก์ชันที่ซ้อนกัน?

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

ให้ฉันอธิบายตัวเอง:

functionA(){
   x = something
   functionB(x)
}
functionB(x){
   functionC(x)
}
functionC(x){
   finallyDoSomethingWithX(x)
}
finallyDoSomethingWithX(x){
  x += 1 //Very dummy example ignoring pass by value, not reference.
}

แทนที่โดย:

globalX;
functionA(){
   globalX = something
   functionB()
}
...
...
...
finallyDoSomethingWithX(){
   globalX += 1
}

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

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

คำแนะนำใด ๆ รูปแบบ? ฉันสามารถเฉพาะเจาะจงมากขึ้นถ้าจำเป็น


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

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

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

@KilianFoth ขอบคุณ คุณช่วยอธิบายเพิ่มเติมด้วยรหัสบางส่วนเพื่อให้ฉันสามารถตรวจสอบคำตอบได้หรือไม่
AFP_555

1
ลองพิจารณาโครงสร้างของรหัส JavaScript ของคุณเช่นเดียวกับในภาษาอื่น ๆ (เช่นภาษาที่ใช้คลาส "ของจริง") ลิงก์ที่มีประโยชน์เกี่ยวกับคำถามที่เกี่ยวข้องนี้ใน SO: stackoverflow.com/questions/927651/…
Ben Cottrell

คำตอบ:


7

อย่าใช้ตัวแปรทั่วโลก

อย่าให้พารามิเตอร์ผ่านกลุ่มของฟังก์ชัน!

มันยากเพราะคุณไม่ได้ใช้ตัวอย่างจริง แต่โดยปกติจะมีวิธีการที่ดีกว่า

ให้บอกว่าเรามีตัวแปรรหัสผ่านที่เราต้องใช้ในการเรียก apis ที่ใช้ inturn โดยฟังก์ชั่นระดับต่ำต่างๆ

วิธีการทั่วโลก (รหัส psudo)

var pass;

function multiply(a,b) {
   return apiMultiply(pass,a,b);
}

วิธีการผ่านพารามิเตอร์

function multiply(a,b,pass) {
    return apiMultiply(pass,a,b);
}

วิธีการวัตถุ

class math {
    var api;
    constructor(pass) {
        api = new api(pass);
    }

    function Multiply(a,b) {
        api.Multiply(a,b); //uses pass from constructor
    }
}

excelent วิธีการส่งผ่านนี้ไม่ได้อยู่ในสภาพแวดล้อมส่วนกลางและไม่ใช่พารามิเตอร์สำหรับฟังก์ชันmúltipleเนื่องจากสามารถนำมาจากแอตทริบิวต์ของวัตถุได้ ขอบคุณ
AFP_555

3

หลีกเลี่ยงการกลมเหมือนกาฬโรค

รหัสใด ๆ สามารถแก้ไขทั่วโลก ดังนั้นถ้าคุณมีลูกโซ่ A (x) -> B (x) -> C (x) -> ... -> Z (x) และคุณเก็บ x ไว้ใน global X และตอนนี้คุณมีลูกโซ่ A- > B-> C -> ...-> Z จากนั้นในทุกขั้นตอนของโซ่ยาวนั้นหรือในรหัสอิสระที่สมบูรณ์ใคร ๆ ก็สามารถเปลี่ยน X ได้และค่าที่ Z ใช้นั้นอาจแตกต่างอย่างสิ้นเชิงจากที่ A เริ่มต้นด้วย

มันเป็นฝันร้ายถ้าคุณต้องการให้แน่ใจว่ารหัสของคุณทำในสิ่งที่ควรทำหรือทำในสิ่งที่คุณคิด


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