2008-11-17 14 views
11

Tôi đã vật lộn trong vài tháng qua để tìm ra một số mã sạch để báo cáo tiến độ cho người dùng. Mọi thứ dường như luôn luôn sôi xuống:Làm cách nào để tạo mã sạch nhất khi báo cáo tiến trình cho người dùng?

ReportProgress("Starting Task 1"); 
doTask1(); 
ReportProgress("Task 1 is done"); 

ReportProgress("Starting Task 2"); 
doTask2(); 
ReportProgress("Task 2 is done"); 

//etc... where report progress does some form of output to the user. 

Trình coder tốt trong tôi hét lên "Phải có cách thức rõ ràng hơn!" Nhưng tôi đang bối rối. Có suy nghĩ gì không?

EDIT :: Tôi đang tìm kiếm thêm thông tin về thông tin kiến ​​trúc trái với thực hiện cụ thể. Mã được đưa ra là rất được đơn giản hóa.

+0

Bạn đang sử dụng ngôn ngữ nào? C#? Java? –

Trả lời

9

thiết lập công việc của bạn dưới dạng luồng sự kiện và có tiến trình báo cáo 'động cơ' xử lý sự kiện. Mỗi cá thể sự kiện có thể có tên riêng, biểu mẫu/mẫu báo cáo tiến độ, v.v. nếu bạn muốn đi xa đến đó

nếu đây là mẫu thường xảy ra, nó rất đáng để nỗ lực cho cơ sở hạ tầng.Khi bạn đã hoàn tất, các mã có thể sử dụng có thể giống như thế:

EventQueue tasks = new EventQueue(); 
tasks.Add(new TaskEvent(this.doTask1,"Foo-ing the bar")); 
tasks.Add(new TaskEvent(this.doTask2,"Bar-ing the foo")); 
tasks.Add(new TaskEvent(this.doTask3,"Glitching and whinging")); 
... 
tasks.Execute(this.ProgressEventHandler); 
+0

Wow, một mùi mã bạc hà. :) +1 –

+0

@ [Allain Lalonde]: cảm ơn, nó rất tươi, bạn vẫn có thể ngửi thấy mùi trình biên dịch! –

3

Bạn có thể sử dụng Aspect Oriented Programming và đưa ra Khía cạnh tiến độ không?

Có một số triển khai AOP. Trong thế giới Java, 2 phổ biến nhất là AspectJ và Spring (sử dụng AspectJ hoặc các proxy dựa trên các khía cạnh).

+0

lol - vâng tất cả các phương tiện học một mô hình hoàn toàn mới để giải quyết một vấn đề đơn giản! –

+0

Tôi đoán nó phụ thuộc vào số lượng mã. Đối với một chút mã, sau đó chắc chắn, một phương pháp tiếp cận tiến trình trong mã sẽ luôn là cách đơn giản nhất. Nhưng khi số lượng mã tăng lên, bạn sẽ có thêm mã để báo cáo tiến độ, làm xáo trộn chính logic lõi. Chỉ là ý kiến ​​của tôi. – toolkit

+0

@ Steven A. Lowe: Tôi tự hỏi liệu mọi người có phản ứng theo cùng một cách với đề xuất sử dụng các đối tượng khi lập trình hướng đối tượng ở giai đoạn trứng nước không. –

1

Tự động có báo cáo bên trong các cuộc gọi doTask().
Thông thường người báo cáo sẽ là một singleton rằng tất cả các đối tượng đã gửi tin nhắn đến và một lớp người báo cáo đã chịu trách nhiệm về việc quyết định có và hiển thị ở đâu - thanh trạng thái, tệp nhật ký, stderr, v.v.

+0

Điều này kết hợp các phương thức cho lớp người báo cáo, có nghĩa là bạn không thể gọi phương thức mà không báo cáo (hoặc thêm một tham số để kiểm soát xem bạn có gọi cho người báo cáo) hay không. Điều đó có thể ổn - chỉ cần nói. – MusiGenesis

+0

YOu thường cho phép đối tượng phóng viên quyết định xem nó có báo cáo hay không. Trừ khi bạn quan tâm đến chi phí của các bài báo cáo sẽ không được sử dụng. –

1

Giả sử mô hình trong những gì bạn ' tái làm là:

  • nhiệm vụ log bắt đầu
  • làm nhiệm vụ
  • log nhiệm vụ cuối

bạn có thể có một Lớp "Nhiệm vụ" (cha mẹ cho tất cả các nhiệm vụ của bạn), có phương thức do() được phân lớp và tự động ghi nhật ký bắt đầu và kết thúc tác vụ.

Chỉ là một ý tưởng.

0

Bạn có thể gọi ReportProgress từ bên trong phương pháp doTask, mà có thể làm cho nó trông một chút bụi, thay vào đó bạn sẽ chỉ có:

doTask1(); 
doTask2(); 

Việc báo cáo sẽ bị xử lý bên trong các phương pháp đó.

Bạn có thể sử dụng AOP, nhưng não của tôi hét lên KISS !! (Keep It Simple Stupid) trong trường hợp này. Nếu đây chỉ là một đại diện đơn giản của một cái gì đó phức tạp hơn mà bạn đang đối phó với, AOP có thể là một lựa chọn.

3

Bạn có thể tạo lớp Task với thuộc tính tên và ủy quyền. Đặt mỗi công việc trong một bộ sưu tập, sau đó lặp lại thông qua nó, in tin nhắn và gọi đại biểu cho mỗi tác vụ.

