ผ่านตัวแปรสมาชิกเป็นพารามิเตอร์วิธี


33

ในโครงการฉันพบรหัสเช่นนี้:

class SomeClass
{
    private SomeType _someField;

    public SomeType SomeField
    {
        get { return _someField; }
        set { _someField = value; }
    }

    protected virtual void SomeMethod(/*...., */SomeType someVar)
    {
    }

    private void SomeAnotherMethod()
    {
        //.............
        SomeMethod(_someField);
        //.............
    }

};

ฉันจะโน้มน้าวให้เพื่อนร่วมทีมของฉันว่านี่เป็นรหัสไม่ดีได้อย่างไร

ฉันเชื่อว่านี่เป็นภาวะแทรกซ้อนที่ไม่จำเป็น ส่งผ่านตัวแปรสมาชิกเป็นพารามิเตอร์เมธอดทำไมถ้าคุณสามารถเข้าถึงมันได้? นี่ก็เป็นการละเมิด encapsulation

คุณเห็นปัญหาอื่น ๆ ของรหัสนี้หรือไม่?


21
อะไรทำให้คุณคิดว่ามันแย่
yannis

@ Yanis Rizos คุณคิดว่าดีหรือไม่? อย่างน้อยนี่เป็นภาวะแทรกซ้อนที่ไม่จำเป็น ทำไมผ่านตัวแปรเป็นพารามิเตอร์วิธีการถ้าคุณมีการเข้าถึงแล้ว? นี่คือการละเมิด encapsulation เช่นกัน
tika

2
คะแนนที่ถูกต้องโปรดแก้ไขคำถามเพื่อรวมไว้ เราไม่สามารถช่วยให้คุณโน้มน้าวเพื่อนร่วมทีมของคุณได้ แต่เราสามารถช่วยคุณประเมินรหัสนั่นคือคำถามที่คุณควรถาม
yannis

8
ฉันอยากจะมีวิธีการที่สามารถสรุปตัวแปรที่แตกต่างจากวิธีที่ทำค่าคงที่ 2 + 2 พารามิเตอร์ในวิธีการนั้นสามารถนำมาใช้ซ้ำได้
Dante

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

คำตอบ:


3

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

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

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

สำหรับกระสุนมากขึ้นและมีความคิดที่ผมจะขอแนะนำให้ยกขึ้นสำเนาของลุงบ๊อบรหัสสะอาด


ลดลงหลังจากได้เห็นอิทธิพลของหนังสืออ้างอิง
Frank Hileman

แม้ว่าส่วนเล็ก ๆ ของฉันจะเศร้ามากที่ 5 ปีหลังจากที่เขียนคำตอบคุณเอาแค่ 2 จุดอินเทอร์เน็ตจากฉันมีอีกส่วนเล็ก ๆ ของฉันที่อยากรู้อยากเห็นถ้าคุณสามารถให้การอ้างอิงบางอย่างที่จะบ่งบอกถึงของ อิทธิพลที่หนังสือที่ฉันอ้างถึงมี นั่นจะดูเป็นธรรมและคุ้มค่ากับคะแนนเหล่านั้น
DXM

การอ้างอิงคือตัวฉันเองการเห็นอิทธิพลของผู้พัฒนารายอื่นเป็นการส่วนตัว แรงจูงใจทั้งหมดที่อยู่เบื้องหลังหนังสือดังกล่าวเป็นสิ่งที่ดีอย่างไรก็ตามโดยระบุว่ารหัสทั้งหมดจะต้องเป็นไปตามแนวทางที่ไม่ได้มาตรฐาน (เช่นแนวทางที่ให้บริการตามวัตถุประสงค์จริง) หนังสือดังกล่าวดูเหมือนจะก่อให้เกิดการสูญเสียการคิดเชิงวิพากษ์ .
Frank Hileman

เกี่ยวกับความท้าทายในการประมวลผลของสมองให้พิจารณาแนวคิดของภาระการรับรู้
jxramos

30

ฉันสามารถนึกถึงเหตุผลในการส่งผ่านเขตข้อมูลสมาชิกเป็นพารามิเตอร์ในวิธี (ส่วนตัว): มันทำให้ชัดเจนว่าวิธีการของคุณขึ้นอยู่กับ

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

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


2
สิ่งที่จะเป็นที่พึ่งพึ่งพาที่เหลือ? ฉันสันนิษฐานจากตัวอย่างของคุณว่า_someFieldเป็นพารามิเตอร์เดียวที่จำเป็นในการคำนวณผลลัพธ์และเราเพิ่งทำอย่างชัดเจน (หมายเหตุ: นี่เป็นสิ่งสำคัญเราไม่ได้เพิ่มการพึ่งพาเราทำให้ชัดเจนเท่านั้น!)
Andres F.

