ซิงเกิลตันที่ไม่เปลี่ยนรูป / ไร้สัญชาตินั้นแย่หรือไม่?


12

เมื่อเร็ว ๆ นี้มีการปฏิวัติต่อต้านซิงเกิลบ้าง แต่มีอะไรผิดปกติกับพวกเขาไหมถ้าพวกเขาไร้สัญชาติ?

ฉันรู้ว่าการพูดคุยที่มากเกินไปและทั้งหมด ... สิ่งนี้ใช้ได้กับทุกสิ่งที่ไม่ใช่แค่ซิงเกิลตัน


1
ไม่ได้ซิงเกิลในหลักการไม่เลวพวกเขาใช้งานมากเกินไปอย่างมาก
Bart van Ingen Schenau

3
เมื่อเร็ว ๆ นี้คุณหมายถึงอะไร
Manoj R

5
@ โจอาคิมซาวเออร์: ทำไมคุณต้องเปลี่ยน; หากไร้สัญชาติคุณสามารถทดสอบได้อย่างผิดปกติ
m3th0dman

1
ถ้าคุณมีคนโสดไร้สัญชาติคุณจะมีคลาสยูทิลิตี้คงที่ซึ่งมีแนวโน้มที่จะเติบโตในรูปแบบการต่อต้านพระเจ้าระดับ โดยปกติคุณสามารถใช้วิธีการคงที่แทนในบริบทที่พวกเขาใช้ใน (หรือดียิ่งขึ้น: ใช้วิธีการขยายใน C #)
Spoike

คำตอบ:


12
  > Are immutable/stateless singletons bad?
  • ไม่หากไม่ได้ขึ้นอยู่กับระบบภายนอกอื่น ๆ
    • ตัวอย่าง: Stringutility ที่หนีออกมา html ภายในสตริง
    • เหตุผล: ใน unittests ไม่จำเป็นต้องแทนที่ด้วยจำลอง / จำลอง
  • ใช่ถ้าซิงเกิลที่ไม่เปลี่ยนรูป / ไร้สัญชาติของคุณขึ้นอยู่กับระบบ / บริการภายนอกอื่น ๆ และถ้าคุณต้องการทำการทดสอบแบบไม่แน่นอน (การทดสอบใน Isolation)
    • ตัวอย่าง: บริการที่ขึ้นอยู่กับ Tax-Calculator- Webservice ภายนอก
    • เหตุผล: ในการที่จะทำการถอนการติดตั้งด้วยบริการนี้ (แยกต่างหาก) คุณจะต้องจำลอง / จำลองระบบ / บริการภายนอก

สำหรับรายละเอียดเพิ่มเติมดูthe-onion-architecture


  • Singleton-s สามารถทำให้การทดสอบหน่วย (แบบแยก) difficuilt เพิ่มเติม / เป็นไปไม่ได้และ
  • การพึ่งพา / การมีเพศสัมพันธ์ที่ซ่อนอยู่สามารถมองเห็นเป็นปัญหาตามที่อธิบายโดย @ yBee

ฉันไม่เห็นเหตุผลอื่น ๆ ว่าทำไมไม่ใช้ Singletons


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

@ m3th0dman ฉันเห็นด้วย
k3b

10

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

หากคุณมีซิงเกิลไร้สัญชาติทำไมไม่ใช้คลาสที่เสนอวิธีการแบบคงที่เท่านั้น (หรือใช้คลาสแบบคงที่)?

ที่นี่โพสต์บางส่วนเกี่ยวกับตัวแปรทั่วโลกและซิงเกิลตันโดยทั่วไป

ฉันจะไม่เข้มงวดเท่าผู้เขียน แต่เขาแสดงให้เห็นว่าในกรณีส่วนใหญ่ที่คุณคิดว่าคุณต้องการซิงเกิลคุณไม่ต้องการมันจริงๆ


1
ทำไมไม่ใช้คลาสที่มีวิธีการคงที่? เช่นมรดก ...
m3th0dman

3
@ m3th0dman: ดูเหมือนจะไม่เหมาะสำหรับการสืบทอด
Billy ONeal

@BillyONeal คุณสามารถพูดได้ว่าสิ่งที่ดีหรือไม่ดีสำหรับการสืบทอดถ้าคุณรู้ว่ารูปแบบโดเมนสิ่งที่จะเป็นแบบในลักษณะนั้น ...
m3th0dman

2
@ m3th0dman: เอ่อไม่มี ฉันสามารถคิดบวกได้โดยไม่ต้องรู้อะไรเกี่ยวกับแบบจำลองโดเมน การสืบทอดมีไว้สำหรับพฤติกรรม polymorphic แต่ในฐานะซิงเกิลคุณจะไม่ได้มีพฤติกรรมแบบ polymorphic
Billy ONeal

1
@ m3th0dman: เนื่องจากการได้รับวัตถุ singleton ต้องระบุชื่อของ singleton ที่ไซต์การโทร ซึ่งหมายความว่าคุณไม่ได้ใช้พฤติกรรม polymorphic ซึ่งหมายความว่าองค์ประกอบนั้นมีความยืดหยุ่นมากกว่าการสืบทอด
Billy ONeal

7

ไม่มีสิ่งใดที่ซิงเกิลไร้สัญชาติไร้รูปสามารถทำสิ่งที่คลาสคงที่ไม่สามารถทำได้

ไม่มีเหตุผลที่จะเพิ่มความซับซ้อนในระดับพิเศษที่ -> Instance () สร้างขึ้นในขณะที่การเรียกธรรมดาไปที่วิธีการแบบสแตติกจะชัดเจนยิ่งขึ้นอนุรักษ์ในแง่ของทรัพยากรและอาจเร็วขึ้น

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


ฉันเดิมพันคุณสามารถสร้างบางกรณีที่ Singleton มีข้อได้เปรียบบางอย่าง ขึ้นอยู่กับสถานการณ์และภาษาโปรแกรม (เช่นการใช้ประโยชน์จากการโหลดแบบสันหลังยาว)
StampedeXV

1
@StampedeXV: ใช่แน่นอนเป็นรัฐเดี่ยว คนไร้สัญชาติและไร้ศีลธรรม - ฉันอยากรู้อยากเห็นตัวอย่างมาก ๆ แต่ฉันไม่กลั้นลมหายใจ
เอสเอฟ

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

1
กับการเรียนที่มีเพียงฟังก์ชั่นแบบคงที่คุณไม่สามารถใช้มรดก / polymorphism ซึ่งเป็นข้อ จำกัด ใหญ่ ...
m3th0dman

1
ไม่มีสิ่งใดที่ซิงเกิลไร้สัญชาติไร้รูปสามารถทำสิ่งที่คลาสคงที่ไม่สามารถทำได้ ดีวิธีคงที่ไม่สามารถใช้อินเทอร์เฟซซึ่งเดี่ยวสามารถทำได้
Michal M

3

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

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

interface Interface
{
    void Method();
}

class StatelessSingleton : Interface
{
    public static readonly StatelessSingleton Instance = new StatelessSingleton();
    private StatelessSingleton() { }

    public void Method() { }
}

class User
{
    public User(Interface i) { /* ... */ }
}

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

อย่างไรก็ตามบางทีเราควรใช้รูปแบบอื่นสำหรับการใช้งานเริ่มต้น:

class Implementation : Interface
{
    private readonly Action _method;

    public Implementation()
    {
        _method = new Action(() => { /* default */ });
    }

    public Implementation(Action custom)
    {
        _method = custom;
    }

    public void Method()
    {
        _method();
    }
}

มันกระทบกับประสิทธิภาพด้วยความเคารพ StatelessSingleton แต่ถือเป็นการใช้งานทั่วไปของอินเตอร์เฟส โซลูชันที่คล้ายกันนั้นถูกใช้โดยส่วนต่อประสานIProgress

เพิ่มอีกครั้งเหตุใดจึงอนุญาตให้สร้างการใช้งานพฤติกรรมเริ่มต้นมากกว่าหนึ่งรายการ แต่เราสามารถรวมสอง:

class Implementation : Interface
{
    public readonly Implementation Default = new Implementation();

    private readonly Action _method;

    private Implementation()
    {
        _method = new Action(() => { /* default */ });
    }

    public Implementation(Action custom)
    {
        _method = custom;
    }

    public void Method()
    {
        _method();
    }
}

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

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