init () มีวิธีการดมกลิ่นของรหัสหรือไม่?


20

มีวัตถุประสงค์ในการประกาศinit()วิธีการสำหรับประเภทใด ๆ ?

ฉันไม่ได้ถามว่าเราควรจะต้องการinit()มากกว่านวกรรมิกหรือวิธีการหลีกเลี่ยงการประกาศinit()

ฉันถามว่ามีเหตุผลใด ๆ ที่อยู่เบื้องหลังการประกาศinit()วิธีการ (ดูว่ามันเป็นเรื่องธรรมดา) หรือไม่ถ้ามันเป็นกลิ่นรหัสและควรหลีกเลี่ยง


init()สำนวนเป็นเรื่องธรรมดามาก แต่ผมยังไม่เห็นประโยชน์ที่แท้จริงใด ๆ

ฉันกำลังพูดถึงประเภทที่สนับสนุนการเริ่มต้นด้วยวิธีการ:

class Demo {
    public void init() {
        //...
    }
}

สิ่งนี้จะใช้ในรหัสการผลิตเมื่อใด


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

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


1
ถึง "... เห็นว่ามันเป็นเรื่องธรรมดา ... ": มันเป็นเรื่องธรรมดาไหม คุณยกตัวอย่างได้บ้าง บางทีคุณกำลังจัดการกับกรอบที่ต้องแยกการเริ่มต้นและการก่อสร้าง
จาก

เป็นวิธีการที่พบในชั้นฐานหรือชั้นที่ได้รับหรือทั้งสองอย่าง? (หรือ: เป็นวิธีการที่พบในชั้นเรียนที่เป็นของลำดับชั้นการสืบทอดหรือไม่ชั้นฐานเรียกinit()ในระดับที่ได้รับหรือในทางกลับกัน?) ถ้าเป็นเช่นนั้นมันเป็นตัวอย่างของการปล่อยให้ชั้นฐานดำเนินการ "post-constructor "ซึ่งสามารถดำเนินการได้หลังจากคลาสที่ได้รับมาส่วนใหญ่เสร็จสิ้นการก่อสร้างแล้ว มันเป็นตัวอย่างของการเริ่มต้นหลายเฟส
rwong

หากคุณไม่ต้องการกำหนดค่าเริ่มต้นที่จุดอินสแตนซ์คุณควรแยกทั้งสองอย่างออกก่อน
JᴀʏMᴇᴇ

คุณอาจจะสนใจ is-a-start-run-or-execute-method-a-good-practice
Laiv

คำตอบ:


39

ใช่มันเป็นกลิ่นรหัส กลิ่นรหัสไม่ใช่สิ่งที่จำเป็นต้องลบออกเสมอ มันเป็นสิ่งที่ทำให้คุณดูเป็นครั้งที่สอง

ที่นี่คุณมีวัตถุในสองสถานะที่แตกต่างกันโดยพื้นฐาน: pre-init และ post-init รัฐเหล่านั้นมีความรับผิดชอบแตกต่างกันวิธีการต่าง ๆ ที่ได้รับอนุญาตให้เรียกใช้และพฤติกรรมที่แตกต่างกัน มันมีประสิทธิภาพสองคลาสที่แตกต่างกัน

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

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


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

1
นี่คือคำตอบที่ดีที่สุด สิ่งหนึ่งที่ทำให้ฉันเป็นโรคจิต: " รัฐเหล่านั้นมีความรับผิดชอบแตกต่างกันวิธีการต่าง ๆ ที่ได้รับอนุญาตให้เรียกและพฤติกรรมที่แตกต่าง " - การไม่แยกความรับผิดชอบเหล่านี้เป็นการละเมิด SRP หากวัตถุประสงค์ของซอฟต์แวร์คือการจำลองสถานการณ์จริงในทุกด้านสิ่งนี้จะสมเหตุสมผล แต่ในการผลิต devs ส่วนใหญ่เขียนโค้ดที่ส่งเสริมการจัดการที่ง่ายแก้ไขโมเดลถ้าจำเป็นเพื่อให้เหมาะกับสภาพแวดล้อมที่ใช้ซอฟต์แวร์ (ต่อความคิดเห็นถัดไป)
Vince Emigh

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

