2011-01-20 34 views
7

Tôi đã chọn lấy tệp thuộc tính để tùy chỉnh một số cài đặt. tôi sử dụng đoạn mã sau để thực hiện một thuộc tính đối tượng có sẵn trong một lớp họcTạo các thuộc tính Java có sẵn trên các lớp?

Properties defaultProps = new Properties(); 
    try { 
     FileInputStream in = new FileInputStream("custom.properties"); 
     defaultProps.load(in); 
     in.close(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

Tôi có phải thêm video này vào mỗi lớp? Có lẽ không phải vì sau đó mọi lớp sẽ mở một luồng cho tệp này. Nhưng tôi không chắc chắn làm thế nào để xử lý này đúng cách. Tôi có nên thực hiện một lớp học MyProperties và khởi tạo nó trong bất kỳ lớp học nào cần tài sản không?

Cảm ơn trước!

+0

câu trả lời liên quan: http: //stackoverflow.com/questions/4362911/how-to-create-a-singleton-class/4363254#4363254 – BalusC

Trả lời

10

Khi bạn đã khởi tạo defaultProps, bạn có thể cung cấp nội dung của nó cho các đối tượng khác trong ứng dụng của bạn, ví dụ: thông qua một phương pháp accessor tĩnh công cộng, ví dụ:

public class Config { 
    private static Properties defaultProps = new Properties(); 
    static { 
    try { 
     FileInputStream in = new FileInputStream("custom.properties"); 
     defaultProps.load(in); 
     in.close(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    } 
    public static String getProperty(String key) { 
    return defaultProps.getProperty(key); 
    } 
} 

Đây là phương pháp đơn giản nhất, tuy nhiên nó tạo ra một sự phụ thuộc thêm mà làm cho đơn vị kiểm tra khó khăn hơn (trừ khi bạn cung cấp một phương pháp trong Config để thiết lập một đối tượng sở hữu mô hình để thử nghiệm đơn vị).

Cách khác là tiêm defaultProps (hoặc giá trị cấu hình riêng lẻ từ nó) vào mỗi đối tượng cần. Tuy nhiên, điều này có nghĩa là bạn cần phải thêm (các) tham số bổ sung vào nhiều phương thức nếu phân cấp cuộc gọi của bạn sâu.

+1

Tôi không thích giải pháp này. Làm cho phương pháp không tĩnh và tạo ra một singleton làm cho nó linh hoạt hơn nhiều và chi phí không có gì. – maaartinus

+0

@maaartinus: cách chính xác áp dụng mẫu đơn giản hơn? Bạn không nhầm lẫn nó với mô hình nhà máy trừu tượng? – BalusC

+1

@maaartinus, Singleton sẽ linh hoạt hơn như thế nào? Lưu ý rằng thực tế đây đã là một singleton (nó là một đối tượng toàn cầu duy nhất, với tất cả các hành lý phụ thuộc của nó), chỉ ẩn đằng sau một giao diện. –

0

Có quá ít thông tin để xác định cách tốt nhất để xử lý vấn đề này là gì. Bạn có thể muốn để lộ nó bằng cách sử dụng một accessor, hoặc vượt qua nó vào mỗi lớp đòi hỏi nó. Ngoài ra, bạn có thể rút ra các thuộc tính mà mỗi lớp cần và chuyển các giá trị của chúng vào trong hàm tạo của lớp.

0

Tải các thuộc tính khi sử dụng và lưu trữ các thuộc tính một cách nào đó mà các lớp khác có thể kéo. Nếu đó là một lớp MyProperties tham chiếu đến một biến tĩnh ở đâu đó thì tốt.

0

Đây là trường hợp đặc biệt để làm mọi thứ có sẵn trên toàn cầu. Sử dụng phương pháp tĩnh là khá xấu. Một giải pháp tốt hơn nhưng xấu là sử dụng mẫu sigleton. Thử nghiệm là vấn đề lớn nhất ở đây. IMHO, cách tốt nhất là sử dụng Dependency injection, mặc dù nó có thể là quá mức cần thiết cho các ứng dụng nhỏ.

3

Nếu bạn chỉ cần một phiên bản thuộc tính thuộc tính của mình, bạn có thể sử dụng singleton pattern.

Nó sẽ trông giống như một lớp học như thế này:

public class MyProperties extends Properties { 
    private static MyProperties instance = null; 

    private MyProperties() { 
    } 

    public static MyProperties getInstance() { 
     if (instance == null) { 
      try { 
       instance = new MyProperties(); 
       FileInputStream in = new FileInputStream("custom.properties"); 
       instance.load(in); 
       in.close(); 
      } catch (Exception e) { 
       e.printStackTrace(); 
       return null; 
      } 
     } 
     return instance; 
    } 
} 
+0

"this.load (in);" cần phải là "instance.load (in);" – icedek

+0

@icedek cố định (câu trả lời cũ của tôi!) – SirDarius

0

Kể từ khi thông tin này là tĩnh trên tất cả các trường hợp, tôi khuyên bạn nên thực hiện các lớp Properties như một singleton. Bằng cách sử dụng phương thức staticinitialization block, bạn có thể tự động tải tệp khi chương trình khởi động.

public class Properties { 
    static { 
    try { 
     FileInputStream in = new FileInputStream("custom.properties"); 
     load(in); 
     in.close(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    } 

    protected static void load(FileInputStream in) { 
    // existing load functionality here 
    } 
} 

Bạn vẫn cần một cơ chế lưu trữ nội bộ và cơ chế truy cập. Chúng cũng phải được đánh dấu là static.

1

Tại sao không sử dụng ResourceBundle tĩnh?

static final ResourceBundle myResources = 
      ResourceBundle.getBundle("MyResources", currentLocale); 
0

Thay vì tải thuộc tính trong mọi lớp. Tải nó ở đâu đó quanh main() và chuyển nó tới các lớp khác thông qua các hàm tạo của chúng.

Không chia sẻ chúng trên toàn cầu. - Khó để kiểm tra - Against the trừu tượng (truy cập toàn cầu, DAO có thể truy cập thiết lập người dùng nó phải được ngăn ngừa bằng cách đi qua chỉ những gì nó cần .. không phải mọi thứ.) - Các lớp nằm gì họ cần

Các vấn đề liên quan