1

Tôi sẽ không mã hóa các phần số của các tin nhắn được hiển thị như thế (bất kỳ lúc nào bạn cần thêm hoặc xóa các hành động hoặc thay đổi trình tự mà bạn đã cắt và dán). Bạn muốn bất kỳ đối tượng nào đang xử lý phương thức ReportProgress để tự động tăng lên khi nó đi cùng.

1

Một cách khá đơn giản và sạch sẽ để tạo ra một lớp trừu tượng mà có một phương pháp do() và trừu tượng doTask() và getName() phương pháp:

do() { 
    ReportProgress("Starting " + this.getName()); 
    doTask(); 
    ReportProgress("Finished " + this.getName()); 
} 

sau đó, trong nhiệm vụ của bạn:

class Task1 extends Task { 
    getName(){return "Task 1";} 
    doTask() { 
     //do stuff here 
    } 
} 

sau đó, bạn có thể có một công tác mà có một phương pháp doTask() chạy do() trên một bó toàn bộ o nhiệm vụ. Điều này có thể dễ dàng được đệ quy, trong đó bất kỳ nhiệm vụ nào có thể chạy một số nhiệm vụ phụ.

1

+1 trên đề xuất AOP. Đây là một mối quan tâm xuyên suốt cổ điển mà AOP sẽ giải quyết một cách thanh lịch.

0

Thật không may, tôi nghĩ cách tốt nhất để làm điều này phụ thuộc vào chi tiết - ít nhất ngôn ngữ bạn đang sử dụng. Ví dụ trong python bạn có thể sử dụng một context manager để cho phép viết mã như thế này:

with progress_report("Task 1"): 
    do_task_1() 

Điều này có thể, ví dụ, đảm bảo rằng "Nhiệm vụ 1 được thực hiện" được báo cáo ngay cả khi do_task_1() đặt ra một ngoại lệ. Nếu bạn muốn, bạn có thể xử lý các ngoại lệ riêng biệt và in một cái gì đó khác nhau như "Task 1 thất bại" hoặc "Task 1 bị hủy bỏ."

0

Trong bộ công cụ của chúng tôi, chúng tôi có bộ điều khiển tác vụ quản lý tác vụ. Tác vụ được chạy dưới dạng một chuỗi. Ngoài hỗ trợ luồng thông thường, một tác vụ hỗ trợ các phương thức tiến trình. Một cái nhìn có thể về tiến trình là thanh tiến trình trực quan với tiêu đề đề cập đến tên nhiệm vụ và bước trong nhiệm vụ. Để hỗ trợ thống kê và trạng thái hiển thị, mã phải thực hiện các cuộc gọi không thường xuyên đến phương thức tiến trình của tác vụ. Thông thường, điều này được thực hiện trong vòng lặp vì tỷ lệ phần trăm có thể được ước tính bởi chỉ mục hiện tại chia cho giới hạn.

Bộ điều khiển tác vụ là nơi hữu ích để thêm điều khiển chuỗi toàn cục, đầu dò trạng thái, thống kê khác và móc đo lường hiệu suất. Một số lỗi và các vấn đề thời gian đa luồng có thể được phân tích bằng cách kiểm tra trạng thái của bộ điều khiển và trạng thái của tất cả các nhiệm vụ.

2

Điều đó phụ thuộc vào cấu hình cần thiết khi đang di chuyển, tôi hy vọng mã sẽ rất chung chung và có nhiệm vụ được thiết lập qua mùa xuân hoặc bất kỳ vùng chứa ioc nào.

Tất cả điều này sẽ có trong cấu hình mùa xuân: Cấu hình xml sẽ cung cấp đối tượng nhiệm vụ với tên và thông số của nó. sau đó thêm các tác vụ này vào bộ sưu tập và trao bộ sưu tập đó cho trình chạy tác vụ.

Nhân viên nhiệm vụ sau đó là mã báo hiệu dừng và bắt đầu mỗi tác vụ, nhưng mỗi tác vụ sau đó được tự do cung cấp trạng thái cụ thể về cách thức hoạt động của nó. Ngoài ra taskrunner sẽ bắt bất kỳ trường hợp ngoại lệ và tiếp tục đi nếu một cái gì đó errs ra. Nó có thể được thực hiện cấu hình để nói rằng một số nhiệm vụ phụ thuộc vào việc hoàn thành những người khác, và một số nhiệm vụ nên ngăn chặn tất cả mọi thứ nếu họ thất bại.

Tôi không đồng ý rằng AOP nên được sử dụng tại đây. quá mức.

0

Nếu bạn đang sử dụng .NET, tôi khuyên bạn nên sử dụng Chặn ứng dụng chính sách từ Enterprise Library (Phiên bản tối thiểu: 3.1). Tôi đã sử dụng một công cụ tương tự để thực hiện "Hoàn nguyên về nhận dạng hồ bơi ứng dụng" cho một trang web bị mạo danh nặng.

Bạn có thể làm tương tự với nhiệm vụ của mình. Bạn có thể chỉ định nghĩa một lớp nhiệm vụ với một nhà máy xây dựng đối tượng với nhà máy đối tượng Thư viện Doanh nghiệp và tự động thêm thông báo "Trước" và "Sau" vào tác vụ. Điều đó sẽ cung cấp cho CHÍNH XÁC những gì bạn muốn với sự thanh lịch được yêu cầu.

Hãy vui vẻ!