Tản mạn về hai mô hình phát triển phần mềm là Waterfall và Agile

Tản mạn về hai mô hình phát triển phần mềm là Waterfall và Agile

Những mẩu tin ngắn hàng ngày dành cho bạn
  • Một phần mềm giúp chuyển đổi văn bản thành giọng nói do một lập trình viên người Việt làm ra - J2TEAM - Text to Speech (Free). Bạn có thể chuyển đổi hàng chục ngôn ngữ sang hàng chục giọng đọc tự nhiên khác nhau. Điều đặc biệt là nó miễn phí.

    Đánh giá sơ bộ thì chuyển đổi văn bản dài hoặc văn bản bằng tiếng Việt thuần thì rất tốt. Còn dính thêm các từ tiếng Anh thì nó đọc hơi buồn cười 😅

    » Xem thêm
  • Quá ghê ghớm, Codeium - vốn được biết đến như một đối thủ của Github Copilot, khi nó cho người dùng dùng miễn phí không giới hạn. Mới đây họ giới thiệu thêm Windsurf Editor - không chỉ còn là VSCode Extentions nữa mà là một trình Editor luôn - cạnh tranh trực tiếp với Cursor. Và điểm chính là nó... hoàn toàn miễn phí 🫣.

    » Xem thêm
  • Tin vui đầu này, Github Copilot đã chính thức có bản Free cho tất cả mọi người.

    Github Copilot là một trợ lý AI code cùng chúng ta, nó có thể tự động hoàn thành mã, trò chuyện hoặc sửa lỗi. Hiện đang hỗ trợ nhiều trình soạn thảo, IDE phổ biến như VSCode, JetBrains, XCode...

    Phiên bản miễn phí đang bị giới hạn 2000 Suggestions, và khoảng 50 requests đến tính năng Chat hàng tháng. Sau đó bạn có thể nâng cấp lên các phiên bản cao cấp hơn với giá từ 10$.

    Theo đánh giá của mình thì Copilot rất tốt và xứng đáng trong tầm giá, đang dùng hàng ngày 😄

    » Xem thêm

Vấn đề

Hồi còn đi học, trong môn "Phân tích thiết kế hệ thống thông tin" mà tôi được học có nhắc đến quy trình phát triển phần mềm theo mô hình thác nước (Waterfall). Tên gọi của nó khiến tôi liên tưởng đến hình ảnh một thác nước đang đổ ào ào từ trên xuống dưới rất mạnh mẽ, và dĩ nhiên dòng nước thì chỉ đổ được theo một chiều, hàm ý rằng đây là một quy trình tuần tự và khó có thể quay lui lại bước trước đó.

Nhưng sự thật là khi đi làm, tôi chưa thấy có một công ty nào áp dụng mô hình này để phát triển phần mềm cả. Hoặc là không có, hoặc là một cái tên khác: Agile.

Agile - Scrum là một cái tên mà tôi tin chắc rằng nhiều người biết hoặc đang áp dụng tại nơi làm việc. Một chu trình (sprints) chỉ mất khoảng 2 tuần để phát triển và hoàn thành một số tính năng để tung ra thị trường, đến với người sử dụng. Tư tưởng của Agile là làm sao đưa tính năng ra nhanh nhất cho khách hàng, từ đó khiến họ hài lòng và trả tiền để sử dụng sản phẩm.

Còn gì tuyệt vời hơn Agile, chúng ta quay vòng liên tục trong danh sách tính năng mới, "code" rồi "release"... thi thoảng là một chu trình sửa lỗi, cải thiện tính năng. Cuối mỗi sprint, chúng ta sẽ có một buổi "retrospective" để nhìn lại những gì đã và đang làm tốt hoặc chưa tốt, từ đó rút kinh nghiệm cho lần sau.

Thú thật, đối với một sinh viên mới ra trường lúc đó, Agile như là một phương pháp mà tôi cảm thấy tuyệt vời nhất. Người ta thường nói, con người thường sẽ có cảm xúc mãnh liệt với thứ đầu tiên họ tiếp xúc. Nghĩa là ngay từ đầu được tiếp xúc với Agile, cho dù sau đó được tiếp xúc với mô hình gì đi nữa, Agile vẫn có chỗ đứng đặc biệt trong lòng.

