2009-05-21 27 views
8

Tôi được sử dụng để viết các ngôn ngữ. PHP, Javascript vv và tôi đã viết một vài ứng dụng Java và C# tương đối đơn giản. Đây là một câu hỏi tôi đã nhiều lần cần một câu trả lời cho, và tôi tưởng tượng tôi không phải là người duy nhất.Làm cách nào để duy trì dữ liệu mà không có biến toàn cầu?

Giả sử tôi đang sử dụng Javascript.

Tôi có hàm A(), được gọi bởi GUI, truy xuất một số giá trị.

Chức năng B(), cũng được gọi bởi GUI, yêu cầu giá trị đó, nhưng hàm B() sẽ được gọi là số lần tùy ý, một khoảng thời gian tùy ý sau A().

Tôi không muốn A() tính lại giá trị mỗi lần.

Ví dụ là thông tin xác thực đăng nhập. A() yêu cầu tên người dùng và B() sử dụng giá trị đó để nối thêm vào nhật ký mỗi khi được gọi.

Đối với điều này, tôi có thể chỉ sử dụng biến toàn cục.

Hiện tại, C#. Không có biến toàn cầu! Làm thế nào tôi phải làm điều này?

Chỉnh sửa: Tận hưởng câu trả lời nhưng có rất nhiều ý kiến ​​"cố gắng không sử dụng hình cầu". Tôi hiểu điều đó, nhưng tôi muốn nghe các mẫu thay thế cho yêu cầu này.

+2

Bạn có thể xem xét việc đọc "ghi nhớ", là tên cho kỹ thuật chung để ghi nhớ đầu ra của một hàm và sử dụng lại nó sau này mà không tính toán lại nó. Có rất nhiều kỹ thuật thú vị để ghi nhớ hiệu quả. –

Trả lời

4

Trước tiên, hãy luôn tự hỏi bản thân xem bạn có thực sự cần phải có toàn cầu hay không, thường thì bạn sẽ không. Nhưng nếu bạn thực sự cần phải có một ...

Cách tốt nhất để làm điều này là để có một tài sản tĩnh trên một số lớp hợp lý được đặt tên, nó có hiệu quả trở nên biến toàn cầu của bạn

public class Credentials 
{ 
    public static string Username {get;set;} 
} 

//...somewhere in your code 

Credentials.Username = "MyUserName"; 

EDIT:

Một vài người ở đây đã nói tuyên bố chăn rằng Biến toàn cầu là xấu, và tôi đồng ý với tình cảm này, và nó sẽ xuất hiện rằng các nhà thiết kế của C# cũng đồng ý vì chúng đơn giản là không có sẵn.

Tuy nhiên, chúng ta nên xem xét lý do tại sao Globals là xấu, và chúng được coi là xấu vì bạn phá vỡ các quy tắc đóng gói. Mặc dù dữ liệu tĩnh không phải là xấu, nhưng điều tốt về dữ liệu tĩnh là bạn có thể gói gọn nó, ví dụ trên của tôi là một ví dụ rất đơn giản về điều đó, có thể trong một tình huống thực tế bạn sẽ bao gồm dữ liệu tĩnh của bạn trong cùng một lớp làm việc khác với thông tin đăng nhập, có thể là lớp Đăng nhập hoặc Lớp người dùng hoặc bất kỳ điều gì có ý nghĩa với ứng dụng của bạn.

+0

Tôi sẽ nhấn mạnh: KHÔNG sử dụng globals :) Tuy nhiên, nếu bạn nhấn mạnh, đây là một cách hay để làm điều đó. –

+0

@Marcel: C# không có hình cầu. – Brian

+0

Cảm ơn câu trả lời của Tim. Marcel - cho yêu cầu này, bạn sẽ đề xuất gì thay vào đó? – ChristianLinnell

0

Trong C#, một trong những cách để có được hành vi tương tự như các biến toàn cục là sử dụng các phương thức lớp tĩnh và các biến lớp. Các phương thức và các biến lớp tĩnh có một cá thể duy nhất trong C# và có phần giống với các biến toàn cục trong các ngôn ngữ khác.

