Một cái nhìn trái ngược về sự bất biến
TL / DR: Tính không thay đổi là xu hướng thời trang hơn là sự cần thiết trong JavaScript. Nếu bạn đang sử dụng React, nó sẽ cung cấp một cách giải quyết gọn gàng cho một số lựa chọn thiết kế khó hiểu trong quản lý nhà nước. Tuy nhiên, trong hầu hết các tình huống khác, nó sẽ không thêm đủ giá trị so với độ phức tạp mà nó giới thiệu, phục vụ nhiều hơn để đệm một bản lý lịch hơn là để đáp ứng nhu cầu thực tế của khách hàng.
Câu trả lời dài: đọc bên dưới.
Tại sao tính bất biến rất quan trọng (hoặc cần thiết) trong javascript?
Vâng, tôi rất vui vì bạn đã hỏi!
Cách đây một thời gian, một anh chàng rất tài năng tên là Dan Abramov đã viết một thư viện quản lý nhà nước javascript có tên Redux , sử dụng các hàm thuần túy và bất biến. Ông cũng thực hiện một số video thực sự thú vị khiến ý tưởng thực sự dễ hiểu (và bán).
Thời điểm là hoàn hảo. Sự mới lạ của Angular đang mờ dần và thế giới JavaScript đã sẵn sàng khắc phục điều mới nhất có mức độ tuyệt vời và thư viện này không chỉ đổi mới mà còn hoàn hảo với React đang được bán bởi một cường quốc khác ở Thung lũng Silicon .
Đáng buồn thay, có thể là thời trang quy tắc trong thế giới của JavaScript. Bây giờ Abramov đang được ca ngợi như một vị á thần và tất cả chúng ta chỉ là những người phàm trần phải tự chịu đựng Đạo bất biến ... Điều đó có ý nghĩa hay không.
Điều gì là sai trong việc đột biến các đối tượng?
Không có gì!
Trong thực tế, các lập trình viên đã và đang biến đổi các đối tượng trong chừng mực ... miễn là có các đối tượng bị đột biến. Hơn 50 năm phát triển ứng dụng nói cách khác.
Và tại sao lại phức tạp hóa mọi thứ? Khi bạn có đối tượng cat
và nó chết, bạn có thực sự cần một giây cat
để theo dõi sự thay đổi không? Hầu hết mọi người sẽ chỉ nói cat.isDead = true
và được thực hiện với nó.
Không (biến đổi đối tượng) làm cho mọi thứ đơn giản?
ĐÚNG! .. Tất nhiên là thế!
Đặc biệt trong JavaScript, trong thực tế là hữu ích nhất được sử dụng để hiển thị chế độ xem của một số trạng thái được duy trì ở nơi khác (như trong cơ sở dữ liệu).
Điều gì xảy ra nếu tôi có một đối tượng Tin tức mới phải được cập nhật? ... Làm thế nào để tôi đạt được trong trường hợp này? Xóa cửa hàng & tạo lại nó? Không thêm một đối tượng vào mảng là một hoạt động ít tốn kém hơn?
Chà, bạn có thể đi theo cách tiếp cận truyền thống và cập nhật News
đối tượng, do đó biểu diễn trong bộ nhớ của đối tượng đó sẽ thay đổi (và chế độ xem được hiển thị cho người dùng, hoặc người ta sẽ hy vọng) ...
Hay cách khác...
Bạn có thể thử cách tiếp cận FP / Bất biến gợi cảm và thêm các thay đổi của bạn vào News
đối tượng vào một mảng theo dõi mọi thay đổi lịch sử để sau đó bạn có thể lặp lại qua mảng và tìm ra cách biểu diễn trạng thái chính xác (phew!).
Tôi đang cố gắng học những gì ngay tại đây. Xin hãy soi sáng cho tôi :)
Thời trang đến và đi bạn thân. Có nhiều cách để da mèo.
Tôi xin lỗi vì bạn phải chịu sự nhầm lẫn của một tập hợp các mô hình lập trình liên tục thay đổi. Nhưng này, CHÀO MỪNG BẠN ĐẾN CÂU LẠC BỘ !!
Bây giờ có một vài điểm quan trọng cần nhớ liên quan đến Tính bất biến, và bạn sẽ bị những thứ này ném vào bạn với cường độ sốt mà chỉ có sự ngây thơ mới có thể tập hợp được.
1) Tính không thay đổi là tuyệt vời để tránh các điều kiện chủng tộc trong môi trường đa luồng .
Các môi trường đa luồng (như C ++, Java và C #) có tội trong việc thực hành khóa các đối tượng khi có nhiều hơn một luồng muốn thay đổi chúng. Điều này là xấu cho hiệu suất, nhưng tốt hơn so với thay thế tham nhũng dữ liệu. Nhưng vẫn không tốt bằng làm cho mọi thứ trở nên bất biến (Chúa khen ngợi Haskell!).
NHƯNG! Trong JavaScript, bạn luôn hoạt động trên một luồng . Ngay cả nhân viên web (mỗi người chạy trong một bối cảnh riêng biệt ). Vì vậy, vì bạn không thể có một điều kiện cuộc đua liên quan đến chủ đề trong bối cảnh thực thi của mình (tất cả các biến và đóng toàn cầu đáng yêu đó), điểm chính có lợi cho tính không thay đổi sẽ xuất hiện ngoài cửa sổ.
(Có nói rằng, có là một lợi thế để sử dụng chức năng thuần túy trong công nhân trang web, mà là bạn sẽ không có kỳ vọng về loay hoay với các đối tượng trên chủ đề chính.)
2) Tính không thay đổi có thể (bằng cách nào đó) tránh các điều kiện chủng tộc trong trạng thái ứng dụng của bạn.
Và đây là mấu chốt thực sự của vấn đề, hầu hết các nhà phát triển (React) sẽ nói với bạn rằng Tính bất biến và FP bằng cách nào đó có thể thực hiện phép thuật này cho phép trạng thái ứng dụng của bạn trở nên dễ đoán.
Tất nhiên, điều này không có nghĩa là bạn có thể tránh các điều kiện chạy đua trong cơ sở dữ liệu , để loại bỏ điều đó, bạn phải điều phối tất cả người dùng trong tất cả các trình duyệt và vì thế bạn cần một công nghệ đẩy lùi như WebSockets ( nhiều hơn về điều này dưới đây) sẽ phát sóng thay đổi cho tất cả mọi người chạy ứng dụng.
Điều đó cũng không có nghĩa là có một số vấn đề cố hữu trong JavaScript khi trạng thái ứng dụng của bạn cần tính bất biến để có thể dự đoán được, bất kỳ nhà phát triển nào đã mã hóa các ứng dụng front-end trước khi React nói với bạn điều này.
Yêu cầu khá khó hiểu này chỉ đơn giản có nghĩa là với React, trạng thái ứng dụng của bạn sẽ trở nên dễ bị điều kiện chủng tộc hơn , nhưng sự bất biến đó cho phép bạn loại bỏ nỗi đau đó. Tại sao? Bởi vì React rất đặc biệt .. nó được thiết kế như một thư viện kết xuất được tối ưu hóa cao với quản lý trạng thái mạch lạc chiếm vị trí thứ hai và do đó trạng thái thành phần được quản lý thông qua chuỗi sự kiện không đồng bộ (còn gọi là "liên kết dữ liệu một chiều") mà bạn không kiểm soát được hơn và dựa vào bạn nhớ không biến đổi trạng thái trực tiếp ...
Với bối cảnh này, thật dễ dàng để thấy rằng nhu cầu về tính bất biến ít liên quan đến JavaScript và rất nhiều điều phải làm với điều kiện chủng tộc trong React: nếu có một loạt các thay đổi phụ thuộc lẫn nhau trong ứng dụng của bạn và không có cách nào dễ dàng để tìm ra điều gì trạng thái của bạn hiện đang ở, bạn sẽ bị lẫn lộn , và do đó nó hoàn toàn hợp lý để sử dụng tính bất biến để theo dõi mọi thay đổi lịch sử .
3) Điều kiện chủng tộc là xấu về thể loại.
Chà, chúng có thể là nếu bạn đang sử dụng React. Nhưng chúng rất hiếm nếu bạn chọn một khung khác.
Bên cạnh đó, thông thường bạn có những vấn đề lớn hơn rất nhiều để đối phó với các vấn đề về vấn đề như địa ngục phụ thuộc. Giống như một cơ sở mã cồng kềnh. Giống như CSS của bạn không được tải. Giống như một quá trình xây dựng chậm hoặc bị mắc kẹt vào một back-end nguyên khối làm cho việc lặp lại gần như không thể. Giống như các nhà phát triển thiếu kinh nghiệm không hiểu chuyện gì đang xảy ra và làm cho mọi thứ trở nên lộn xộn.
Bạn biết. Thực tế. Nhưng này, ai quan tâm đến điều đó?
4) Tính không thay đổi sử dụng các loại tham chiếu để giảm tác động hiệu suất của việc theo dõi mọi thay đổi trạng thái.
Bởi vì nghiêm túc, nếu bạn định sao chép mọi thứ mỗi khi trạng thái của bạn thay đổi, tốt hơn bạn nên chắc chắn rằng bạn thông minh về nó.
5) Tính không thay đổi cho phép bạn sử dụng công cụ UNDO .
Bởi vì er .. đây là tính năng số một mà người quản lý dự án của bạn sẽ yêu cầu, phải không?
6) Trạng thái bất biến có rất nhiều tiềm năng thú vị khi kết hợp với WebSockets
Cuối cùng nhưng không kém phần quan trọng, sự tích lũy của các trạng thái deltas tạo nên một trường hợp khá hấp dẫn kết hợp với WebSockets, cho phép tiêu thụ trạng thái dễ dàng như một dòng chảy của các sự kiện bất biến ...
Một khi đồng xu rơi vào khái niệm này (trạng thái là một dòng sự kiện - chứ không phải là một bộ hồ sơ thô sơ đại diện cho quan điểm mới nhất), thế giới bất biến trở thành một nơi kỳ diệu để sinh sống. Một vùng đất của sự ngạc nhiên có nguồn gốc và khả năng vượt qua chính thời gian . Và khi thực hiện quyền này chắc chắn có thể làm cho thời gian thực các ứng dụng EASI er để thực hiện, bạn chỉ cần phát sóng dòng chảy của sự kiện để tất cả mọi người quan tâm để họ có thể xây dựng đại diện của mình trong hiện tại và viết lại những thay đổi của mình vào dòng chảy xã.
Nhưng đến một lúc nào đó bạn thức dậy và nhận ra rằng tất cả những điều kỳ diệu và ma thuật đó không đến miễn phí. Không giống như các đồng nghiệp háo hức, các bên liên quan của bạn (yea, những người trả tiền cho bạn) quan tâm rất ít đến triết lý hoặc thời trang và rất nhiều về số tiền họ trả để xây dựng một sản phẩm họ có thể bán. Và điểm mấu chốt là việc viết mã bất biến khó hơn và dễ phá mã hơn, cộng với việc có một mặt trước bất biến nếu bạn không có back-end để hỗ trợ. Khi nào (và nếu!) Cuối cùng bạn thuyết phục được các bên liên quan của mình rằng bạn nên xuất bản và tiêu thụ các sự kiện thông qua một công nghệ đẩy như WebSockets, bạn sẽ tìm ra sự đau đớn khi mở rộng quy mô sản xuất .
Bây giờ cho một số lời khuyên, bạn nên chọn chấp nhận nó.
Một lựa chọn để viết JavaScript bằng cách sử dụng FP / Tính không thay đổi cũng là một lựa chọn để làm cho cơ sở mã ứng dụng của bạn lớn hơn, phức tạp hơn và khó quản lý hơn. Tôi chắc chắn sẽ tranh luận về việc giới hạn cách tiếp cận này với các bộ giảm Redux của bạn, trừ khi bạn biết bạn đang làm gì ... Và NẾU bạn sẽ tiếp tục và sử dụng tính bất biến, sau đó áp dụng trạng thái bất biến cho toàn bộ ngăn xếp ứng dụng của bạn , và không chỉ phía khách hàng, vì bạn đang thiếu giá trị thực của nó.
Bây giờ, nếu bạn đủ may mắn để có thể đưa ra lựa chọn trong công việc của mình, thì hãy thử và sử dụng trí tuệ của bạn (hoặc không) và làm những gì đúng bởi người trả tiền cho bạn . Bạn có thể dựa trên kinh nghiệm của bạn, về ruột của bạn hoặc những gì đang diễn ra xung quanh bạn (phải thừa nhận rằng nếu mọi người đang sử dụng React / Redux thì có một lập luận hợp lệ rằng việc tìm tài nguyên để tiếp tục công việc của bạn sẽ dễ dàng hơn) .. Hoặc, bạn có thể thử các phương pháp tiếp tục phát triển theo hướng hoặc phát triển theo hướng Hype . Họ có thể là nhiều thứ của bạn.
Nói tóm lại, điều cần nói về sự bất biến là nó sẽ giúp bạn trở nên thời trang hơn với các đồng nghiệp của mình, ít nhất là cho đến khi cơn sốt tiếp theo xuất hiện, đến lúc đó bạn sẽ vui mừng bước tiếp.
Bây giờ sau phiên tự trị liệu này, tôi muốn chỉ ra rằng tôi đã thêm bài viết này dưới dạng một bài viết trong blog của mình => Tính bất biến trong JavaScript: Một quan điểm trái ngược . Vui lòng trả lời trong đó nếu bạn có cảm xúc mạnh mẽ mà bạn muốn rời khỏi ngực của bạn quá;).