Đã có thời gian tôi đề cao Agile, sẵn sàng vùi dập các phương pháp khác như Waterfall trong các cuộc tranh luận. Rằng Waterfall là đã quá lạc hậu, không thể đáp ứng được nhu cầu phát triển phần mềm mạnh mẽ ngày nay.

Nhưng chỉ mới gần đây thôi, có lẽ tôi đã tích đủ cho mình "chứng cứ" để chỉ ra một sự thật: "Agile không phải là nhất" nếu như không muốn nói là nó quá tệ trong hầu hết trường hợp.

Vậy, tại sao?

Waterfall và Agile

Đầu tiên hãy nhắc lại một chút về khái niệm mô hình Waterfall.

Waterfall là một mô hình của quy trình phát triển phần mềm, trong đó quy trình phát triển trông giống như một dòng chảy, với các pha được thực hiện theo trật tự nghiêm ngặt và không có sự quay lui hay nhảy vượt pha là: phân tích yêu cầu, thiết kế, triển khai thực hiện, kiểm thử, liên kết và bảo trì.

Mô hình Waterfall

Trong hầu hết thời gian đi làm, phân tích yêu cầu luôn là giai đoạn mà tôi thấy là tốn nhiều thời gian nhất. Vì đó là nơi mà cần phải quyết định xem cần phải làm gì, chiến lược kết hợp với tầm nhìn, kế hoạch và cả những con số thống kê để đi đến tính năng cần phải làm...

Vì vậy, nó phải được thực hiện rất tỉ mỉ và thận trọng trước khi chuyển giao sang giai đoạn tiếp theo, bởi vì một khi đả chuyển thì khó có thể quay lại được. Khi đó bộ phận khác đã tiếp nhận yêu cầu và bắt đầu thiết kế hệ thống, giao diện ứng dụng/phần mềm... Vậy điều gì xảy ra nếu như ngay từ bước đầu tiên đã xuất hiện vấn đề bất thường?

Nếu sai sót là nhỏ, trong tầm kiểm soát, chỉ cần sửa lại câu từ hoặc bổ sung thêm một vài trường hợp không gây ảnh hưởng đến chức năng chính, mọi thứ có thể du di chấp nhận được. Ngược lại, giả sử bộ phận Design tiếp nhận yêu cầu và họ tìm ra một cơ số lỗ hổng nếu không khắc phục thì không thể tiếp tục được. Chu trình thác nước lúc này có thể bị đổ vỡ. Chúng ta không thể cứ mãi một vòng lặp phản hồi từ Requirements đến Design được, vì như thế các bước sau đó sẽ mãi mãi không bao giờ được tiếp tục.

Tôi tin rằng có thể có rất nhiều sai lầm giống như trên đã xảy ra trong quá khứ, cho nên đã đến lúc đội phát triển cần một phương pháp mới: Agile ra đời.

Phát triển phần mềm linh hoạt (Agile) là một phương thức thực hiện các dự án công nghệ phần mềm, phương thức này khuyến khích sự thay đổi khi phát triển dự án và đưa sản phẩm đến tay người dùng sao cho nhanh nhất.

Mô hình Agile

Chúng ta không còn thác nước, không còn từng bước như thác đổ và không sợ bị quay lui nữa. Tất cả giờ đây tập trung vào "đưa sản phẩm đến tay người dùng nhanh nhất".

Chà, nếu thế thì hơi chung chung. Làm thế nào để đưa sản phẩm đến tay người dùng nhanh nhất?

Scrum là một khung cộng tác nhóm linh hoạt thường được áp dụng trong Agile. Theo scrum, chúng ta sẽ có một vòng lặp có hạn thời gian để liên tục phát triển phần mềm, ví dụ là 2 tuần cho đến một tháng. Trong mỗi vòng lặp, phải có tính năng được hoàn thành và đưa đến tay người dùng, và khá nhiều quy tắc nữa nhưng tôi sẽ không nói thêm trong phạm vi bài viết này.

Tôi tin rằng Agile rất phổ biến, khi hỏi 10 người bạn làm trong cùng lĩnh vực, 9 người đều biết Agile, và công ty họ làm đều đang áp dụng phương pháp này, chỉ 1 người còn lại thì bảo "I'm free" - nghĩa là không theo một mô hình nào cả.

