2015-05-14 14 views
5

Câu hỏi của tôi không may được hình thành xấu vì tôi không hoàn toàn chắc chắn để gọi những gì tôi đang cố gắng làm. Tôi xin lỗi vì điều đó.Thiết kế chương trình mô-đun

Nó xuất hiện kể từ khi tôi đang cố gắng mã hóa một trình duyệt thực sự cơ bản mà tôi muốn triển khai trong C và tôi đã suy nghĩ về cách tốt nhất để thực hiện nó. Ý tưởng cơ bản là một cái gì đó như libcurl (cho tương tác mạng) -> libxml2 (phân tích HTML) -> UI và sau đó một số cách để nhận libcurl chấp nhận yêu cầu GET hoặc POST từ giao diện người dùng (chưa đến thời điểm này).

Tuy nhiên, approuch này bị hạn chế nghiêm trọng, nếu tôi nói muốn kiểm tra xem đó là một tệp PDF và sau đó gửi nó đến libpoppler trước khi giao nó cho libxml2, tôi sẽ phải mã hóa toàn bộ luồng chương trình của mình. Hơn nữa, nếu tôi muốn sử dụng các phần của chương trình của tôi (ví dụ, phần libcurl -> pdftohtml -> libxml2) và gửi nó đến một chương trình khác (ví dụ w3m thay vì giao diện người dùng của tôi), tôi lại không thấy tôi sẽ quản lý điều đó.

Thay vào đó, tôi có thể viết một trình bao bọc Perl hoặc Python cho curl, libxml2, v.v. hoặc làm điều gì đó dọc theo dòng "curl example.com | parser | UI". Tuy nhiên làm nó trong Perl hoặc Python vẫn có vẻ như tôi sẽ phải recode logic chương trình của tôi mỗi khi tôi muốn làm một cái gì đó mới, và đường ống tất cả mọi thứ dường như không phù hợp. Tôi cũng muốn làm điều này trong C nếu có thể.

Vì vậy, câu hỏi của tôi là; một người gọi ý tưởng này là gì? Tôi đã lái xe bản thân mình điên cố gắng tìm ra cách để tìm kiếm một giải pháp cho một vấn đề mà tôi không thể đặt tên. Tôi biết nó có liên quan đến mô đun, tuy nhiên tôi không biết cụ thể và mô đun nào là một cụm từ rộng rất. Thứ hai và tùy chọn nếu bất cứ ai có thể chỉ cho tôi theo hướng của một giải pháp tôi sẽ đánh giá cao điều đó cũng mặc dù nó không quan trọng như những gì nó được gọi là.

Nhờ tất cả những ai đã đọc nội dung này. :)

+2

Có thể đáng chú ý là một trình phân tích cú pháp XML (libxml2) * không thể * phân tích cú pháp HTML trực tiếp. Trước tiên, bạn sẽ phải chạy HTML thông qua một bước chuyển đổi nó thành cú pháp XML chính xác, điều này sẽ là một thách thức (và sau đó bạn đã viết một trình phân tích cú pháp HTML). –

+1

Tôi thực sự không hiểu ý bạn là gì. Bạn gửi một yêu cầu và sau đó bạn nhận được một phản hồi, khi bạn làm sau đó bạn kiểm tra xem nó là gì và gọi hàm thích hợp để làm những gì bạn muốn -> (Render HTML, Mở một tệp PDF ... vv), tại sao bạn cần phải ** recode ** toàn bộ điều? Ý tưởng của bạn về điều đó không có ý nghĩa với tôi. –

+0

@GregHewgill AFAIK 'libxml2' có giao diện trình phân tích html. –

Trả lời

4

Trước tiên, tôi đề nghị bạn hãy xem http://www.amazon.com/Interfaces-Implementations-Techniques-Creating-Reusable/dp/0201498413. Hầu hết các trình duyệt thứ hai là không đồng bộ, do đó bạn sẽ cần thư viện sự kiện như libuv hoặc libev. Ngoài ra, hầu hết các trang web hiện đại đều yêu cầu javascript hoạt động bình thường, nhưng việc thêm một công cụ javascript vào trình duyệt của bạn sẽ làm phức tạp nhiều dự án. Tôi cũng không thấy bất kỳ đề cập nào về cách bạn lập kế hoạch phân tích cú pháp http được gửi đến và từ trình duyệt của bạn, tôi đề xuất https://github.com/joyent/http-parser.

Đối với câu hỏi của bạn về luồng điều khiển, tôi sẽ có chức năng phân tích phản hồi từ máy chủ và sử dụng switch() để xử lý các loại dữ liệu khác nhau được gửi tới trình duyệt của bạn. Có một trường trong tiêu đề http giải thích loại nội dung và theo cách đó, trình duyệt của bạn sẽ có thể gọi các chức năng khác nhau dựa trên loại nội dung.

Ngoài ra hãy xem các con trỏ hàm, cả ở đây Polymorphism (in C) và tại đây How do function pointers in C work?. Con trỏ chức năng sẽ/có thể là một cách hùng hồn hơn để giải quyết vấn đề của bạn thay vì có các câu lệnh chuyển đổi lớn thông qua mã của bạn. Với các con trỏ hàm, bạn có thể có một hàm mà khi được gọi trong chương trình của bạn hoạt động khác nhau.

