Cấu hình lớp / cấu trúc: mẫu hoặc chống mẫu? Lựa chọn thay thế?


10

Nếu bạn thêm các tùy chọn cấu hình mới vào một chương trình, nó thường có thể có hàng tấn hiệu ứng gợn về việc đưa các tùy chọn đến nơi mà chúng cần phải được xử lý. Có ba cách cơ bản để giải quyết vấn đề này mà tôi biết:

  1. Truyền tất cả các cài đặt cấu hình cho các phần của chương trình của bạn cần chúng rõ ràng là nguyên thủy. Đây là cách rõ ràng nhất và cách phân tách mọi thứ nhiều nhất. Nhược điểm là điều này vừa dài vừa giòn.

  2. Thực hiện các cài đặt cấu hình được sử dụng thường xuyên nhất toàn cầu / tĩnh. Đây là cách đơn giản nhất nhưng giới thiệu hành động ở khoảng cách xa, cản trở khả năng kiểm tra và giả định rằng cấu hình thực sự là toàn cầu (rằng bạn chỉ muốn một cấu hình tại bất kỳ thời điểm nào).

  3. Tạo một lớp / cấu hình cấu hình có chứa tất cả các tùy chọn cấu hình cho toàn bộ chương trình hoặc cho từng mối quan tâm chính trong chương trình, và sau đó chuyển nó một cách rõ ràng. Điều này ít rõ ràng hơn (1) nhưng rõ ràng hơn (2). Nếu bạn muốn thay đổi cài đặt chỉ cho một cuộc gọi chức năng, bạn có thể sao chép đối tượng cấu hình và thay đổi một giá trị này. Điều này rất hữu ích trong cả thử nghiệm và trong thực tế. Tuy nhiên, cuối cùng bạn vẫn có khả năng chuyển hàng tấn thông tin đến một chức năng mà nó không cần và thay đổi một giá trị trong lớp cấu hình / struct vẫn có thể gây ra hành động từ xa.

Bạn sẽ xem xét (3) một mẫu hoặc một mẫu chống? Nếu đó là một mô hình chống, bạn sẽ làm gì thay thế?


Làm thế nào về một biến thể trên 3 - có một vài lớp cấu hình, chuyển một biến thích hợp đến nơi cần thiết?
Oded

@Oded: Tôi muốn nhấn mạnh điều đó như một khả năng. Đã chỉnh sửa.
dsimcha

Câu trả lời:


4

Các tốt nhất giải pháp sẽ được thực hiện một số giao diện cấu hình và thực hiện chúng như bạn muốn. Điều này cả hai giới hạn khả năng tiếp cận và giữ cho mọi thứ địa phương. Tuy nhiên, đó là quá nhiều nỗ lực để có giá trị của nó chỉ đơn giản là gặm nhấm tất cả các cấu hình trong một lớp duy nhất và chuyển sang một vấn đề với nhiều gravitas hơn. Đây là cấu hình, không phải UtterlyCrucialAlwaysChangingClass - nó sẽ không thay đổi nhiều. Miễn là bạn không làm cho nó trở nên toàn cầu và việc triển khai là nhất quán, tôi sẽ không lo lắng về điều đó.


4
+1 để nói rằng một cái gì đó không phải là thiết kế lý tưởng nhưng vẫn có thể tốt trong thực tế khi xem xét tính đơn giản và khả năng thay đổi (hoặc thiếu nó).
dsimcha

Tôi vừa ném ra bốn đối số và thay thế nó bằng một lớp Cài đặt. Nó cảm thấy như điều đúng đắn.
Martin Uting

Tôi không hiểu lựa chọn nào trong số 3 lựa chọn mà bạn ủng hộ. Bạn có thể vui lòng chỉ định?
DBedrenko

1