11
-1 หากไม่มีการพึ่งพาสมาชิกอินสแตนซ์โดยปริยายควรเป็นสมาชิกแบบสแตติกที่รับค่าเป็นพารามิเตอร์ ในตัวอย่างนี้แม้ว่าคุณจะมีเหตุผล แต่ฉันไม่คิดว่ามันเป็นเหตุผลที่ถูกต้อง มันเป็นรหัสที่ไม่ดี
Steven Evers

2
@SnOrfus จริง ๆ แล้วฉันแนะนำ refactoring วิธีการทั้งหมดออกจากคลาส
Andres F.

5
+1 สำหรับ "... มันไม่ชัดเจนหรือที่จะทำให้การพึ่งพานี้ชัดเจน?" abso-เลว-loutely ใครที่นี่จะพูดว่า "ตัวแปรทั่วโลกดีตามกฎทั่วไป"? นั่นคือ COBOL-68 ได้ยินฉันตอนนี้และเชื่อฉันในภายหลัง ในโค้ดที่ไม่น่าสนใจของเราในบางครั้งฉันจะปรับโครงสร้างเพื่อถ่ายทอดอย่างชัดเจนโดยใช้ตัวแปรระดับโลก เราขันสุนัขในหลาย ๆ กรณีโดย) การใช้ back-n-out โดยพลการของสนามส่วนตัวและมันเป็นสมบัติสาธารณะ b) ทำให้งงงวยการเปลี่ยนแปลงของเขตข้อมูลโดย "ซ่อนการพึ่งพา" ทีนี้ทวีคูณสิ่งนี้ด้วยโซ่การรับรู้ลึก ๆ 3-5 อัน
Radarbob

2
@Tarion ฉันไม่เห็นด้วยกับลุง Bob เกี่ยวกับเรื่องนี้ เมื่อใดก็ตามที่เป็นไปได้วิธีการควรจะมีฟังก์ชั่นเหมือนและขึ้นอยู่กับการอ้างอิงที่ชัดเจนเท่านั้น (เมื่อเรียกวิธีสาธารณะใน OOP หนึ่งในการพึ่งพาเหล่านี้คือthis(หรือself) แต่มันทำให้ชัดเจนโดยการเรียกตัวเองobj.method(x)) การพึ่งพาโดยนัยอื่น ๆ คือสถานะของวัตถุ ซึ่งมักจะทำให้เข้าใจรหัสยากขึ้น เมื่อใดก็ตามที่เป็นไปได้ - และภายในเหตุผล - ทำการอ้างอิงอย่างชัดเจน & ฟังก์ชั่นสไตล์ ในกรณีของวิธีการส่วนตัวถ้าเป็นไปได้ส่งผ่านทุกพารามิเตอร์ที่พวกเขาต้องการอย่างชัดเจน และใช่มันช่วยในการปรับโครงสร้างพวกมันอีกครั้ง
Andres F.

28

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

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

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


5
คำตอบ Supurb แม้จะมีแนวคิดที่ดี แต่หลาย ๆ คลาสในซอฟท์แวร์ในปัจจุบันมีขนาดใหญ่และน่าเกลียดกว่าโปรแกรมทั้งหมดเมื่อเฟส "Globals is Evil" ประกาศเกียรติคุณ ตัวแปรคลาสคือตามวัตถุประสงค์ทั้งหมดที่ใช้งานได้จริงจะอยู่ในขอบเขตของอินสแตนซ์ของคลาส การมีงานจำนวนมากที่ทำในฟังก์ชั่นล้วน ๆ ทำให้ได้รหัสที่สามารถทดสอบได้และมีประสิทธิภาพมากขึ้น
mattnz

@mattnz มีวิธีใดที่คุณสามารถเชื่อมโยงไปยังบรรณานุกรมของ Hwat หรือหนังสือของเขาเกี่ยวกับการเขียนโปรแกรมในอุดมคติ? ฉันขัดถูอินเทอร์เน็ตและไม่พบสิ่งใดบนเขา Google พยายามแก้ไขอัตโนมัติเพื่อ "อะไร"
Buttle Butkus

8

หากฟังก์ชั่นนี้ถูกเรียกว่าหลาย ๆ ครั้งบางครั้งก็ผ่านตัวแปรสมาชิกนั้นและบางครั้งก็ผ่านอย่างอื่นก็ไม่เป็นไร ตัวอย่างเช่นฉันจะไม่พิจารณาสิ่งที่ไม่ดีเลย:

