2010-04-28 32 views
26

Tôi có một Lớp truy xuất một số dữ liệu và hình ảnh thực hiện một số nội dung cho chúng và chúng tải chúng lên ứng dụng của bên thứ ba bằng các dịch vụ web. Đối tượng cần thực hiện một số bước cụ thể theo thứ tự. Câu hỏi của tôi là tôi nên trình bày rõ ràng từng phương pháp công khai như vậy.Các phương thức được yêu cầu thực thi theo một thứ tự cụ thể có phải là riêng tư không?

myObject obj = new myObject(); 
obj.RetrieveImages(); 
obj.RetrieveAssociatedData(); 
obj.LogIntoThirdPartyWebService(); 
obj.UploadStuffToWebService(); 

hoặc tất cả các phương pháp này là riêng tư và được đóng gói trong một phương thức công khai như vậy.

public class myObject() 
{ 
private void RetrieveImages(){}; 
private void RetrieveAssociatedData(){}; 
private void LogIntoThirdPartyWebService(){}; 
private void UploadStuffToWebService(){}; 

public void DoStuff() 
    { 
    this.RetrieveImages(); 
    this.RetrieveAssociatedData(); 
    this.LogIntoThirdPartyWebService(); 
    this.UploadStuffToWebService(); 
    } 
} 

được gọi là như vậy.

myObject obj = new myObject(); 
obj.DoStuff(); 
+0