Ngày nay sự cạnh tranh trong các sản phẩm công nghệ là rất lớn. Chúng ta không thể chắc chắn ý tưởng của mình là duy nhất vì chỉ cần lơ là một chút, hàng tá sản phẩm có ý tưởng tương tự sẽ xuất hiện ngay sau đó mặc dù chưa từng khoe nó ở bất kỳ đâu.

Như vậy, chúng ta cần Agile để đẩy sản phẩm ra nhanh nhất cho người dùng, từ đó chiếm được thị trường và bước tiếp theo thì chỉ cần ung dung thêm tính năng mới.

Điều đó liệu có đúng? Nếu bạn đã từng ứng dụng Agile và nhận thấy mội vài hạn chế của nó mà chưa tiện nói ra ở đâu, thì hãy tạm dừng lại một chút để nghĩ về những bất cập đó và tiếp theo là...xem những điều đó có giống như tôi?

Dưới đây là những "bằng chứng" đã nhắc đến ở đầu bài để củng cố cho quan điểm "Agile không phải là nhất" trong suốt hơn 5 năm làm việc mà tôi đúc kết được.

  • Sự mập mờ và thiếu thông tin: Trong các chu trình mang tính liên tục và ngắn ngày, đòi hỏi mọi thứ phải nhanh. Từ khâu lên tài liệu cho đến các buổi "làm mịn" (Grooming) để phổ biến đến mọi người phát triển, thậm chí bạn còn không có thời gian để kịp nhìn thấy tài liệu của tính năng chuẩn bị làm.
  • Quá nhanh và không kịp suy nghĩ: Bạn không thể hình dung hết được những gì sắp làm có gây ảnh hưởng đến những gì đang có, chỉ khi bắt tay vào làm, nhiều vấn đề mới bắt đầu phát sinh.
  • Dễ khiến kiệt sức, chán nản: Liên tục xoay vòng trong các tính năng, đôi khi còn phải tiếp nhận yêu cầu hoàn toàn mới khiến cho chu trình hiện tại chậm trễ, hay thậm chí là bị sụp đổ. Vô định trong sự phát triển của sản phẩm nhiều khi khiến chúng ta nghi ngờ về chính sản phẩm mà chúng ta đang tạo ra.
  • ET và OT: Ngay khi nhận được danh sách tính năng, điều tiếp theo là các buổi lên kế hoạch chi tiết, phân chia nhiệm vụ và "estimate" thời gian hoàn thành. Đây không phải là một công việc dễ dàng gì, nó mất rất nhiều thời gian để "dự đoán" cho những điều còn chưa chắc chắn. Và nếu sắp đến ngày bàn giao còn chưa làm xong, làm thêm giờ sẽ là phương án cứu cánh cuối cùng để cho cả tuần làm việc không ngừng nghỉ.
  • Rơi vào cạm bẫy xây dựng: Đã bao giờ bạn tự hỏi danh sách tính năng lấy từ đâu ra chưa? Từ cấp trên, từ khách hàng, hay là từ bộ phận có nhiệm vụ "nghiên cứu sản phẩm"!?... Một sản phẩm mang lại giá trị cho người dùng khi nó giải quyết được vấn đề cho họ. Vì vậy, tính năng làm ra phải bám sát vào nhu cầu của khách hàng. Chúng ta cần phải tiếp xúc với khách hàng nhiều hơn để thấu hiểu được điều họ muốn, điều này thường mất nhiều thời gian và công sức. Vậy nên có một cách khác để nhanh hơn là tự thấu hiểu cho nỗi đau của người dùng, liên tục tung ra tính năng và kiểm tra xem mức độ sử dụng, nếu người dùng nhiều tức là thành công, và ngược lại.
  • Không hiểu sản phẩm: Hầu hết khi bắt đầu vào làm ở môi trường mới, tôi sẽ có một vài tuần để làm quen với những thứ mới, về văn hóa, về môi trường, về sản phẩm và cả những dòng code... nhưng rất ít khi được trình bày một bức tranh tổng quát về sản phẩm sắp sửa được tham gia. Phần lớn vì thời gian làm quen là có hạn, sau đó sẽ bị cuốn vào chu trình phát triển phần mềm không hồi kết.

Đến lúc này thì mới thấy Waterfall lại khắc phục được hầu hết nhược điểm trên.