if ( CalculateCharges(newStartDate) > CalculateCharges(m_StartDate) )
{
     //handle increase in charges
}

โดยที่newStartDateคือตัวแปรโลคัลและm_StartDateเป็นตัวแปรสมาชิก

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


3
ไม่สำคัญว่าวิธีการนั้นถูกเรียกด้วยพารามิเตอร์อื่นนอกเหนือจากตัวแปรสมาชิก สิ่งที่สำคัญคือมันอาจเรียกได้ว่าเป็นอย่างนั้น คุณไม่เคยรู้วิธีที่จะเรียกวิธีในที่สุดเมื่อคุณสร้างมัน
Caleb

บางทีคุณควรแทนที่เงื่อนไข "if" ด้วย "needHandleIncreaseChages (newStartDate)" และอาร์กิวเมนต์ของคุณจะไม่มีอีกต่อไป
Tarion

2

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


สิ่งที่คุณหายไปก็คือตัวแปรสมาชิกส่วนตัวนี้มี accessors สาธารณะ
tika

ดังนั้นคุณกำลังบอกว่าวิธีเสมือนจริงที่ได้รับการป้องกันควรขึ้นอยู่กับ accessor สาธารณะของตัวแปรส่วนตัวหรือไม่? และคุณมีปัญหากับรหัสปัจจุบันหรือไม่?
Michael Brown

accessors สาธารณะถูกสร้างขึ้นเพื่อใช้งาน ระยะเวลา
tika

1

โดยทั่วไปเฟรมเวิร์ก GUI จะมีคลาส 'มุมมอง' ที่แสดงสิ่งที่วาดบนหน้าจอและคลาสนั้นมักจะมีวิธีการที่invalidateRect(Rect r)จะทำเครื่องหมายส่วนหนึ่งของพื้นที่วาดรูปตามที่จำเป็นต้องวาดใหม่ ลูกค้าอาจเรียกวิธีการนั้นเพื่อร้องขอการอัพเดทเป็นส่วนหนึ่งของมุมมอง แต่มุมมองอาจเรียกวิธีการของตัวเองเช่น:

invalidateRect(m_frame);

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

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

invalidateFrame();

แต่ทำไมต้องเพิ่มวิธีพิเศษเฉพาะเมื่อคุณสามารถใช้งานทั่วไปได้มากกว่าinvalidateRect()นี้ หรือถ้าคุณเลือกที่จะให้invalidateFrame()คุณอาจนำไปใช้ในแง่ของทั่วไปมากขึ้นinvalidateRect():

View::invalidateFrame(void)
{
    invalidateRect(m_frame)
}

ทำไมผ่านตัวแปรเป็นพารามิเตอร์วิธีการถ้าคุณมีการเข้าถึงแล้ว?

คุณควรส่งตัวแปรอินสแตนซ์เป็นพารามิเตอร์ไปยังวิธีการของคุณเองหากวิธีนี้ไม่ได้ทำงานเฉพาะกับตัวแปรอินสแตนซ์นั้น ในตัวอย่างด้านบนกรอบของมุมมองเป็นเพียงสี่เหลี่ยมผืนผ้าอื่นเท่าที่invalidateRect()เกี่ยวข้องกับวิธีการ


1

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

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

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


1

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

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

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


1

บางสิ่งที่มาหาฉันเมื่อคิดถึงสิ่งนี้:

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

0

คุณหายไปหากพารามิเตอร์ ("อาร์กิวเมนต์") เป็นการอ้างอิงหรืออ่านอย่างเดียว

class SomeClass
{
    protected SomeType _someField;
    public SomeType SomeField
    {
        get { return _someField; }

        set {
          if (doSomeValidation(value))
          {
            _someField = value;
          }
        }
    }

    protected virtual void ModifyMethod(/*...., */ ref SomeType someVar)
    { 
      // ...
    }    

    protected virtual void ReadMethod(/*...., */ SomeType someVar)
    { 
      // ...
    }

    private void SomeAnotherMethod()
    {
        //.............

        // not recommended, but, may be required in some cases
        ModifyMethod(ref this._someField);

        //.............

        // recommended, but, verbose
        SomeType SomeVar = this.someField;
        ModifyMethod(ref SomeVar);
        this.someField = SomeVar;

        //.............

        ReadMethod(this.someField);
        //.............
    }

};

นักพัฒนาหลายคนมักจะกำหนดเขตข้อมูลภายในของตัวแปรโดยตรงในวิธีการสร้าง มีข้อยกเว้นบางประการ

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

หมายเหตุ: ฉันขอแนะนำให้รักษาเขตข้อมูลคุณสมบัติเป็น "ป้องกัน"

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