Tôi thích tùy chọn 1 của bạn vì việc tách rời cho phép kiểm tra dễ dàng hơn và các cài đặt cấu hình mà đối tượng phụ thuộc vào được thực hiện rõ ràng. Nếu một đối tượng yêu cầu một thiết lập cấu hình, thì cung cấp rõ ràng cho đối tượng đó bằng một đối số hàm tạo hoặc phương thức setter. Giảm mức độ chi tiết bằng cách sử dụng khung tiêm phụ thuộc để tiêm các cài đặt cấu hình đó vào đối tượng.


Bạn đã mâu thuẫn với chính mình: bạn nói hãy sử dụng Tùy chọn 1, nhưng sau đó nói "Giảm mức độ chi tiết bằng cách sử dụng khung tiêm phụ thuộc để tiêm các cài đặt cấu hình đó vào đối tượng." đó là lựa chọn 3: tiêm xây dựng.
DBedrenko

0

Hãy tưởng tượng nếu tập tin cấu hình của bạn được viết bằng XML. Sau đó, bạn có thể chuyển các đoạn XML này cho từng thành phần của mình để chúng có được dữ liệu cấu hình của chúng.

Nếu bạn đang sử dụng .NET, bạn có thể tạo các lớp với DataContuces mà bạn có thể sử dụng XmlSerialiser để tạo một đối tượng hierachy từ cấu hình Xml của bạn và chuyển các đối tượng này thành cấu hình.

Điều này sau đó giới thiệu cho bạn các vấn đề tiếp theo. Dữ liệu cấu hình của bạn có ba phần khác nhau. Cấu hình ứng dụng cấu trúc tổ chức các thư viện mã của bạn hoạt động như sản phẩm cụ thể này. Cài đặt cấu hình trang có chứa cài đặt cụ thể cài đặt của bạn và dữ liệu cài đặt / tùy chọn người dùng thay đổi theo từng người dùng trên hệ thống của bạn.

Biết phần nào là phần nào và giữ các cài đặt dữ liệu này tách biệt sẽ giúp việc cài đặt các bản cập nhật đơn giản hơn nhiều (không mất cài đặt của khách hàng)


0

Tôi sẽ làm cho lớp trong tùy chọn # 3 tĩnh. Vì vậy, thay vì

//create SomeCl
Foo f = new Foo();
f.setConfigInst(cfg);
...
...
//Inside Foo
public void setConfig(MyAppConfig c) { localCfg = c; }
...
//somewhere else:
x = localCfg.getConfigForX();

Bạn chỉ có thể có:

//Inside Foo
x = MyAppConfig.getConfigForX();

Hãy để các chi tiết tải / lưu dữ liệu cấu hình xảy ra trong MyAppConfiglớp. Và tất nhiên bạn có thể có các biến thể phức tạp hơn, chẳng hạn như các lớp khác nhau cho các mục đích khác nhau.

Trường hợp duy nhất mà cách tiếp cận này sẽ là một vấn đề sẽ xảy ra nếu bạn vì một số lý do cần thiết để làm việc trên nhiều phiên bản của các cấu hình khác nhau cùng một lúc , mặc dù tôi chưa gặp phải tình huống như vậy.


1
Đó là những gì xảy ra khi chạy thử nghiệm đơn vị trong một số khung thử nghiệm ... Nhưng ngay cả khi không có thử nghiệm đơn vị song song rõ ràng, nó sẽ gây khó khăn cho các đối tượng thử nghiệm đơn vị phụ thuộc vào trạng thái toàn cầu.
Péter Török

0

Tôi đang làm việc trong một dự án nơi chúng tôi đang sử dụng phương pháp "3 lớp (giao diện, logic nghiệp vụ, truy cập dữ liệu)". Ứng dụng có thể là máy chủ web nhiều người dùng hoặc máy chủ khách.

Chúng tôi làm việc với 3 cấu hình khác nhau, cụ thể đầu tiên cho PC, người dùng đang làm việc. Cụ thể thứ hai cho người dùng hiện tại và cấu hình toàn cầu thứ ba cho tất cả người dùng và ứng dụng khách.

Mỗi cấu hình được thể hiện trong mỗi instace của ứng dụng bởi một đối tượng.

Cách tiếp cận này có thể giúp dự án của bạn.

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.