Tất cả yêu cầu đã được làm rõ ngay từ bước đầu tiên, chúng ta có đầy đủ tài liệu để làm và không sợ bị thay đổi, vấn đề lúc này chỉ là bản kế hoạch về thời gian hoàn thành tất cả tính năng.

Khảo sát và đánh giá, tất cả đều nằm trong bước đầu tiên. Khảo sát giúp cho chúng ta tránh khỏi cạm bẫy xây dựng và có đủ cơ sở để tin rằng một khi tính năng được ra mắt, nó sẽ đem lại sự hài lòng cho rất nhiều người.

Khi tất cả yêu cầu được giao xuống, tất cả bộ phận đều nắm rõ thông tin sản phẩm, từ đó tạo ra động lực về một tương lai về sản phẩm sắp được làm ra và nó mang lại giá trị gì cho người dùng.

Tuy vậy, ưu điểm của Waterfall cũng là nhược điểm chí mạng khi nó không thể linh hoạt trong các khâu phát triển phần mềm. Hầu hết các công ty mà tôi từng tham gia phát triển đều đang trong quá trình Start-up, họ có chiến lược tạm thời và kế hoạch tung sản phẩm rất nhanh chóng để kịp cho việc chiếm lĩnh thị trường.

Nói đến đây không phải là để chỉ trích phương pháp nào cả, mà một khi đã nhìn ra những bất cập, chúng ta cần phải tìm ra cách để khắc chế lại nó.

Agile khuyến khích mọi người tương tác với nhau nhiều hơn để đẩy nhanh quá trình phát triển. Đừng quá quở trách đội nghiên cứu sản phẩm vì những yêu cầu chưa rõ ràng, tài liệu chậm trễ từ phía họ, vì đôi khi mọi người cũng đang quay cuồng trong danh sách tính năng cần được ưu tiên cho sự sống còn của sản phẩm. Thay vào đó chúng ta có thể chủ động hỏi những câu hỏi để làm sáng tỏ vấn đề, suy nghĩ hay đưa ra các trường hợp mà đội sản phẩm không lường được hết. Hãy nhớ một khi đã chọn Agile, chắc chắn việc làm thế nào để tung sản phẩm ra nhanh nhất cho người dùng mới là điều quan trọng.

Để tránh khỏi cạm bẫy xây dựng, hãy đặt nhiều câu hỏi liên quan đến sản phẩm trong giai đoạn Grooming hoặc Planing. Yêu cầu những con số biết nói và nếu có thể hãy đặt cả câu hỏi tại sao cần làm những tính năng sắp tới. Qua đó giúp cho mọi người có cái nhìn xa hơn về giá trị mà sản phẩm mang lại cho người dùng.

Cuối cùng là, luôn sẵn sàng tâm thế cho việc thay đổi liên tục.

Tổng kết

Tóm lại, bài viết này chỉ là sự nhìn nhận mang tính cá nhân về ưu và nhược điểm của 2 phương pháp phát triển phần mềm Waterfall và Agile. Trong khi Waterfall yêu cầu một nền tảng vững chắc thì Agile lại phù hợp với những thay đổi linh hoạt. Chúng phù hợp trong những môi trường làm việc khác nhau và qua bài viết này hy vọng bạn đọc không mắc phải những sai lầm như tôi khi đã quá đề cao một trong hai phương pháp từ đầu.

Cao cấp
Hello

Bí mật ngăn xếp của Blog

Là một lập trình viên, bạn có tò mò về bí mật công nghệ hay những khoản nợ kỹ thuật về trang blog này? Tất cả bí mật sẽ được bật mí ngay bài viết dưới đây. Còn chờ đợi gì nữa, hãy bấm vào ngay!

Là một lập trình viên, bạn có tò mò về bí mật công nghệ hay những khoản nợ kỹ thuật về trang blog này? Tất cả bí mật sẽ được bật mí ngay bài viết dưới đây. Còn chờ đợi gì nữa, hãy bấm vào ngay!

Xem tất cả

Đăng ký nhận thông báo bài viết mới

hoặc
* Bản tin tổng hợp được gửi mỗi 1-2 tuần, huỷ bất cứ lúc nào.
Author