14

มันขึ้นอยู่กับ.

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

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

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


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

@VinceEmigh: ok มันเป็นตัวอย่างแรกที่ฉันสามารถหาที่นี่ใน platfform SE อาจจะไม่ดีที่สุด แต่มีอยู่กรณีการใช้งานที่ถูกต้องสำหรับแยกinitวิธี อย่างไรก็ตามเมื่อใดก็ตามที่คุณเห็นวิธีการดังกล่าวอย่าลังเลที่จะถามถึงความจำเป็นของมัน
Doc Brown

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

1
@VinceEmigh: เมื่อคุณไม่สามารถนึกถึงสถานการณ์ดังกล่าวได้คุณต้องใช้จินตนาการของคุณ ;-) หรืออ่านคำตอบของฉันอีกครั้งอย่าลดเพียงแค่ "การจัดสรร" หรือทำงานกับเฟรมเวิร์กเพิ่มเติมจากผู้จำหน่ายที่แตกต่างกัน
Doc Brown

1
@DocBrown การใช้จินตนาการมากกว่าการฝึกฝนที่พิสูจน์แล้วนำไปสู่โค้ดบางอย่างที่ขี้ขลาดเช่นการเริ่มต้นวงเล็บปีกกาสองครั้ง: ฉลาด แต่ไม่มีประสิทธิภาพและควรหลีกเลี่ยง ฉันรู้ว่าผู้ขายใช้มัน แต่นั่นไม่ได้หมายความว่าการใช้นั้นถูกต้อง หากคุณรู้สึกว่ามันเป็นโปรดแจ้งให้เราทราบว่าทำไมเป็นเพราะสิ่งที่ฉันได้พยายามที่จะคิดออก ดูเหมือนว่าคุณจะตายไปแล้วโดยมีวัตถุประสงค์เพื่อประโยชน์บางอย่าง แต่ดูเหมือนว่าคุณกำลังมีช่วงเวลาที่ยากลำบากในการยกตัวอย่างที่สนับสนุนการออกแบบที่ดี ฉันรู้ภายใต้สถานการณ์ที่สามารถใช้งานได้ แต่ควรใช้หรือไม่
Vince Emigh

5

ประสบการณ์ของฉันแบ่งออกเป็นสองกลุ่ม:

  1. รหัสที่ต้องการ init () จริง ๆ สิ่งนี้สามารถเกิดขึ้นได้เมื่อซูเปอร์คลาสหรือเฟรมเวิร์กป้องกันไม่ให้คอนสตรัคเตอร์ของคลาสของคุณได้รับการอ้างอิงทั้งหมดระหว่างการก่อสร้าง
  2. รหัสที่ใช้ init () แต่สามารถหลีกเลี่ยงได้

จากประสบการณ์ส่วนตัวของฉันฉันได้เห็นอินสแตนซ์เพียงไม่กี่รายการของ (1) แต่อินสแตนซ์อื่น ๆ อีกมากมายของ (2) ดังนั้นฉันมักจะถือว่า init () เป็น code-ดมกลิ่น แต่ก็ไม่ได้เป็นเช่นนั้นเสมอไป บางครั้งคุณก็ไม่สามารถหลีกเลี่ยงได้

ฉันพบว่าการใช้รูปแบบของตัวสร้างมักจะช่วยลบความต้องการ / ความปรารถนาที่จะมี init ()


1
ถ้าซูเปอร์คลาสหรือเฟรมเวิร์กไม่อนุญาตให้มีประเภทที่จะได้รับการอ้างอิงที่ต้องการผ่านตัวสร้างวิธีการเพิ่มinit()วิธีการแก้ปัญหาได้อย่างไร init()วิธีการอย่างใดอย่างหนึ่งจะต้องพารามิเตอร์ที่จะยอมรับการอ้างอิงหรือคุณต้องการมีการยกตัวอย่างการอ้างอิงภายในinit()วิธีการที่คุณยังสามารถทำกับผู้สร้าง คุณยกตัวอย่างได้ไหม
Vince Emigh