Điều đó nói rằng, đối với vấn đề của bạn, nó có vẻ giống như một vấn đề thiết kế. C# rất tập trung vào thiết kế hướng đối tượng; Tôi muốn nghi ngờ cho vấn đề bạn đã đưa ra rằng một OOD tốt hơn sẽ giải quyết vấn đề của bạn.

5

Đây không phải là một thói quen tốt, nhưng nếu bạn thực sự cần nó, có một số cách sau:

  1. Ứng dụng web: Bạn có thể đặt biến của bạn trong một số loại ngữ cảnh, giống như phiên hoặc phạm vi ứng dụng.
  2. Ứng dụng dành cho máy tính để bàn: Bạn có thể tạo đối tượng và lưu trữ đối tượng đó làm thuộc tính của lớp luôn có đối tượng đang hoạt động.
  3. Bất kỳ loại ứng dụng nào: sử dụng thuộc tính tĩnh công khai. Nó hiển thị cho tất cả mọi người.
+0

Cảm ơn câu trả lời ... vì vậy bạn nên đề xuất phương pháp hay nào? – ChristianLinnell

+0

Thay đổi thiết kế của bạn để phù hợp hơn với mô hình thiết kế của ngôn ngữ bạn đã chọn! – tomfanning

0

Chức năng A sẽ là một phần của một lớp (gọi là C). Hàm A sau đó có thể lưu trữ các thông tin đăng nhập và cung cấp một hàm (hoặc trong C#, một thuộc tính) để có được các thông tin đăng nhập. Khi chúng được yêu cầu, bạn có thể chỉ cần sử dụng thuộc tính để có được các thông tin được lưu trữ và chuyển chúng vào Hàm B (trên một lớp khác).

class C 
{ 
    public void functionA() 
    { 
     credentials = obtainCredentials; 
    } 

    private LogonCredentials _logonCredentials = null; 

    public LogonCredentials logonCredentials 
    { 
     get { return _logonCredentials; } 
    } 
} 

class D 
{ 
    public void functionB(LogonCredentials credentials) 
    { 
     //do stuff 
    } 
} 

///other stuff 
///other function ... 
    ... 
    instanceC = C(); 
    instanceC.functionA(); 
    ///more stuff here 
    instangeD = D(); 
    instanceD.functionB(instanceC.logonCredentials); 
1

Tôi muốn nói bạn nên sử dụng số Singleton Pattern.

Nếu bạn đang đi cho một ứng dụng đa luồng thì bạn cũng cần phải đảm bảo truy cập vào các thuộc tính của cá thể của singleton là threadsafe.

Như mọi khi, hãy suy nghĩ cẩn thận về việc giới thiệu bất kỳ loại hình toàn cầu nào trong ứng dụng của bạn nhưng đừng ngại sử dụng nó. Rất nhiều thứ thực sự là hình cầu, ví dụ như App.Settings mà không có bất kỳ thứ gì "xấu" trong chúng.

Điều này article on MSDN giải thích cách tạo đúng singleton trong C#.

+2

@Jorge, vì đây là lời khuyên không tốt. Một singleton không nên được sử dụng cho dữ liệu tĩnh, yêu cầu đối với mẫu singleton thực sự hiếm hơn mọi người nghĩ, nhiều hơn về hạn chế sử dụng tài nguyên và đảm bảo rằng các cuộc gọi phương thức đang gọi trên trạng thái nhất quán ... chứ không chỉ giữ dữ liệu tĩnh . –

+0

Tôi nhận thấy điều đó đúng với lý thuyết nhưng trong thực tế chúng chỉ hữu ích. Họ cung cấp instanstiation lười biếng, một điểm truy cập phổ biến, và mức độ cần thiết của trừu tượng như vậy về cơ bản, khi nói đến được thực dụng, tôi thấy tự của tôi sử dụng chúng anyway. –

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