Xin chào, tôi tên là Hoài - một anh Dev kể chuyện bằng cách viết ✍️ và làm sản phẩm 🚀. Với nhiều năm kinh nghiệm lập trình, tôi đã đóng góp một phần công sức cho nhiều sản phẩm mang lại giá trị cho người dùng tại nơi đang làm việc, cũng như cho chính bản thân. Sở thích của tôi là đọc, viết, nghiên cứu... Tôi tạo ra trang Blog này với sứ mệnh mang đến những bài viết chất lượng cho độc giả của 2coffee.dev.Hãy theo dõi tôi qua các kênh LinkedIn, Facebook, Instagram, Telegram.

Bạn thấy bài viết này có ích?
Không

Bình luận (8)

Nội dung bình luận...
Avatar
Ẩn danh1 năm trước
Nếu nhóm của bạn cảm thấy mệt mỏi với sự thay đổi và mông lung khi không có tài liệu, kế hoạch rõ ràng, có lẽ nhóm bạn nên thêm nó vào quy trình của mình, mình nghĩ dù bạn dùng gì thì cũng cần sự rõ ràng và thống nhất. Mình thấy cái này (https://designsprintkit.withgoogle.com/) có thể giúp ích cho nhóm của bạn. Nhân tiện vì comment được sắp xếp theo cái mới nhất, mình thấy đưa ô nhập lên trên thì sẽ tốt hơn
Trả lời
Avatar
Xuân Hoài Tống1 năm trước
Rất cảm ơn về sự gợi ý. Thực ra cuối các buổi retro, team cũng đã nêu ra rất nhiều lần rồi và... như bạn biết đấy, chỉ khắc phục được một phần... Một quy trình có vấn đề có lẽ cũng phụ thuộc vào nhiều yếu tố, cả khách quan, chủ quan và mình nghĩ nhiều nhất là yếu tố con người. Các công ty mình góp mặt hầu như đều bị một vấn đề như thế, thời gian đầu cảm thấy rất ức chế, chán... nhưng sau đó thì dần hiểu ra và mình không đổ lỗi cho ai cả mà cách tốt hơn là tìm cách để giải quyết những vấn đề đó.
Avatar
Ẩn danh1 năm trước
mình hiểu quan điểm của bạn, mình thấy mối phương pháp đều cho thấy sự phù hợp trong các phạm vi, quy mô khác nhau, không nhất thiết mình phải áp dụng chỉ một cho tất cả. Mình thấy dẫn chứng bạn đưa ra có chút thiên kiến về một phương pháp, những vấn đề bạn đề cập cho agile hoàn toàn vẫn gặp trong Waterfall, nên đã đề cập đề mọi người có cái nhìn đa chiều hơn. cảm ơn bạn về bài viết
Trả lời
Avatar
Xuân Hoài Tống1 năm trước
Vâng, chắc chắn là mỗi phương pháp luôn tồn tại ưu và nhược điểm, và chúng ta cần là chọn ra được giải pháp phù hợp. Mình cũng không phủ nhận mặt tích cực của Agile, tuy nhiên chúng ta hoàn toàn có thể cóp nhặt được những gì tốt trong mỗi cái để "biến" thành của riêng. Thực ra bài viết nói nhiều về Agile hơn bởi vì hầu hết thời gian làm việc của mình đều dựa trên phương pháp này, rồi từ đó rút ra được những thứ có trong bài viết. Tuy vậy đó không hoàn toàn là quan điểm của cá nhân, mình cũng có hỏi và quan sát đồng nghiệp trong cùng môi trường. Đa phần họ đều cảm thấy mệt mỏi với sự thay đổi và mông lung khi không có tài liệu, kế hoạch rõ ràng. Cảm ơn vì những góp ý của bạn để bài viết được hoàn thiện hơn.
Avatar
Ẩn danh1 năm trước
chiến lược thay đổi đâu có phụ thuộc vào phương pháp pháp triển. Khi bạn đang áp dụng Waterfall, nhu cầu người dùng hay chiến lược phát triển vấn có thể thay đổi mà, cái duy nhất khó thay đổi là watefall, lúc đó những gì bạn phân tích xong đã không còn phù hợp với thị trường, nó vấn đảm bảo bạn làm ra sản phẩm như bạn đã xác định, nhưng lúc đó, sản phẩm đó có còn đúng với nhu cầu thị trường. Giá trị của Agile là linh hoạt để thích ứng với sự thay đổi
Trả lời
Avatar
Ẩn danh1 năm trước
Các vấn đề trong bài dường như đến từ việc nhóm đã hiểu sai ý nghĩa của nhanh trong Agile, dẫn đến đã loại bỏ vài bước trong CTPT khi triển khai Agile. Nhanh chuyển giao tới người dùng chứ không phải nhanh là bỏ qua giá giai đoạn khi phát triển
Trả lời
Avatar
Xuân Hoài Tống1 năm trước
Qua đó, chúng ta thấy được ưu và nhược điểm của từng phương pháp. Một sprint có thể coi là một waterfall rất nhỏ? Có thể có...hoặc không. Đơn giản vì thời gian diễn ra của nó quá ngắn, chúng ta không có thời gian tổ chức tài liệu, kế hoạch khảo sát cục diện hay thực hiện một chu trình hoàn chỉnh như waterfall được, nơi mà các bước phải được ổn định nhất có thể. Nói như thế không phải là Agile không chỉn chu mà đó là sự linh hoạt, không cứng nhắc như waterfall. Sự dẻo dai của agile giúp cho đội phát triển phần mềm biến đổi linh hoạt tùy theo nhu cầu thị trường, đổi lại nó sẽ khiến cho các thành viên trong đội phải rèn luyện một tinh thần thích ứng cao độ.
Avatar
Xuân Hoài Tống1 năm trước
Mình hiểu ý của bạn đang muốn đề cập đến, dù là phương pháp phát triển phần mềm nào thì mục đích cuối cùng vẫn là đưa sản phẩm đến với người dùng cuối, chỉ có điều là quá trình đó diễn ra như thế nào. Theo như cách trình bày vấn đề của bạn, "Bản chất Agile vẫn dùng Waterfall để phát triển" thì mình cảm thấy không đồng quan điểm cho lắm. Hãy đi qua khái niệm của Agile, phương pháp này khuyến khích sự thay đổi và tương tác, hay nói cách khác là tùy cơ ứng biến, trong khi bạn đang thử nghiệm tính năng này thì vì một lý do nào đó mà thay đổi chiến lược thì hoàn toàn có thể tạm gác lại và làm cái mới. Waterfall thì ngược lại, mọi thứ đã được lên kế hoạch từ đầu rất chỉn chu và tất cả quá trình được diễn ra tuần tự mà không có bất kì sự xáo trộn nào cho đến khi sản phẩm được ra mắt.
Avatar
Ẩn danh1 năm trước
Vì khối lượng công việc và giá trị chuyển giao nhỏ hơn, nên thời gian phát hành tới người dùng sẽ nhanh hơn, nhanh có được phản hồi từ người dùng. đây mới là ý nghĩa của nhanh trong Agile. Thay vì chỉ có 1 CTPT tại một thời điểm như Waterfall truyền thống, Agile có thể làm nhiều CTPT cùng một thời điểm nên với một phần mềm lớn chúng ta có thể đưa nhiều team vào phát triển độc lập, cái mà Waterfall truyền thống không cho phép
Trả lời
Avatar
Ẩn danh1 năm trước
Cả Waterfall truyền thống vs Agile hay Scrum đều thực hiện các CTPT, chúng chỉ khác nhau về khối lượng công việc và giá trị chuyển giao tới khách hàng.
Trả lời
Avatar
Ẩn danh1 năm trước
Agile và Scrum: với khối lượng tính năng đồ sộ xác định được, chúng ta xác định một lượng tối thiểu các tính năng cần để có thể phát hành (MVP). Sau đó cứ mối Sprint chúng các xác định vài tính năng rồi thực hiện 1 CTPT lên đó.
Trả lời
Avatar
Ẩn danh1 năm trước
Bản chất Agile vẫn dùng Waterfall để phát triển, chỉ khác nhau về phạm vi, giá trị chuyển giao tới người dùng. Chu trình phát triển( CTPT - các bước chính ): Phân tích thị trường, xác định yêu cầu - thiết kế, phát triển - kiểm thử, phát hành Waterfall truyền thống: chúng ta xác định sản phẩm cần làm và thực hiện chỉ 1 CTPT. Sau đó phần mềm thay đổi, chúng ta tổng hợp lại và thực hiện 1 CTPT mới trong 1 khoảng thời gian (thường theo năm)
Trả lời