Tôi sẽ cố gắng giải thích bên dưới bằng trình duyệt làm ví dụ.

Vì vậy, giả sử trình duyệt của bạn vừa nhận được phản hồi http từ một số máy chủ. Câu trả lời http trông giống như thế này trong C.

struct http_res 
{ 
    struct http_header *header; 
    struct http_body *body 

    int (*decode_body)(char **); 
}; 

Vì vậy, trình phân tích cú pháp http đầu tiên sẽ phân tích tiêu đề http và tìm hiểu xem đó có phải là phản hồi hợp lệ và nếu có nội dung, v.v.Nếu có nội dung, trình phân tích cú pháp sẽ kiểm tra loại và dựa trên, nếu đó là html, javascript, css hoặc bất kỳ trình phân tích cú pháp nào sẽ đặt con trỏ hàm trỏ tới hàm đúng để giải mã cơ thể http.

static int decode_javascript(char **body) 
{ 
    /* Whatever it takes to parse javascript from http. */ 
    return 0; 
} 

static int decode_html(char **body) 
{ 
    /* Whatever it takes to parse html from http. */ 
    return 0; 
} 

static int decode_css(char **body) 
{ 
    /* Whatever it takes to parse css from http. */ 
    return 0; 
} 

int parse_http_header(struct http_res *http) 
{ 
    /* ... lots of other code to figure out content type. ... */ 

    switch(body_content_type) 
    { 
     case BCT_JAVASCRIPT: 
      http->decode_body = &decode_javascript; 
      break; 

     case BCT_HTML: 
      http->decode_body = &decode_html; 
      break; 

     case BCT_CSS: 
      http->decode_body = &decode_css; 
      break; 

     default: 
      printf("Error can't parse body type.\n"); 
      return -1; 
    } 
    return 0; 
} 

Bây giờ khi chúng ta vượt qua những yêu cầu http đến một phần khác của trình duyệt có chức năng có thể gọi decode_body() trong đối tượng phản ứng http và nó sẽ kết thúc với một cơ thể được giải mã nó có thể hiểu, với ra biết những gì nó giải mã.

int next_function(struct http_res * res) 
{ 
    char *decoded_body; 
    int rtrn; 

    /* Now we can decode the http body with out knowing anything about 
    it. We just call decode_body() and end up with a buffer with the 
    decoded data in it. */ 
    rtrn = res->decode_body(&decoded_body); 
    if(rtrn < 0) 
    { 
     printf("Can't decode body.\n"); 
     return -1; 
    } 

    return 0; 
} 

Để làm cho chương trình của bạn thực sự mô-đun ít nhất là trong C, bạn sẽ dính vào các phần khác nhau của trình duyệt của bạn trong các thư viện chia sẻ khác nhau, như phân tích cú pháp HTTP, thư viện sự kiện, động cơ Javascript, html phân tích cú pháp, vv, vv Sau đó, bạn sẽ tạo ra các giao diện giữa mỗi thư viện và bạn có thể trao đổi từng thư viện với một thư viện khác với việc phải thay đổi chương trình của bạn, bạn sẽ liên kết một thư viện khác vào thời gian chạy. Hãy xem Tiến sĩ Robert martin (chú bob) ông nói về điều này rộng rãi. Cuộc nói chuyện này là tốt nhưng nó thiếu slide https://www.youtube.com/watch?v=asLUTiJJqdE, bắt đầu lúc 8:20. Điều này cũng thú vị, và nó có slide: https://www.youtube.com/watch?v=WpkDN78P884.

Và cuối cùng không có gì về C, perl hoặc python có nghĩa là bạn sẽ phải mã hóa logic chương trình của mình. Bạn sẽ phải thiết kế chương trình của bạn để mỗi mô-đun không biết về nhau. Module này biết về giao diện và nếu bạn kết nối hai mô-đun mà cả hai "nói" cùng một giao diện, bạn sẽ tạo ra một hệ thống mô-đun. Nó giống như cách internet hoạt động trên các máy tính khác nhau trên internet không cần biết máy tính khác là gì, hoặc nó đang hoạt động, hoặc hệ điều hành, tất cả những gì họ cần biết là TCP/IP và họ có thể liên lạc với tất cả các thiết bị khác trên mạng.

+0

Cảm ơn bạn, tôi sẽ xem xét những gì bạn gợi ý vì dường như nó đang đi đúng hướng tới những gì tôi đang cố gắng làm. Thực tế là tôi đang mã hóa một trình duyệt có phần tùy tiện, tôi quan tâm nhiều hơn đến việc sử dụng nó để tìm hiểu cách viết các chương trình mô-đun. Bạn có muốn mở rộng hai đoạn văn cuối cùng của mình thêm một chút nữa vì tôi không chắc chắn ý bạn là gì? – Ellen

+0

Yea không có vấn đề, và không mong đợi để đọc tất cả trong một ngồi. Tôi chỉ đọc một số ít trang mỗi ngày. Ngoài ra Hãy nhìn vào thế kỷ 21 C, sách giao diện được viết theo kiểu C cũ hơn. – 2trill2spill

+0

Hãy khám phá ngay bây giờ tôi đã thêm rất nhiều thông tin mới. – 2trill2spill

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