Hãy để tôi hỏi bạn một câu hỏi hoàn toàn nghiêm túc: Theo quan điểm của bạn, sự khác biệt giữa "dữ liệu" và "mã" là gì?
Khi tôi nghe từ "dữ liệu", tôi nghĩ "trạng thái". Dữ liệu, theo định nghĩa, là thứ mà chính ứng dụng được thiết kế để quản lý, và do đó, chính là thứ mà ứng dụng không bao giờ có thể biết về thời gian biên dịch. Không thể mã hóa dữ liệu cứng, vì ngay khi bạn mã hóa cứng, nó sẽ trở thành hành vi - không phải dữ liệu.
Loại dữ liệu khác nhau tùy theo ứng dụng; một hệ thống hóa đơn thương mại có thể lưu trữ thông tin khách hàng và đặt hàng trong cơ sở dữ liệu SQL và chương trình đồ họa vector có thể lưu trữ dữ liệu hình học và siêu dữ liệu trong tệp nhị phân. Trong cả hai trường hợp này và mọi thứ ở giữa, có một sự tách biệt rõ ràng và không thể phá vỡ giữa mã và dữ liệu. Dữ liệu thuộc về người dùng , không phải lập trình viên, vì vậy nó không bao giờ có thể được mã hóa cứng.
Những gì bạn dường như đang nói đến là, sử dụng mô tả chính xác nhất về mặt kỹ thuật có sẵn cho từ vựng hiện tại của tôi: thông tin chi phối hành vi chương trình không được viết bằng ngôn ngữ lập trình chính được sử dụng để phát triển phần lớn ứng dụng.
Ngay cả định nghĩa này, ít mơ hồ hơn đáng kể so với chỉ từ "dữ liệu", có một vài vấn đề. Ví dụ, điều gì sẽ xảy ra nếu các phần quan trọng của chương trình được viết bằng các ngôn ngữ khác nhau? Cá nhân tôi đã làm việc trên một số dự án khoảng 50% C # và 50% JavaScript. Mã JavaScript có phải là "dữ liệu" không? Hầu hết mọi người sẽ nói không. Còn HTML thì sao, đó là "dữ liệu"? Hầu hết mọi người vẫn sẽ nói không.
Còn CSS thì sao? Đó là dữ liệu hay mã? Nếu chúng ta nghĩ rằng mã là thứ gì đó kiểm soát hành vi của chương trình, thì CSS không thực sự là mã, bởi vì nó chỉ (tốt, chủ yếu) ảnh hưởng đến ngoại hình chứ không phải hành vi. Nhưng nó cũng không thực sự là dữ liệu; Người dùng không sở hữu nó, ứng dụng thậm chí không thực sự sở hữu nó. Nó tương đương với mã cho một nhà thiết kế UI. Đó là mã- giống như , nhưng không hoàn toàn là mã.
Tôi có thể gọi CSS là một loại cấu hình, nhưng một định nghĩa thực tế hơn là nó chỉ đơn giản là mã trong một ngôn ngữ dành riêng cho tên miền . Đó là những gì XML, YAML và "tệp định dạng" khác của bạn thường đại diện. Và lý do chúng tôi sử dụng một ngôn ngữ dành riêng cho tên miền là vì nói chung, nó đồng thời ngắn gọn và biểu cảm hơn trong miền cụ thể của nó hơn là mã hóa thông tin tương tự trong ngôn ngữ lập trình đa năng như C hoặc C # hoặc Java.
Bạn có nhận ra định dạng sau?
{
name: 'Jane Doe',
age: 27,
interests: ['cats', 'shoes']
}
Tôi chắc chắn rằng hầu hết mọi người làm; đó là JSON . Và đây là điều thú vị về JSON: Trong JavaScript, nó rõ ràng là mã và trong mọi ngôn ngữ khác, nó rõ ràng dữ liệu được định dạng . Hầu như mọi ngôn ngữ lập trình chính thống đều có ít nhất một thư viện để "phân tích cú pháp" JSON.
Nếu chúng ta sử dụng chính cú pháp tương tự bên trong một hàm trong tệp JavaScript, thì nó không thể là gì khác ngoài mã. Tuy nhiên, nếu chúng ta lấy JSON đó, chuyển nó vào một .json
tệp và phân tích nó trong một ứng dụng Java, đột nhiên nó là "dữ liệu". Điều đó thực sự có ý nghĩa?
Tôi lập luận rằng "dữ liệu" hoặc "cấu hình" hoặc "mã" là cố hữu với những gì được mô tả, không phải là cách nó được mô tả.
Nếu chương trình của bạn cần một từ điển 1 triệu từ để tạo một cụm mật khẩu ngẫu nhiên, bạn có muốn viết mã như thế này không:
var words = new List<string>();
words.Add("aa");
words.Add("aah");
words.Add("ahhed");
// snip 172836 more lines
words.Add("zyzzyva");
words.Add("zyzzyvas");
Hoặc bạn sẽ chuyển tất cả những từ đó vào một tệp văn bản được phân cách bằng dòng và bảo chương trình của bạn đọc từ đó? Sẽ không có vấn đề gì nếu danh sách từ không bao giờ thay đổi, đó không phải là câu hỏi về việc bạn mã hóa cứng hay mã hóa mềm (mà nhiều người coi là một mô hình chống khi áp dụng không phù hợp), đó đơn giản chỉ là một câu hỏi về định dạng nào là hiệu quả nhất và làm cho nó dễ dàng nhất để mô tả "công cụ", bất kể "công cụ" là gì. Nó khá là không liên quan cho dù bạn gọi nó là mã hay dữ liệu; đó là thông tin mà chương trình của bạn yêu cầu để chạy và định dạng tệp phẳng là cách thuận tiện nhất để quản lý và duy trì chương trình.
Giả sử bạn tuân theo các thực tiễn phù hợp, dù sao tất cả những thứ này sẽ đi vào kiểm soát nguồn, vì vậy bạn cũng có thể gọi nó là mã, chỉ là mã theo một định dạng khác và có lẽ rất tối giản. Hoặc bạn có thể gọi nó là cấu hình, nhưng điều duy nhất thực sự phân biệt mã với cấu hình là liệu bạn có ghi lại nó hay không và cho người dùng cuối biết cách thay đổi nó. Có lẽ bạn có thể phát minh ra một số đối số không có thật về cấu hình được diễn giải vào lúc khởi động hoặc thời gian chạy chứ không phải lúc biên dịch, nhưng sau đó bạn sẽ bắt đầu mô tả một số ngôn ngữ được gõ động và gần như chắc chắn bất cứ thứ gì có công cụ kịch bản được nhúng bên trong nó (ví dụ hầu hết các trò chơi). Mã và cấu hình là bất cứ điều gì bạn quyết định gắn nhãn chúng là, không hơn, không kém.
Bây giờ, có là một nguy hiểm cho externalizing thông tin đó không phải là thực sự an toàn để sửa đổi (xem liên kết "mềm mã hóa" ở trên). Nếu bạn bên ngoài mảng nguyên âm của mình trong một tệp cấu hình và ghi lại nó dưới dạng tệp cấu hình cho người dùng cuối của bạn, thì bạn đang cung cấp cho họ một cách gần như hoàn hảo để phá vỡ ứng dụng của bạn, ví dụ như bằng cách đặt "q" làm nguyên âm. Nhưng đó không phải là vấn đề cơ bản với "phân tách mã và dữ liệu", nó đơn giản là ý nghĩa thiết kế tồi.
Những gì tôi nói với các nhà phát triển cơ sở là họ phải luôn luôn đặt bên ngoài các cài đặt mà họ mong muốn thay đổi theo từng môi trường. Điều đó bao gồm những thứ như chuỗi kết nối, tên người dùng, khóa API, đường dẫn thư mục, v.v. Chúng có thể giống nhau trên hộp dev của bạn và trong sản xuất, nhưng có lẽ là không, và các sysadins sẽ quyết định cách chúng muốn nó trông như thế nào trong sản xuất, chứ không phải dev. Vì vậy, bạn cần một cách để áp dụng một nhóm cài đặt trên một số máy và các cài đặt khác được áp dụng trên các máy khác - ergo, tệp cấu hình bên ngoài (hoặc cài đặt trong cơ sở dữ liệu, v.v.)
Nhưng tôi nhấn mạnh rằng chỉ đơn giản là đưa một số "dữ liệu" vào một "tệp" không giống như việc đưa nó vào cấu hình. Đặt một từ điển các từ vào một tệp văn bản không có nghĩa là bạn muốn người dùng (hoặc CNTT) thay đổi nó, đó chỉ là một cách giúp các nhà phát triển dễ hiểu hơn những gì đang xảy ra và, nếu cần, hãy làm thỉnh thoảng thay đổi. Tương tự như vậy, việc đưa thông tin tương tự vào bảng cơ sở dữ liệu không nhất thiết được tính là ngoại ứng hóa hành vi, nếu bảng chỉ đọc và / hoặc DBA được hướng dẫn không bao giờ bắt vít với nó. Cấu hình ngụ ý rằng dữ liệu có thể thay đổi, nhưng trong thực tế được xác định bởi quy trình và trách nhiệm thay vì lựa chọn định dạng.
Vì vậy, để tóm tắt:
"Mã" không phải là một thuật ngữ được định nghĩa cứng nhắc. Nếu bạn mở rộng định nghĩa của mình để bao gồm các ngôn ngữ dành riêng cho tên miền và bất kỳ ngôn ngữ nào khác ảnh hưởng đến hành vi, rất nhiều ma sát rõ ràng này sẽ biến mất và tất cả sẽ có ý nghĩa. Bạn có thể có "mã" DSL không được biên dịch trong một tệp phẳng.
"Dữ liệu" ngụ ý thông tin thuộc sở hữu của người dùng hoặc ít nhất là một người nào đó không phải là nhà phát triển và thường không có sẵn tại thời điểm thiết kế. Nó không thể được mã hóa cứng ngay cả khi bạn muốn làm như vậy. Ngoại trừ có thể có mã tự sửa đổi , việc phân tách giữa mã và dữ liệu là vấn đề định nghĩa, không phải là sở thích cá nhân.
"Mã hóa mềm" có thể là một thực tiễn khủng khiếp khi được áp dụng quá mức, nhưng không phải mọi trường hợp ngoại hóa nhất thiết phải cấu thành mã hóa mềm, và nhiều trường hợp lưu trữ thông tin trong "tệp phẳng" không nhất thiết là một nỗ lực bên ngoài.
Cấu hình là một loại đặc biệt của phần mềm mã hóa đó là cần thiết vì sự hiểu biết rằng các ứng dụng có thể cần phải chạy trong môi trường khác nhau. Việc triển khai một tệp cấu hình riêng cùng với ứng dụng là công việc ít hơn nhiều (và ít nguy hiểm hơn) so với việc triển khai một phiên bản mã khác nhau cho mọi môi trường. Vì vậy, một số loại mã hóa mềm thực sự hữu ích.