1
@VinceEmigh: init () บางครั้งสามารถใช้เพื่อโหลดไฟล์กำหนดค่าจากแหล่งภายนอกเปิดการเชื่อมต่อฐานข้อมูลหรือสิ่งที่ ILK นั้น กระบวนการ DoFn.initialize () วิธี (จากเฟรมเวิร์ก apache Crunch) ถูกใช้ในลักษณะนี้ นอกจากนี้ยังสามารถใช้เพื่อโหลดฟิลด์ภายในที่ไม่สามารถทำให้เป็นอนุกรมได้ (DoFns ต้องเป็นแบบอนุกรม) ปัญหาสองข้อในที่นี้คือ (1) บางสิ่งจำเป็นเพื่อให้แน่ใจว่ามีการเรียกใช้วิธีการเริ่มต้นและ (2) วัตถุต้องรู้ว่ามันจะได้รับจากแหล่งไหน
อีวาน

1

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

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


หากการปรับปรุงการกำหนดค่าและนี้ต้องวัตถุที่จะรีเซ็ต / เปลี่ยนของรัฐตามการกำหนดค่าที่คุณไม่คิดว่ามันจะดีกว่าที่จะมีการกระทำที่วัตถุในฐานะที่เป็นผู้สังเกตการณ์ต่อConfig?
Vince Emigh

@Vince Emigh ไม่ใช่คนที่สมควรได้รับ ผู้สังเกตการณ์จะทำงานถ้าฉันรู้ว่าช่วงเวลาที่แน่นอนเมื่อมีการเปลี่ยนแปลงการกำหนดค่า อย่างไรก็ตามหากข้อมูลการกำหนดค่าถูกเก็บไว้ในไฟล์ที่สามารถเปลี่ยนแปลงได้นอกแอพพลิเคชั่นก็จะไม่มีวิธีการที่ซับซ้อน ตัวอย่างเช่นถ้าฉันมีโปรแกรมที่แยกวิเคราะห์ไฟล์และแปลงข้อมูลเป็นแบบจำลองภายในบางส่วนและไฟล์ config แยกต่างหากมีค่าเริ่มต้นสำหรับข้อมูลที่ขาดหายไปถ้าฉันเปลี่ยนค่าเริ่มต้นฉันจะอ่านอีกครั้งเมื่อฉันเรียกใช้ครั้งต่อไป การแยกวิเคราะห์ มีวิธี Init ในแอปพลิเคชันของฉันจะค่อนข้างมีประโยชน์ในกรณีนั้น
Vladimir Stokic

หากไฟล์ config มีการแก้ไขภายนอกที่รันไทม์มีวิธีการโหลดตัวแปรเหล่านั้นโดยไม่ต้องไม่มีบางชนิดของการแจ้งเตือนแจ้งแอพลิเคชันของคุณที่จะต้องมีการเรียก init ( update/ reloadอาจจะอธิบายเพิ่มเติมสำหรับชนิดของพฤติกรรมนี้) ที่จริงการลงทะเบียนการเปลี่ยนแปลงเหล่านั้น . ในกรณีดังกล่าวการแจ้งเตือนนั้นจะทำให้ค่าของการเปลี่ยนแปลงในแอปพลิเคชันของคุณภายในซึ่งฉันเชื่อว่าสามารถสังเกตได้โดยให้สังเกตได้จากการกำหนดค่าของคุณโดยแจ้งให้ผู้สังเกตการณ์ทราบเมื่อมีการบอกให้เปลี่ยนค่าหนึ่ง หรือฉันเข้าใจผิดตัวอย่างของคุณ?
Vince Emigh

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

1

ขึ้นอยู่กับว่าคุณใช้มันอย่างไร

