2013-04-15 36 views
9

khi đọc tài liệu python và các danh sách gửi thư khác nhau, tôi luôn đọc những gì trông hơi giống một giáo điều. Các biến toàn cầu nên tránh như địa ngục, chúng là thiết kế kém ... OK, tại sao không? Nhưng có một số tình huống sống thực sự mà tôi không làm thế nào để tránh một mô hình như vậy.Làm thế nào để tránh các biến toàn cầu

Giả sử tôi có GUI có thể tải một số tệp từ menu chính. Các đối tượng tệp tương ứng với các tệp đã tải có thể được sử dụng để hiển thị tất cả GUI (ví dụ: trình xem hình ảnh sẽ hiển thị hình ảnh và các hành động khác nhau có thể được thực hiện trên các hộp thoại/plugin khác nhau).

Có một cái gì đó thực sự xảy ra với việc xây dựng các thiết kế sau:

  • Menu.py -> file sẽ được nạp từ đây
  • Main.py -> các đối tượng tập tin được tải có thể được sử dụng đây
  • Dialog1.py -> hoặc đây
  • Dialog2.py -> hoặc có
  • Dialog3.py -> hoặc có
  • ...
  • Globals.py

nơi Globals.py sẽ lưu một từ điển có khóa là tên của các tệp đã tải và giá trị của các đối tượng tệp tương ứng. Sau đó, từ đó, các phần khác nhau của mã cần các dữ liệu đó sẽ truy cập nó thông qua các tham chiếu yếu.

Xin lỗi nếu câu hỏi của tôi có vẻ (hoặc là) ngu ngốc, nhưng bạn có thấy bất kỳ lựa chọn thay thế trang nhã hoặc toàn cầu nào không? Một cách sẽ là đóng gói từ điển dữ liệu đã nạp trong lớp ứng dụng chính của Main.py bằng cách xem nó như là phần truy cập trung tâm của GUI. Tuy nhiên, điều đó cũng sẽ mang lại một số biến chứng vì lớp này nên dễ dàng truy cập từ tất cả các hộp thoại cần dữ liệu ngay cả khi chúng là những đứa trẻ trực tiếp cần thiết của nó.

cảm ơn rất nhiều sự giúp đỡ của bạn

+1

biến toàn cầu không phải là điều xấu. Cái ác là gì khi sử dụng nó như một biến có thể thay đổi được. Các biến toàn cầu sẽ vẫn tĩnh và "bất biến" bất cứ khi nào có thể. Nếu bạn phải thay đổi nội dung từ điển trong globals.py, không tốt. Khác hơn thế, để đọc là không sao. – CppLearner

+0

có, toàn cầu "hằng số" là ok, toàn cầu "biến" nên tránh. – monkut

+1

OK, tôi hiểu ý nghĩa của cả hai bạn nhưng tôi vẫn không thấy một thay thế python hợp lệ cho thiết kế mà tôi đã đề xuất trong đó từ điển dữ liệu được tải có thể phát triển qua thời gian (tệp được tải mới, tệp đã xóa) – Eurydice

Trả lời

11

Biến toàn cục nên tránh vì chúng ức chế sử dụng lại mã. Nhiều widget/ứng dụng có thể sống độc đáo trong cùng một vòng lặp chính. Điều này cho phép bạn tóm tắt những gì bạn nghĩ là một GUI đơn thành một thư viện tạo GUI như vậy theo yêu cầu, để (ví dụ) một launcher đơn có thể khởi chạy nhiều GUI cấp cao nhất chia sẻ cùng một quá trình.

Nếu bạn sử dụng các biến toàn cầu, điều này là không thể vì nhiều phiên bản GUI sẽ vượt qua trạng thái của nhau.

Phương án thay thế cho biến toàn cục là liên kết các thuộc tính cần thiết với tiện ích con cấp cao nhất và tạo tiện ích phụ trỏ đến cùng một tiện ích con cấp cao nhất. Sau đó, ví dụ: một tác vụ menu sẽ sử dụng tiện ích con cấp cao nhất của nó để tiếp cận tệp hiện đang mở để hoạt động trên đó.

+0

Tôi sẽ đồng ý biến thành viên tĩnh/thuộc tính (nhưng không nhất thiết phải là thuộc tính cho mỗi trường hợp nếu chỉ một lần cho mục đích đọc, liên tục). Nhưng tùy thuộc vào yêu cầu, có một số hằng số không quá tệ. Chỉ cần chắc chắn rằng họ hiểu những gì Python có thể làm và không thể làm: p – CppLearner

+0

Nếu tôi làm cho bạn đúng, thiết kế như vậy sẽ giống như một loại cây nơi từ điển dữ liệu được tải sẽ được lưu trữ như một thuộc tính của tiện ích con cấp cao nhất. Sau đó, tất cả các widget của ứng dụng có thể truy cập nó thông qua một cuộc gọi đến phương thức "topLevelParent". – Eurydice

+0

Bạn có thể có 'MainModel' để lưu trữ tên tệp và dữ liệu cấp cao nhất. Với QT bạn sẽ có cửa sổ chính, và nó sẽ lưu trữ tên tập tin và dữ liệu cấp cao nhất. Các sự kiện để mở và ghi tệp thường được xử lý trong các đối tượng cấp cao nhất, các đối tượng cấp thấp hơn không cần phải biết tên tệp. – Eike

-1

Tôi sẽ quản lý dữ liệu toàn cầu bằng cách đóng gói dữ liệu trong một lớp quặng và thực hiện mẫu borg cho các lớp này. Xem Why is the Borg pattern better than the Singleton pattern in Python

+1

Xin đừng quảng cáo mẫu Borg. Toàn bộ điểm singleton là bạn có một ** đơn ** duy nhất, do đó tiết kiệm bộ nhớ và đảm bảo hành vi giống hệt nhau. Nếu nó thực sự cần thiết để có các cá thể khác nhau trong các lớp con khác nhau, có nhiều cách để làm điều đó mà không ảnh hưởng đến yêu cầu Singleton cơ bản để có một cá thể trên mỗi lớp. – user4815162342

+3

Cả mô hình Borg lẫn Singleton đều không làm giảm bớt vấn đề chính của các biến toàn cầu, đó là bạn có một trạng thái toàn cầu đơn. Thực tế, mẫu đơn giản đơn giản là một giao diện kiểu OO tốt đẹp cho một trạng thái toàn cầu được chia sẻ, chính xác là những gì mà văn học đang nói (không giải thích lý do tại sao) OP để tránh. – user4815162342

+1

Tôi thích một cách tiếp cận thực tế: các biến toàn cầu aka singleton aka borg pattern chỉ nguy hiểm nếu mã viết và đọc từ chúng. Một logger toàn cầu (tất cả các máy khách viết) không nguy hiểm cũng như một pool cho các kết nối cơ sở dữ liệu (tất cả các máy khách đọc). Sẽ tốt nếu các nhà phát triển theo dõi sách nhưng không nên quên đi phần backgound. – rocksportrocker

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