Bản sao có thể có của [Khi nào tôi nên sử dụng các phương thức công khai/riêng tư/tĩnh?] (http://stackoverflow.com/questions/793494/when-should-i-use-public-private-static-methods) –

Trả lời

25

Nó phụ thuộc vào ai biết rằng các phương pháp nên được gọi theo cách đó.

  • Consumer biết: Ví dụ, nếu đối tượng là một Stream, thường là tiêu dùng của Stream quyết định khi nào thì Open, Read, và Close dòng. Rõ ràng, các phương thức này cần phải được công khai hoặc đối tượng khác không thể được sử dụng đúng cách. (*)

  • Object biết: Nếu đối tượng biết thứ tự của các phương pháp (ví dụ đó là một TaxForm và phải thực hiện tính toán theo một thứ tự cụ thể), sau đó các phương pháp đó nên là riêng tư và tiếp xúc thông qua một một cấp cao hơn (ví dụ: ComputeFederalTax sẽ gọi CalculateDeductions, AdjustGrossIncomeDeductStateIncome).

  • Nếu số bước nhiều hơn số ít, bạn sẽ muốn xem xét một Strategy thay vì thực hiện các bước được kết hợp trực tiếp vào đối tượng. Sau đó, bạn có thể thay đổi mọi thứ xung quanh mà không mucking quá nhiều với đối tượng hoặc giao diện của nó.

Trong trường hợp cụ thể của bạn, có vẻ như người tiêu dùng đối tượng của bạn không quan tâm đến bất kỳ điều gì khác ngoài hoạt động xử lý. Vì nó không cần phải biết về thứ tự mà các bước đó xảy ra, nên có một phương thức công khai duy nhất được gọi là Process (hoặc một cái gì đó cho hiệu ứng đó).


(*) Tuy nhiên, thường là đối tượng biết ít nhất là trật tự trong đó các phương pháp có thể được gọi để ngăn chặn tình trạng không hợp lệ, ngay cả khi nó không biết khi để thực sự làm các bước . Nghĩa là, đối tượng nên biết đủ để ngăn bản thân khỏi bị rơi vào trạng thái vô nghĩa; ném một số loại ngoại lệ nếu bạn cố gắng gọi Close trước Open là một ví dụ điển hình về điều này.

2

Riêng tư - và lấy các tham số trong hàm tạo và thực hiện thứ tự tại đó.

Đừng cho người gọi biết, hoặc biết cách gọi, gọi cho họ theo thứ tự.

Vì vậy, chứ không phải là ví dụ bạn đã liệt kê, tôi sẽ làm điều đó theo cách này:

MyObject myObject = new MyObject(); // make a constructor to take any parameters that are required to "setup" the object per your requirements. 
myObject.UploadToWebService(); 
+0

Chỉ vì điều gì đó cần được thực hiện theo một thứ tự nhất định không có nghĩa là cần phải riêng tư. Ví dụ, nó không có ý nghĩa để gọi 'Close' trên một' Stream' trước khi bạn 'Open' nó, nhưng điều đó không có nghĩa là chúng ta nên làm cho những phương thức riêng tư. –

+0

Nó không phải là một tuyên bố chăn về tất cả mọi thứ nói chung, nhưng dựa trên mô tả của mình. –

4

Có tin, nếu không bạn đang để ngỏ cửa cho người sử dụng để làm những điều sai trái, mà sẽ chỉ có một gây đau cho mọi người.

Bạn có bao giờ cần tự gọi bất kỳ phương pháp nào trong số những phương pháp này không? tức là có ai trong số họ làm bất cứ điều gì hữu ích và có thể cần thiết một mình không? nếu vậy thì bạn có thể muốn giữ chúng ở chế độ công khai, nhưng ngay cả khi bạn giữ chúng ở chế độ công khai, bạn nên có phương thức gọi chúng theo đúng thứ tự (tốt nhất là với tên hữu ích) để giúp mọi người dễ dàng hơn.

+0

có thể downvoters xin vui lòng giải thích lý do? –

3

Nghe có vẻ như với người tiêu dùng về quan điểm đối tượng của bạn, đối tượng thực hiện một điều: nó di chuyển hình ảnh từ nơi này sang nơi khác. Là người tiêu dùng của đối tượng, tất cả các bước riêng lẻ bạn cần thực hiện để thực hiện điều đó không liên quan đến tôi; sau khi tất cả đó là lý do tại sao tôi có bạn để làm điều đó cho tôi.

Vì vậy, bạn cần có một phương thức DoStuff() duy nhất có tất cả các thông số cần thiết và đặt tất cả chi tiết triển khai ở chế độ riêng tư.

1

Nó thực sự phụ thuộc vào việc bạn ước tính rằng bất kỳ ai cũng muốn chỉ gọi một trong những phương pháp này và liệu chúng có ý nghĩa riêng hay có thể được triển khai độc lập. Nếu không, thì tốt hơn là tránh để lộ bất cứ thứ gì ngoài op cao cấp.

0

Câu hỏi công khai hoặc riêng tư phụ thuộc hoàn toàn vào hợp đồng bạn muốn vạch trần cho đối tượng của mình. Bạn có muốn người dùng của đối tượng của bạn gọi các phương thức riêng lẻ hay bạn muốn họ gọi một phương thức "DoStuff" đơn lẻ và được thực hiện với nó?

tất cả tùy thuộc vào mục đích sử dụng của lớp.

Trong ví dụ bạn đã đưa ra, tôi muốn nói DoStuff phải công khai và phần còn lại là riêng tư.

1

Hiển thị càng ít càng tốt, càng nhiều càng tốt. Nếu cuộc gọi đến FuncA()luôn, sau đó gọi tới số FuncB(), hãy thực hiện một số public và gọi điện cho số khác hoặc public FuncC() gọi cho chúng theo thứ tự.

0

Bạn nghĩ điều gì sẽ dễ dàng hơn cho người tiêu dùng trong lớp học của bạn?

Tuyệt đối viết một phương pháp công khai thực hiện đúng các bước theo đúng thứ tự. Nếu không, người gọi sẽ không làm điều đó đúng; họ sẽ quên một bước hoặc bỏ qua một cái gì đó.

1

Có, nó chắc chắn phải là riêng tư, đặc biệt là vì tất cả các phương pháp dường như không có tham số và bạn chỉ quan tâm đến thứ tự.

Thời gian duy nhất tôi xem xét gọi từng phương thức một cách rõ ràng là mỗi phương thức lấy một vài tham số không chồng chéo và bạn sẽ không muốn truyền một chuỗi thông số dài đến một phương pháp và muốn mô đun hóa. Và sau đó bạn nên đảm bảo ghi lại tài liệu rõ ràng. Nhưng hãy nhớ rằng các bình luận không thực thi được ... Bạn vẫn sẽ phải tin tưởng người dùng của bạn nhiều hơn một chút so với bạn thực sự cần.

Một trong những yếu tố lớn nhất của việc ẩn thông tin và OOP ... chỉ cung cấp cho người dùng những gì thực sự cần thiết. Cho phép càng ít chỗ cho mess-up càng tốt.

+0

một kịch bản khác có thể là nếu mỗi bước mất một thời gian dài đáng lo ngại, sau đó có thể tách nó lên và làm những việc ở giữa có thể là một điều tốt (nếu đa luồng không thể làm được). –

4

Tất cả phụ thuộc vào việc hoạt động về cơ bản là nguyên tử. Trong trường hợp này nó trông giống như một hoạt động duy nhất cho chúng tôi bên ngoài, nhưng nó thực sự? Nếu LogIntoThirdPartyWebService không thành công, giao diện người dùng có cần hiển thị một hộp thoại để hỏi người dùng nếu họ muốn thử lại không? Trong trường hợp bạn có một thao tác đơn lẻ, việc thử lại thao tác LogIntoThirdPartyWebService cũng yêu cầu thực hiện lại các hoạt động có khả năng tốn kém như RetrieveImages, trong khi làm cho chúng riêng biệt cho phép logic chi tiết hơn.

Những gì tôi sẽ làm gì trong trường hợp này là một cái gì đó như thế này:

Images images = RetrieveImages(); 
ImagesAndData data = RetrieveAssociatedData(images); 
WebService webservice = LogIntoThirdPartyWebService(); 
UploadStuffToWebService(data, webservice); 

hoặc có thể lý tưởng hơn một cái gì đó như thế này:

UploadStuffToWebService(RetrieveImages().RetrieveAssociatedData(), 
         LogIntoThirdPartyWebService()); 

Bây giờ bạn có granularity trong khi thi hành theo đúng thứ tự của các hoạt động.

+0

+1 có vẻ như lớp học của anh ấy có thể lưu trữ rất nhiều dữ liệu trong nội bộ mà các phương thức khác nhau trong quá trình sẽ phụ thuộc vào. –

+0

Tại sao lại là downvote? Tôi đề nghị cùng một điều như Rex M, và không ai downvoted câu trả lời của mình. – Gabe

0

Một lý do khiến chúng công khai là nếu bạn dự định người dùng có thể chèn logic giữa các bước. Trong trường hợp này, bạn nên áp đặt rằng các hàm được gọi theo đúng thứ tự nội bộ bằng cách giữ một máy trạng thái thực sự nhỏ. Nếu máy trạng thái chuyển đổi theo thứ tự sai, bạn có các tùy chọn ngoài việc làm điều gì sai, chẳng hạn như ném một ngoại lệ.

Tuy nhiên, một thiết kế thay thế cho phép tất cả chúng được giữ riêng tư nếu trường hợp cần thực hiện các bước đã tồn tại. Thay vì làm cho các phương thức công khai, cung cấp một giao diện gọi lại công khai cho phép người dùng đính kèm các trình xử lý mà bạn gọi ở mỗi bước của quy trình. Trong phương pháp hiện nay tin doItAll(), bạn có thể làm điều gì đó như dạng hạt như:

if(preRetrieveHandlerExists){ preRetrieveHandler() } obj.RetrieveImages();

if(postRetrieveHandlerExists){ postRetrieveHandler() } //so on and so forth

14

Nếu phương pháp B() thực sự không thể được gọi trừ khi A() được gọi đầu tiên, thiết kế sau đó đúng mệnh lệnh rằng A phải trả lại một số đối tượng mà B yêu cầu như một tham số.

Cho dù điều này luôn luôn thực tế là một vấn đề khác, nhưng đó là cách nó nên được thực hiện.

+0

Tôi trực giác thích câu trả lời này, nhưng tôi không chắc tại sao. Bạn có một số tài liệu tham khảo đó sẽ giải thích một chút lý do tại sao điều này là như vậy? – Daniel

+0

@Daniel Đây là cách duy nhất để thực thi lệnh gọi thông qua việc thiết kế mã của bạn. Lần đầu tiên tôi nghe nó trong một phiên với Bob Martin. –

+1

@Rex: Tôi nghi ngờ lý do bạn không thấy điều này rất nhiều là vì nó hiếm khi thực tế để thực thi lệnh gọi theo cách này. Ngoài ra, đây là những gì bạn đang làm nếu bạn chỉ có một chuỗi các phương thức: "đối tượng B yêu cầu" chỉ đơn giản là 'this', và nếu' this' không ở trạng thái đúng, bạn ném một ngoại lệ . –

0

Không. Tôi nghĩ rằng bạn có ít nhất 3 đối tượng nếu không bạn sẽ vi phạm Nguyên tắc một trách nhiệm. Bạn cần một đối tượng "Gets và giữ hình ảnh", một đối tượng "thao túng hình ảnh" và một đối tượng "quản lý thông tin liên lạc của nhà cung cấp bên ngoài".

0

Quy tắc kỹ thuật phần mềm của tôi là luôn luôn cung cấp cho người dùng/người tiêu dùng/người gọi càng ít cơ hội để xoay mọi thứ càng tốt. Vì vậy, giữ cho các phương pháp riêng tư để đảm bảo trật tự làm việc.

0

Fowler sử dụng thuật ngữ "Tính năng ghen tị" để mô tả tình huống mà một đối tượng gọi một số phương thức (đặc biệt là nhiều lần) trên một phương thức khác.

Tôi không biết anh ấy lấy nó từ đâu. Bạn không nhìn thấy nó nhiều trong văn học, và rất nhiều người trong những năm qua không biết tôi đang nói về điều gì (tôi không biết tại sao, tôi nghĩ cái tên đó hoàn toàn hiển nhiên khi tôi nghe nó. Đó là lý do tại sao tôi lặp lại nó)

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