2012-08-14 37 views
5

Tôi biết rằng các biến toàn cầu là xấu và cần tránh càng nhiều càng tốt. Tuy nhiên, khi viết các chương trình song song với MPI chẳng hạn, một số biến chỉ được khởi tạo một lần và không bao giờ thay đổi (số của nhiệm vụ này, tổng số nhiệm vụ, v.v.). Nó vẫn được coi là thực hành xấu để có các biến này là toàn cầu? Vì bạn cần truy cập nhiều vào các biến này mọi lúc, nên có vẻ ngớ ngẩn khi tạo một lớp cho chúng trong chính và chuyển một con trỏ tới nó tới 99% tất cả các hàm trong chương trình. Cách tiếp cận của tôi cho đến nay đã được để ẩn chúng trong một không gian tên mpi_glob (đối với trường hợp của C + +, tôi đoán tôi sẽ không bận tâm để đặt chúng trong một struct trong C để thi đua một không gian tên). Tôi đoán câu hỏi này cũng áp dụng cho các biến số chỉ một lần khác như hệ thống đơn vị, v.v.Biến toàn cầu và MPI

Trả lời

5

Lý do các biến toàn cầu "là xấu" là chúng giới thiệu khớp nối giữa các tệp nguồn riêng biệt có thể khó xác định và theo dõi. Đặc biệt, nếu một biến toàn cầu có một trạng thái bất ngờ tại một số điểm trong chương trình, có thể khó để tìm ra nơi nó đã được sửa đổi.

Thay thế các biến chung bằng các biến cục bộ được chuyển qua tham chiếu tới mọi hàm trong chương trình không loại trừ vấn đề đó. Về mặt thiết kế, đó là "dữ liệu tramp", tức là dữ liệu di chuyển xung quanh ngay cả khi không cần thiết.

Bây giờ, điểm ở đây là, như bạn đề xuất, dữ liệu được khởi tạo một lần và không bao giờ thay đổi không có vấn đề khiến biến toàn cục "xấu". Vì vấn đề không tồn tại, giải pháp là không cần thiết.

0

Không có quy tắc nào được theo dõi trên vách đá và chi tiết cụ thể hoàn toàn phụ thuộc vào loại chương trình bạn đang viết.

Nếu chương trình của bạn là tương đối nhỏ (hoặc bạn là người duy nhất viết/duy trì nó), thì có thể để lại các biến "toàn cục" trong một không gian tên đặc biệt. Ít nhất theo cách đó bạn không có khả năng vô tình bóng hoặc dậm vào chúng trong một phạm vi địa phương một nơi nào đó. Đó là giả sử bạn không làm điều gì đó như thế này mặc dù:

using namespace mpi_glob; 

Điều này hơi khác so với việc chỉ có hình cầu ở một nơi nào đó và không bảo vệ chúng nhiều.

Nếu nó làm cho chương trình của bạn rõ ràng hơn và dễ hiểu hơn bằng cách sử dụng các biến toàn cục, hãy sử dụng chúng. Nếu có thể giữ chúng ở địa phương, hãy giữ chúng cục bộ, vì nó thường sẽ bảo trì đơn giản trong thời gian dài.

0

Tôi giả sử Singleton sẽ giúp bạn quản lý nó tốt hơn, vì vậy bạn không phải truyền con trỏ xung quanh. Thực tế, mpi_glob cũng làm như vậy, Singleton chỉ là cách quen thuộc hơn.

Ngoài ra, bạn vẫn có thể sử dụng các biến toàn cầu - chúng không tệ như vậy. Nếu bạn muốn nhấn mạnh nhiệm vụ một lần bạn có thể khai báo const và đặt chúng qua initializer tĩnh như thế này:

const int number_of_tasks = get_preconfigured_number_of_tasks(); 

nếu biến toàn cục của bạn được sử dụng để tổ chức biên dịch hằng số thời gian, sau đó nó là hoàn toàn tốt đẹp để thay thế chúng với enum thành viên hoặc bộ tiền xử lý xác định. Làm như vậy sẽ dễ dàng lên trên trình biên dịch, bởi vì nó có thể sử dụng ngay lập tức giá trị tại chỗ mà không cần truy cập bộ nhớ.


Tín dụng đi tới Pete Becker để trỏ Singleton phát biểu trong nhận xét của mình. Nếu những vấn đề đó làm phiền bạn, thì cách tiếp cận hoàn toàn khác có thể được thực hiện.

Hãy nhớ rằng các chương trình Java được triển khai như thế nào? Có lớp chính với phương thức chính và tất cả công việc của chương trình đều chạy từ bên trong phương thức chính đó. Chính vẫn là hàm thành viên, nghĩa là nó có thể truy cập độc quyền một số trường riêng của lớp chính (chúng phải là tĩnh trong trường hợp Java, nhưng đây không phải là điểm chính ở đây).

Chúng tôi có thể tiếp tục mở rộng khái niệm thành Command giống như triển khai. Sự khác biệt với Java thông thường là phương thức tương đương chính của bạn không phải là tĩnh và các biến toàn cục của bạn với các giá trị cụ thể cho chương trình có chứa là các biến thành viên không tĩnh. Tất cả các chức năng cần truy cập vào dữ liệu trạng thái toàn cục sẽ được chuyển đổi thành các hàm thành viên. Điều này là có thể, bởi vì phương pháp chính cũng là chức năng thành viên.

Bằng cách này, tôi nghĩ, bạn có thể đạt được sự đóng gói và an toàn dữ liệu tốt hơn.

+1

Một singleton quá mức cần thiết cho các hằng số và chỉ cung cấp một ảo ảnh về an toàn cho dữ liệu toàn cầu. Vấn đề với dữ liệu toàn cầu là nó có thể được sửa đổi từ bất kỳ tệp nguồn nào, vì vậy thật khó để biết được một thay đổi cụ thể đã được thực hiện ở đâu. Làm cho nó một singleton không thay đổi điều đó. Lợi ích duy nhất tôi nhận thức được từ việc sử dụng singleton là nó làm giảm thứ tự các vấn đề khởi tạo. Nhưng trật tự của các vấn đề khởi tạo phát sinh từ việc sử dụng quá nhiều các hình cầu; việc giảm việc sử dụng các hình cầu cũng làm giảm các vấn đề này, cũng như giảm các vấn đề gỡ lỗi mà các hình cầu có mặt. –

+0

@PeteBecker Tôi đồng ý với bạn về kiểm soát dữ liệu, đặc biệt nếu singleton chỉ là một đối tượng câm mà không cần getters/setters. Trong trường hợp này Singleton không có nghĩa là mang lại lợi thế OP đã không yêu cầu. Tôi đã rút ra nó chỉ để đại diện cho cách thông thường hơn, mà các lập trình viên phổ biến như tôi mong đợi. Nó chắc chắn là một overkill cho hằng số, đó là lý do tại sao có những lựa chọn thay thế khác. –

+0

nó không quan trọng cho dù đối tượng bạn nhận được từ một singleton có getters và setters. Nó vẫn là dữ liệu toàn cầu. Các getters và setters không hữu ích hơn và không kém hữu dụng hơn so với dữ liệu toàn cục thuần túy. –