ฉันใช้รูปแบบนั้นในภาษาที่รวบรวมขยะเช่น Java / C # เมื่อฉันไม่ต้องการจัดสรรวัตถุบนฮีปอีกครั้ง (เช่นเมื่อฉันสร้างวิดีโอเกมและต้องรักษาประสิทธิภาพให้สูงนักสะสมขยะจะฆ่าประสิทธิภาพ) ฉันใช้นวกรรมิกเพื่อทำการจัดสรรฮีปอื่น ๆ ตามที่ต้องการและinitเพื่อสร้างสถานะที่มีประโยชน์ขั้นพื้นฐานก่อนทุกครั้งที่ฉันต้องการนำมาใช้ซ้ำ สิ่งนี้เกี่ยวข้องกับแนวคิดของออบเจ็กต์พูล

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

โดยทั่วไปแล้วมันเป็นกลิ่นรหัส


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

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

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

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

1

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

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

นอกเหนือจากกรณีดังกล่าวฉันคิดว่าทุกอย่างควรเป็นตัวสร้าง


หากประเภทนั้นต้องการการเชื่อมต่อคุณควรใช้ DI หากมีปัญหาในการสร้างการเชื่อมต่อคุณไม่ควรสร้างวัตถุที่ต้องการ ถ้าคุณผลักการสร้างการเชื่อมต่อภายในคลาสคุณจะสร้างวัตถุวัตถุนั้นจะยกตัวอย่างการพึ่งพา (การเชื่อมต่อ) หากการสร้างอินสแตนซ์ของการพึ่งพาล้มเหลวคุณจะปิดท้ายด้วยวัตถุที่คุณไม่สามารถใช้งานได้ซึ่งเป็นการสิ้นเปลืองทรัพยากร
Vince Emigh

ไม่จำเป็น. คุณจะพบวัตถุที่ไม่สามารถใช้งานได้ชั่วคราว ในกรณีเช่นนี้วัตถุอาจทำหน้าที่เป็นคิวหรือพร็อกซีจนกว่าทรัพยากรจะพร้อมใช้งาน initวิธีการประณามอย่างสิ้นเชิงนั้นเป็นการ จำกัด IMHO
tofro

0

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

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


0

ไม่มีกลิ่นรหัสหาก init () - วิธีการฝังอยู่ในความหมายของวงจรชีวิตของวัตถุ

หากคุณจำเป็นต้องเรียกใช้ init () เพื่อทำให้วัตถุอยู่ในสถานะที่สอดคล้องกันมันเป็นกลิ่นรหัส

มีเหตุผลทางเทคนิคหลายประการที่มีโครงสร้างดังกล่าวอยู่:

  1. เบ็ดกรอบ
  2. รีเซ็ตวัตถุเป็นสถานะเริ่มต้น (หลีกเลี่ยงความซ้ำซ้อน)
  3. ความเป็นไปได้ที่จะแทนที่ในระหว่างการทดสอบ

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

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

-4

บางครั้งชื่อ init อาจทึบแสง มาขับรถและเครื่องยนต์กันเถอะ ในการสตาร์ทรถยนต์ (เปิดเครื่องเพียงเพื่อฟังวิทยุ) คุณต้องการตรวจสอบว่าทุกระบบพร้อมใช้งานแล้ว

ดังนั้นคุณสร้างเครื่องยนต์ประตูล้อ ฯลฯ หน้าจอของคุณแสดง engine = off

ไม่จำเป็นต้องเริ่มตรวจสอบเครื่องยนต์ ฯลฯ เนื่องจากทั้งหมดมีราคาแพง จากนั้นเมื่อคุณหมุนกุญแจเพื่อจุดไฟคุณจะโทรหา engine-> start มันเริ่มต้นทำงานกระบวนการที่มีราคาแพงทั้งหมด

ตอนนี้คุณเห็น engine = on และกระบวนการในการจุดระเบิดจะเริ่มขึ้น

รถจะไม่เปิดเครื่องหากไม่มีเครื่องยนต์

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

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