2010-05-02 40 views
8

Tôi đang tạo một chương trình sử dụng một vài hằng số. Lúc đầu, mỗi khi tôi cần sử dụng hằng số, tôi muốn xác định nó làSingletons và hằng số

//C# 
private static readonly int MyConstant = xxx; 

//Java 
private static final int MyConstant = xxx; 

trong lớp mà tôi cần đến. Sau một thời gian, tôi bắt đầu nhận ra rằng một số hằng số sẽ là cần thiết trong nhiều hơn một lớp.

Tại thời điểm này, tôi đã có 3 choises:

  1. Để xác định chúng trong các lớp khác nhau mà cần nó. Điều này dẫn đến sự lặp lại. Nếu bởi một số lý do sau này tôi cần phải thay đổi một trong số họ, tôi sẽ phải kiểm tra trong tất cả các lớp để thay thế chúng ở khắp mọi nơi.
  2. Để xác định một lớp tĩnh/singleton với tất cả các hằng số là công khai.
  3. Nếu tôi cần một hằng số X trong ClassA, ClassB và ClassC, tôi chỉ có thể xác định nó trong ClassA là công khai, và sau đó có ClassB và ClassC tham chiếu đến chúng. Giải pháp này dường như không tốt cho tôi vì nó giới thiệu nhiều sự phụ thuộc hơn khi các lớp đã có giữa chúng.

Tôi đã kết thúc triển khai mã của mình với tùy chọn thứ hai. Đó có phải là giải pháp thay thế tốt nhất? Tôi cảm thấy tôi có thể thiếu một số lựa chọn khác tốt hơn.

Điều gì khiến tôi lo lắng về việc sử dụng singleton ở đây là nó không rõ ràng đối với người dùng của lớp mà lớp này đang sử dụng singleton. Có lẽ tôi có thể tạo ra một ConstantsClass mà giữ tất cả các hằng số cần thiết và sau đó tôi sẽ vượt qua nó trong constructor cho các lớp học cần nó?

Cảm ơn

chỉnh sửa: Tôi đang sử dụng chủ yếu cho các loại phức tạp, không phải là int và chuỗi. Ít nhất trong trường hợp C# tạo sự khác biệt vì nó có nghĩa là tôi không thể sử dụng từ khóa const.

Trả lời

5

Không có từ ngữ nào về C#, nhưng trong Java có một số cách để giải quyết vấn đề này.

  1. Thay đổi access modifier thành mặc định (chỉ trọn gói) hoặc public. Giải pháp đơn giản nhất.

  2. Nhóm chúng trong gói riêng tư hoặc publicenum. Đơn giản nhất nếu các giá trị đó là có liên quan với nhau. Ví dụ. Role.ADMIN, Role.USER, Role.GUEST, v.v.

  3. Khai báo chúng trong một gói tin hoặc publicinterface và để cho các lớp thực hiện nó. Chỉ thực hiện việc này nếu các hằng số đó thuộc về một số hợp đồng mà các lớp phải tuân theo.

  4. Đặt chúng trong properties files và tải dưới dạng private static final Properties và thêm public static String getProperty(String key). Gói số này vào một số gói riêng tư hoặc publicConfiguration lớp. Hữu ích hơn nếu các hằng số có thể nhạy cảm với những thay đổi mà bạn có thể kiểm soát bên ngoài.

Hằng số không yêu cầu truy cập bởi một cá thể, do đó, toàn bộ ý tưởng đơn lẻ không có ý nghĩa.

+0

Nếu nó ở trong một singleton, họ sẽ không được tuyên bố là tĩnh, tất nhiên. Chúng chỉ được khai báo tĩnh nếu ở trong một lớp tĩnh hoặc đặt bên trong mỗi lớp cần nó. –

+1

Sau đó, các giá trị đó thực sự không phải là ** hằng số ** nữa. Không, quên ý tưởng đơn lẻ. – BalusC

1

Tôi định nghĩa nó ở một nơi, trong một trong các lớp cần thiết. Tôi sẽ làm cho nó tĩnh và cuối cùng và công khai vì vậy nó là sự thật liên tục, có thể truy cập bởi bất kỳ khách hàng khác mà cần nó.

4

Sử dụng tệp thuộc tính và đặt các hằng số trong đó.

+1

Tại sao tôi nhận được dinged? –

0

Một cách tiếp cận này sẽ là sử dụng Spring, có sẵn trong cả Java và .NET.

www.springsource.org
www.springframework.net - .net

Nếu tôi muốn sử dụng một tập tin cấu hình.

+0

Khi bạn có nghĩa là một tập tin cấu hình, cuối cùng bạn có nghĩa là sử dụng một cái gì đó giống như một Singleton? –

+0

Theo cấu hình, tôi đặt hằng số vào một vị trí duy nhất trong một tệp riêng biệt, nơi nó có thể dễ dàng được tìm thấy nếu nó cần được cập nhật - thuộc về ứng dụng chứ không phải là một lớp cụ thể. Nếu bạn cảm thấy bạn cần một mùa xuân đơn thì sẽ là lý tưởng cho điều đó. – McAden

+0

Có nhưng từ một quan điểm thiết kế của những gì bạn đang làm là dựa vào cái gì đó kết thúc lên trông giống như một lớp tĩnh. Bạn có tất cả các lớp của bạn dựa vào một đối tượng có trạng thái "toàn cục". –

2

ConfigurationManager.AppSettings Property trong .Net tồn tại chỉ vì lý do này. Bạn đặt cài đặt vào tệp cấu hình giả định rằng đây là những yếu tố mà bạn muốn được đặt ở một nơi, ví dụ: cho một trang web bằng cách sử dụng ASP.Net web.config là một nơi mà các thiết lập có thể được đặt để các môi trường phát triển, thử nghiệm và sản xuất có thể có các cài đặt khác nhau trong cách chúng chạy.

+0

Có nhưng điều đó kết thúc lên như là một lớp tĩnh, phải không? –

+1

Có lẽ, nhưng quan điểm của tôi là có sẵn các lớp học để làm những gì bạn cần, vậy tại sao không sử dụng chúng? –

2

As far as int là có liên quan tôi thường sử dụng một enum trong C#

public enum MyMagicNumbers 
{ 
    TheFirst = 1, 
    TheSecond = 2, 
    TheLast = 10, 
} 

Đối với các loại khác - như BalusC đã đề cập - một lớp niêm phong là tất cả các bạn cần

public sealed class MyMagicStuff 
{ 
    private MyMagicStuff() {} 

    public const string TheFirst = "One"; 
    public const string TheSceond = "Two"; 
    public const string TheLast = "Ten"; 
} 
+0

Làm thế nào thậm chí có thể sử dụng dữ liệu nếu bạn không thể khởi tạo lớp và các trường không tĩnh? –

+1

@devoured Đó là sufficent để làm cho họ 'const' - ít nhất là trong C#. – Filburt

+1

Không biết thực tế đó. Dù sao, các loại của tôi rất phức tạp, do đó tôi không thể sử dụng công cụ sửa đổi "const" trên chúng. –