Là singletons bất biến / không trạng thái xấu?


12

Gần đây đã có một số cuộc cách mạng chống lại những người độc thân, nhưng có điều gì sai trái với họ nếu họ không quốc tịch?

Tôi biết cuộc nói chuyện quá lạm dụng và tất cả ... điều này áp dụng cho tất cả mọi thứ không chỉ riêng người độc thân.


1
Không. Singletons về nguyên tắc không tệ, chúng chỉ được sử dụng quá mức.
Bart van Ingen Schenau

3
gần đây bạn có ý gì?
Manoj R

5
@Joachim Sauer: Tại sao bạn cần thay thế; nếu nó không trạng thái, bạn có thể kiểm tra nó ngay lập tức.
m3th0dman

1
Nếu bạn có singleton không trạng thái thì về cơ bản bạn có một lớp tiện ích tĩnh, có xu hướng phát triển thành mô hình chống lớp God. Bạn thường có thể sử dụng các phương thức tĩnh thay vì trong bối cảnh chúng được sử dụng (hoặc thậm chí tốt hơn: sử dụng các phương thức mở rộng trong C #).
Spoike

Câu trả lời:


12
  > Are immutable/stateless singletons bad?
  • Không nếu chúng không phụ thuộc vào các Hệ thống bên ngoài khác.
    • Ví dụ: Một Stringutility thoát html bên trong một chuỗi.
    • Lý do: Trong trường hợp không cần thiết phải thay thế điều này bằng một giả lập / giả lập.
  • nếu đơn vị bất biến / không trạng thái của bạn phụ thuộc vào các Hệ thống / Dịch vụ bên ngoài khác và nếu bạn muốn thực hiện việc không đáng tin cậy (thử nghiệm trong Cách ly)
    • Ví dụ: Dịch vụ phụ thuộc vào Dịch vụ Web-Máy tính Thuế bên ngoài.
    • Lý do: Để thực hiện các thao tác không mong muốn với Dịch vụ này (cách ly), bạn cần mô phỏng / mô phỏng các Hệ thống / Dịch vụ bên ngoài.

Để biết thêm chi tiết, xem kiến trúc hành tây


  • Singleton-s có thể làm cho thử nghiệm đơn vị (cách ly) trở nên phổ biến hơn / không thể và
  • các phụ thuộc / khớp nối ẩn có thể được coi là một vấn đề như được giải thích bởi @yBee

Tôi không thấy những lý do khác tại sao không sử dụng Singletons.


Bạn vẫn sẽ phải chế giễu dịch vụ web bên ngoài đó nếu bạn muốn kiểm tra lớp của mình, ngay cả khi đó không phải là một đơn vị (không quốc tịch).
m3th0dman

@ m3th0dman tôi đồng ý
k3b

10

Nó luôn luôn phụ thuộc vào việc sử dụng. Tôi nghĩ rằng cuộc cách mạng xuất phát từ thực tế, rằng tất cả các lập trình viên học mô hình này là các mô hình hướng đối tượng. Hầu hết quên suy nghĩ về nơi nó có ý nghĩa và nơi nó không.
Tất nhiên, điều này đúng với mọi mẫu. Chỉ bằng cách sử dụng các mẫu bạn không tạo mã tốt hoặc phần mềm tốt.

Nếu bạn có một singleton không trạng thái, tại sao không sử dụng một lớp chỉ cung cấp các phương thức tĩnh (hoặc sử dụng một lớp tĩnh)?

Ở đây một số bài viết liên quan đến các biến toàn cầu và singletons nói chung.

Tôi sẽ không nghiêm khắc như tác giả nhưng anh ấy cho thấy rằng trong hầu hết các trường hợp bạn nghĩ rằng bạn cần một người độc thân, bạn không thực sự cần nó.


1
Tại sao không sử dụng một lớp với các phương thức tĩnh? Kế thừa chẳng hạn ...
m3th0dman

3
@ m3th0dman: Nghe có vẻ không phải là nơi tốt để thừa kế.
Billy ONeal

@BillyONeal Bạn có thể nói rằng một cái gì đó tốt hay xấu cho việc thừa kế nếu bạn biết mô hình miền, cái gì sẽ được mô hình hóa theo cách đó ...
m3th0dman

2
@ m3th0dman: Erm, không. Tôi có thể khá tích cực mà không biết gì về mô hình miền. Kế thừa là cho hành vi đa hình. Nhưng là một người độc thân, bạn sẽ không có hành vi đa hình.
Billy ONeal

1
@ m3th0dman: Bởi vì để có được đối tượng singleton yêu cầu chỉ định tên của singleton tại trang web cuộc gọi. Điều đó có nghĩa là bạn không sử dụng hành vi đa hình. Điều đó có nghĩa là thành phần linh hoạt hơn nhiều so với thừa kế.
Billy ONeal

7

Không có gì một singleton không trạng thái bất biến có thể làm điều đó mà một lớp tĩnh không thể.

Đơn giản là không có lý do để thêm mức độ phức tạp thêm mà -> Instance () tạo ra, trong khi cuộc gọi đơn giản đến một phương thức tĩnh sẽ rõ ràng hơn, bảo thủ hơn về tài nguyên và có thể nhanh hơn.

Không phải họ sai. Đó là một cách tốt hơn để làm điều đó. Có những kịch bản mà những người độc thân bình thường ("nhà nước") là cách đúng đắn để đi. Cái ác với singleton là chúng thường bị lạm dụng, có kết quả xấu tương tự như các biến toàn cục, nhưng có những trường hợp cụ thể khi sử dụng singleton đơn giản là chính xác. Không có trường hợp như vậy cho những người không quốc tịch.


Tôi cá là bạn có thể xây dựng một số trường hợp trong đó Singleton có một số lợi thế. Tùy thuộc vào kịch bản và Ngôn ngữ lập trình có thể (ví dụ: tận dụng tải lười biếng).
StampedeXV

1
@StampedeXV: Vâng, một singleton trạng thái chắc chắn. Một người không quốc tịch và bất biến - Tôi thực sự tò mò muốn nghe bất kỳ ví dụ nào nhưng tôi không nín thở.
SF.

Ok, bạn có một điểm. Tôi khái quát câu trả lời của bạn một chút ở đó. Đối với trạng thái bất biến tôi cũng không thấy bất kỳ lợi thế nào.
StampedeXV

1
Với các lớp chỉ có chức năng tĩnh, bạn không thể sử dụng tính kế thừa / đa hình, đó là một giới hạn lớn ...
m3th0dman

1
Không có gì một singleton không trạng thái bất biến có thể làm điều đó mà một lớp tĩnh không thể. tốt, các phương thức tĩnh không thể thực hiện một giao diện, mà một singleton có thể
Michal M

3

Vấn đề chính với singleton là nó che giấu các phụ thuộc và khớp nối đặc biệt khi được sử dụng trong kịch bản mối quan tâm xuyên suốt. Xem Singletons là những kẻ nói dối bệnh lý hoặc Tại sao Singletons là Evil để đọc thêm.

Từ phía bên kia, một tiểu bang ít độc thân, nếu không bị lạm dụng, có thể hữu ích và cải thiện hiệu suất. Hãy xem xét một ví dụ:

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) { /* ... */ }
}

Ở đây, StatlessSingleton đóng vai trò là cài đặt mặc định của Giao diện và được đưa vào hàm tạo của Người dùng. Không có khớp nối mã hóa cứng và ẩn phụ thuộc. Chúng tôi không thể sử dụng một lớp tĩnh do giao diện bên dưới nhưng không có lý do gì để tạo nhiều hơn một phiên bản mặc định. Đó là lý do tại sao một người độc thân không quốc tịch dường như là một lựa chọn thích hợp.

Tuy nhiên, có lẽ chúng ta nên sử dụng một mẫu khác để triển khai mặc định:

class Implementation : Interface
{
    private readonly Action _method;

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

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

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

Nó đạt hiệu suất liên quan đến StatlessSingleton nhưng cấu thành một triển khai chung của Giao diện. Giải pháp tương tự được sử dụng bởi giao diện IProTHER .

Một lần nữa, tại sao cho phép tạo nhiều hơn một thực hiện hành vi mặc định? Tuy nhiên, chúng ta có thể kết hợp cả hai:

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();
    }
}

Để kết luận, tôi tin rằng có những nơi (như mặc định được mô tả) nơi Singletons hữu ích. Định nghĩa chính của Singleton nói rằng nó không cho phép tạo nhiều hơn một thể hiện của một lớp. Đó là năng lượng hạt nhân. Có thể tạo ra một năng lượng hoặc một quả bom. Nó phụ thuộc vào con người.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.