Logic nghiệp vụ trong MVC [đã đóng]


182

Tôi có 2 câu hỏi:

Q1. Chính xác thì "logic kinh doanh" nằm ở đâu trong mẫu MVC? Tôi bối rối giữa Model và Trình điều khiển.

Quý 2 "Logic kinh doanh" có giống như "quy tắc kinh doanh" không? Nếu không, sự khác biệt là gì?

Sẽ thật tuyệt nếu bạn có thể giải thích bằng một ví dụ nhỏ.

Câu trả lời:


172

Quy tắc kinh doanh đi trong mô hình.

Giả sử bạn đang hiển thị email cho danh sách gửi thư. Người dùng nhấp vào nút "xóa" bên cạnh một trong các email, bộ điều khiển thông báo cho mô hình để xóa mục N, sau đó thông báo cho chế độ xem mô hình đã thay đổi.

Có lẽ không bao giờ nên xóa email của quản trị viên khỏi danh sách. Đó là một quy tắc kinh doanh, kiến ​​thức đó thuộc về mô hình. Khung nhìn cuối cùng có thể đại diện cho quy tắc này bằng cách nào đó - có lẽ mô hình hiển thị thuộc tính "IsDeletable" là chức năng của quy tắc kinh doanh, do đó nút xóa trong chế độ xem bị vô hiệu hóa cho một số mục nhất định - nhưng bản thân quy tắc không chứa Theo quan điểm.

Mô hình cuối cùng là người gác cổng cho dữ liệu của bạn. Bạn sẽ có thể kiểm tra logic kinh doanh của mình mà không cần chạm vào UI.


5
Cảm ơn ví dụ. Đối với mục nhập email của quản trị viên (kiểm soát xem nó có thể bị xóa hay không), chúng ta có thể không kiểm soát việc sử dụng bộ điều khiển của mình không?
hmthur

2
@mud điều gì xảy ra nếu chúng ta chia mô hình của mình thành hai lớp nữa, tức là lớp dịch vụ và kho lưu trữ ... lớp dịch vụ chịu trách nhiệm cho logic nghiệp vụ và kho lưu trữ chịu trách nhiệm cho lớp dữ liệu ...?
Rồng

3
@PeterMatisko "Các mô hình chỉ nên mang dữ liệu." Bạn không hiểu M nghĩa là gì trong "MVC". V là hoàn toàn trình bày. C là keo giữa trình bày và mô hình. (Trên thực tế, "VC" thường được coi là lớp trình bày và các biến thể phổ biến của MVC như MVVM - Model View Viewmodel - làm cho điều đó rõ ràng hơn.) M là mọi thứ khác : tất cả dữ liệu logic của ứng dụng của bạn. Bạn có thể tách riêng dữ liệu và logic nghiệp vụ trong lớp này và bạn có thể gọi phần dữ liệu của lớp này là "mô hình" của mình, nhưng đó không phải là "M" trong "MVC" đang đề cập đến.
Bùn

1
@PeterMatisko "trong laravel, mọi người sau đó ném mọi thứ vào bộ điều khiển hoặc mô hình. Kiến trúc xấu tệ." Xấu thế nào ? Hãy cụ thể. "V" có nghĩa là "xem". Tất cả mọi thứ không phải là một chế độ xem nhất thiết phải có trong "M" hoặc "C". "MVC là chưa đủ, nó không nói rõ ràng về logic kinh doanh và nơi để đặt nó" Chắc chắn là có. "M" là mô hình ứng dụng của bạn, là dữ liệu của bạn, logic kinh doanh xung quanh nó và mọi thứ và mọi thứ khác không được trình bày. "V" và "C" là lớp trình bày, đầu vào và đầu ra của người dùng.
Bùn

2
@Mud Vấn đề là, laravel gọi 'Model' chỉ là người mang dữ liệu. Khi các hướng dẫn nói rằng Laravel sử dụng MVC và sau đó bạn thấy rằng 'Mô hình' có một mục đích rất cụ thể, thì cuối cùng bạn không biết phải đặt logic kinh doanh ở đâu. Và nơi hợp lý duy nhất là bộ điều khiển, không tốt. Tôi không làm điều này, tôi chỉ nhận xét về các dự án laravel điển hình (và hướng dẫn) mà tôi thường thấy.
Peter Matisko

189

Nắm bắt tất cả:
Tôi tin rằng bạn đang trộn lẫn mô hình MVC và các nguyên tắc thiết kế dựa trên n tầng.

Sử dụng một cách tiếp cận MVC không có nghĩa là bạn không nên lớp ứng dụng của mình.
Nó có thể hữu ích nếu bạn thấy MVC giống như một phần mở rộng của lớp trình bày.

Nếu bạn đặt mã không trình bày bên trong mẫu MVC, bạn có thể sẽ sớm có một thiết kế phức tạp.
Do đó tôi sẽ đề nghị bạn đưa logic kinh doanh của bạn vào một lớp kinh doanh riêng.

Chỉ cần nhìn vào điều này: bài viết Wikipedia về kiến ​​trúc đa nhiệm

Nó nói:

Ngày nay, MVC và mô hình xem-trình bày mô hình tương tự (MVP) là các mẫu thiết kế Tách biệt mối quan tâm áp dụng riêng cho lớp trình bày của một hệ thống lớn hơn.

Dù sao ... khi nói về một ứng dụng web doanh nghiệp, các cuộc gọi từ UI đến lớp logic nghiệp vụ nên được đặt bên trong bộ điều khiển (thuyết trình).

Đó là bởi vì bộ điều khiển thực sự xử lý các cuộc gọi đến một tài nguyên cụ thể, truy vấn dữ liệu bằng cách thực hiện các cuộc gọi đến logic nghiệp vụ và liên kết dữ liệu (mô hình) với chế độ xem phù hợp.

Mud nói với bạn rằng các quy tắc kinh doanh đi vào mô hình.
Điều đó cũng đúng, nhưng anh ta đã trộn lẫn mô hình (trình bày) ('M' trong MVC) và mô hình lớp dữ liệu của một thiết kế ứng dụng dựa trên tầng.
Vì vậy, nó là hợp lệ để đặt các quy tắc kinh doanh liên quan đến cơ sở dữ liệu của bạn trong mô hình (lớp dữ liệu) của ứng dụng của bạn.
Nhưng bạn không nên đặt chúng trong mô hình của lớp trình bày có cấu trúc MVC vì điều này chỉ áp dụng cho một giao diện người dùng cụ thể.

Kỹ thuật này độc lập với việc bạn sử dụng thiết kế theo hướng tên miền hay cách tiếp cận dựa trên tập lệnh giao dịch.

Hãy để tôi hình dung điều đó cho bạn:


Lớp trình bày: Model - View - Controller


Lớp nghiệp vụ: Logic miền - Logic ứng dụng


Lớp dữ liệu: Kho dữ liệu - Lớp truy cập dữ liệu


Mô hình mà bạn thấy ở trên có nghĩa là bạn có một ứng dụng sử dụng MVC, DDD và lớp dữ liệu độc lập với cơ sở dữ liệu.
Đây là một cách tiếp cận phổ biến để thiết kế một ứng dụng web doanh nghiệp lớn hơn.

Nhưng bạn cũng có thể thu nhỏ nó xuống để sử dụng lớp nghiệp vụ không DDD đơn giản (lớp nghiệp vụ không có logic miền) và lớp dữ liệu đơn giản ghi trực tiếp vào cơ sở dữ liệu cụ thể.
Bạn thậm chí có thể bỏ toàn bộ lớp dữ liệu và truy cập cơ sở dữ liệu trực tiếp từ lớp nghiệp vụ, mặc dù tôi không khuyến nghị điều đó.

Đó là mẹo ... Tôi hy vọng điều này sẽ giúp ...

[Lưu ý:] Bạn cũng nên biết rằng thực tế là ngày nay không chỉ có một "mô hình" trong một ứng dụng. Thông thường, mỗi lớp của một ứng dụng có mô hình riêng. Mô hình của lớp trình bày là khung nhìn cụ thể nhưng thường độc lập với các điều khiển được sử dụng. Tầng nghiệp vụ cũng có thể có một mô hình, được gọi là "mô hình miền". Đây thường là trường hợp khi bạn quyết định thực hiện một cách tiếp cận dựa trên tên miền. "Mô hình miền" này chứa dữ liệu cũng như logic nghiệp vụ (logic chính của chương trình của bạn) và thường độc lập với lớp trình bày. Lớp trình bày thường gọi lớp nghiệp vụ trên một "sự kiện" nhất định (nhấn nút, v.v.) để đọc dữ liệu từ hoặc ghi dữ liệu vào lớp dữ liệu. Lớp dữ liệu cũng có thể có mô hình riêng, thường liên quan đến cơ sở dữ liệu.

Câu hỏi là: làm thế nào điều này phù hợp với khái niệm MVC?

Trả lời -> Không!
Vâng - nó hơi giống, nhưng không hoàn toàn.
Điều này là do MVC là một cách tiếp cận được phát triển vào cuối những năm 1970 cho ngôn ngữ lập trình Smalltalk-80. Vào thời điểm đó GUI và máy tính cá nhân khá hiếm và web trên toàn thế giới thậm chí không được phát minh! Hầu hết các ngôn ngữ lập trình và IDE ngày nay đã được phát triển vào những năm 1990. Vào thời điểm đó, máy tính và giao diện người dùng hoàn toàn khác biệt so với những năm 1970.
Bạn nên ghi nhớ điều đó khi bạn nói về MVC.
Martin Fowler đã viết một bài viết rất hay về MVC, MVP và GUI ngày nay.


10
+1 để liệt kê chính xác sự khác biệt giữa ứng dụng mvc và n-tier. Hầu hết các ứng dụng doanh nghiệp tôi phát triển đều có n-tier và chỉ sử dụng mvc làm lớp trình bày.
Nghỉ hưu_User

Hãy nói 1) Xem mô hình trong MVC (Lớp trình bày) 2) Một số công nghệ C # (Lớp nghiệp vụ) cho các giao dịch được ủy quyền, Logic quy tắc kinh doanh cốt lõi. 3) Kho lưu trữ và Đơn vị công việc trong (Lớp truy cập dữ liệu) Vui lòng hướng dẫn một số công nghệ (hoặc Mẫu thực hành tốt nhất) có thể được sử dụng để xây dựng Lớp nghiệp vụ có thể tự do cho phép và hiển thị mô hình, kho lưu trữ để truy cập từ bộ điều khiển trong lớp trình bày (Trên Lớp). Về cơ bản, tôi tin rằng Thêm, Xóa, Cập nhật & Kết hợp của nó là Logic Kinh doanh và nên được giữ trong Giao dịch. Vui lòng trải một số ánh sáng bổ sung về điều này.
Mark Macneil Bikeio 7/03/2016

Xin chào Rahul, nếu tôi hiểu bạn chính xác, thì bạn đã đúng. Hoạt động CRUD về cơ bản là các bộ phận nguyên tử của các giao dịch kinh doanh. Cá nhân tôi thích sử dụng một trình ánh xạ HOẶC mạnh mẽ như Hibernate làm kho lưu trữ thay vì xây dựng của riêng tôi. Đó là bởi vì ngủ đông đã thực hiện đơn vị mẫu công việc trong nội bộ. Ngoài ra tôi thường đặt các giao dịch kinh doanh vào các dịch vụ kinh doanh riêng biệt.
Frank

Đối với mô hình khung nhìn, tôi có thể cung cấp cho bạn ví dụ sau: Chỉ cần hình ảnh bạn có GUI có chế độ xem danh sách kép trong đó. Chế độ xem danh sách kép này sử dụng mô hình chế độ xem danh sách kép làm mô hình dữ liệu của nó. Datamodel này chỉ là một thành phần của hai danh sách đơn giản. Vì vậy, mô hình chế độ xem danh sách kép phụ thuộc vào việc triển khai lớp trình bày vì nó không phải là một phần của mô hình miền của bạn, không giống như hai danh sách đơn giản được sử dụng để tạo mô hình chế độ xem. Tùy thuộc vào GUI bạn muốn tạo, có một số trường hợp bạn có thể muốn liên kết một mô hình cụ thể của chế độ xem với chế độ xem thay vì mô hình miền của mình.
Frank

Các quy tắc kinh doanh / phần logic là một chút khó khăn để giải thích. Để bắt đầu xử lý dữ liệu, bạn gọi một phương thức từ một trong các dịch vụ của bạn. Điều đó có nghĩa là về cơ bản bạn bắt đầu một giao dịch. Nếu phương thức này chứa logic nghiệp vụ thì nó được gọi là "tập lệnh giao dịch". Đó thường là một điều xấu vì nó hầu như không thể tái sử dụng. Sẽ tốt hơn nếu phương thức này gọi logic nghiệp vụ của mô hình miền của bạn. Điều này có nghĩa là mô hình miền của bạn phải được xem xét theo cách có thể chứa logic nghiệp vụ. Cách tiếp cận theo hướng tên miền này sẽ không hoạt động với một mô hình miền không đầy đủ hoặc sai.
Frank

73

Theo tôi, thuật ngữ logic kinh doanh không phải là một định nghĩa chính xác. Evans nói trong cuốn sách của mình, Domain Driven Design, về hai loại logic kinh doanh:

  • Tên miền logic.
  • Ứng dụng logic.

Sự tách biệt này theo ý kiến ​​của tôi rõ ràng hơn rất nhiều. Và với việc nhận ra rằng có nhiều loại quy tắc kinh doanh khác nhau cũng nhận ra rằng tất cả chúng không nhất thiết phải đi cùng một nơi.

Logic miền là logic tương ứng với miền thực. Vì vậy, nếu bạn đang tạo một ứng dụng kế toán, thì các quy tắc miền sẽ là các quy tắc liên quan đến tài khoản, bài đăng, thuế, v.v. Trong một công cụ lập kế hoạch phần mềm nhanh, các quy tắc sẽ là các công cụ như tính ngày phát hành dựa trên vận tốc và điểm câu chuyện trong hồ sơ tồn đọng, Vân vân.

Đối với cả hai loại ứng dụng này, nhập / xuất CSV có thể có liên quan, nhưng các quy tắc nhập / xuất CSV không liên quan gì đến tên miền thực tế. Loại logic này là logic ứng dụng.

Miền logic chắc chắn đi vào lớp mô hình. Mô hình cũng sẽ tương ứng với lớp miền trong DDD.

Logic ứng dụng tuy nhiên không nhất thiết phải được đặt trong lớp mô hình. Điều đó có thể được đặt trực tiếp trong bộ điều khiển hoặc bạn có thể tạo một lớp ứng dụng riêng biệt lưu trữ các quy tắc đó. Điều gì hợp lý nhất trong trường hợp này sẽ phụ thuộc vào ứng dụng thực tế.


1
Thật là quá đúng! Có hai mô hình ở đây Mô hình xem của bạn và Mô hình miền của bạn. Tôi nghĩ rằng điều gần như không may là bố cục của các dự án MVC khiến các nhà phát triển mới làm quen tin rằng họ chỉ nên nhồi nhét mã của họ vào Mô hình xem.
Jonathan

1
Tìm thấy câu trả lời của bạn dễ chấp nhận và dễ hiểu hơn. Cảm ơn.
revo

27

A1 : Logic kinh doanh đi vào Modelmột phần MVC. Vai trò của Modellà chứa dữ liệu và logic kinh doanh. Controllermặt khác có trách nhiệm nhận đầu vào của người dùng và quyết định phải làm gì.

A2 : A Business Rulelà một phần của Business Logic. Họ có một has amối quan hệ. Business LogicBusiness Rules.

Hãy nhìn vào Wikipedia entry for MVC. Đi đến Tổng quan nơi nó đề cập đến dòng chảy của MVCmẫu.

Cũng nhìn vào Wikipedia entry for Business Logic. Nó được đề cập Business Logiclà bao gồm Business RulesWorkflow.


16

Như một vài câu trả lời đã chỉ ra, tôi tin rằng có một số hiểu lầm về kiến ​​trúc đa tầng so với kiến ​​trúc MVC.

Kiến trúc nhiều tầng liên quan đến việc chia ứng dụng của bạn thành các tầng / lớp (ví dụ: trình bày, logic nghiệp vụ, truy cập dữ liệu)

MVC là một kiểu kiến ​​trúc cho lớp trình bày của một ứng dụng. Đối với các ứng dụng không tầm thường, logic kinh doanh / quy tắc kinh doanh / truy cập dữ liệu không nên được đặt trực tiếp vào Mô hình, Chế độ xem hoặc Bộ điều khiển. Để làm như vậy sẽ đặt logic nghiệp vụ trong lớp trình bày của bạn và do đó làm giảm việc sử dụng lại và duy trì mã của bạn.

Mô hình là một lựa chọn rất hợp lý để đặt logic nghiệp vụ, nhưng cách tiếp cận tốt hơn / dễ bảo trì hơn là tách lớp trình bày của bạn khỏi lớp logic nghiệp vụ của bạn và tạo lớp logic nghiệp vụ và chỉ cần gọi lớp logic nghiệp vụ từ các mô hình của bạn khi cần. Lớp logic nghiệp vụ sẽ lần lượt gọi vào lớp truy cập dữ liệu.

Tôi muốn chỉ ra rằng không có gì lạ khi tìm thấy mã kết hợp logic kinh doanh và truy cập dữ liệu trong một trong các thành phần MVC, đặc biệt là nếu ứng dụng không được kiến ​​trúc bằng nhiều tầng. Tuy nhiên, trong hầu hết các ứng dụng doanh nghiệp, bạn thường sẽ tìm thấy các kiến ​​trúc nhiều tầng với kiến ​​trúc MVC được đặt trong lớp trình bày.


2
Câu trả lời tốt nhất về vấn đề này. Nên được bình chọn cao hơn. Câu trả lời tệ nhất được đánh dấu là chấp nhận.
Peter Matisko

Câu trả lời hay nhất .. không còn nghi ngờ gì nữa
salman

Điều này phụ thuộc vào kích thước của dữ liệu và ứng dụng? Đối với một ứng dụng nhỏ, tôi đoán tất cả logic có thể đi vào các mô hình mà không có sự nhầm lẫn nào. Nếu vậy, ngưỡng kích thước để bắt đầu tách thành một lớp riêng biệt là gì?
mLstudent33

15

Đây là một câu hỏi đã được trả lời, nhưng tôi sẽ đưa ra "một xu" của mình:

Quy tắc kinh doanh thuộc về mô hình. "Mô hình" luôn bao gồm (tách biệt về mặt logic hoặc vật lý):

  • mô hình trình bày - một tập hợp các lớp rất phù hợp để sử dụng trong chế độ xem (nó được điều chỉnh theo hướng trình bày / UI cụ thể),
  • mô hình miền - phần độc lập UI của mô hình và
  • kho lưu trữ - phần nhận biết lưu trữ của "mô hình".

Các quy tắc kinh doanh sống trong mô hình miền, được hiển thị dưới dạng phù hợp với bản trình bày cho mô hình "bản trình bày" và đôi khi được sao chép (hoặc cũng được thi hành) trong "lớp dữ liệu".


5

Không có nghĩa gì khi đưa lớp doanh nghiệp của bạn vào Mô hình cho một dự án MVC.

Nói rằng ông chủ của bạn quyết định thay đổi lớp trình bày thành một thứ khác, bạn sẽ bị lừa! Lớp kinh doanh nên là một hội đồng riêng biệt. Mô hình chứa dữ liệu xuất phát từ lớp nghiệp vụ chuyển đến dạng xem để hiển thị. Sau đó, trên bài đăng, mô hình liên kết với một lớp Person cư trú trong lớp nghiệp vụ và gọi PersonBusiness.SavePerson (p); Trong đó p là lớp Người. Đây là những gì tôi làm (lớp BusinessError bị thiếu nhưng cũng sẽ có trong BusinessLayer):nhập mô tả hình ảnh ở đây


Bạn sẽ làm rõ tuyên bố này? " Mô hình chứa dữ liệu xuất phát từ lớp doanh nghiệp chuyển đến chế độ xem để hiển thị."
Anthony Rutledge

2

Q1:

Logic kinh doanh có thể được xem xét trong hai loại:

  1. Các logic tên miền như các điều khiển trên một địa chỉ email (tính duy nhất, các ràng buộc, v.v.), lấy giá của sản phẩm cho hóa đơn hoặc tính tổng giá của shoppingCart dựa trên các đối tượng sản phẩm của nó.

  2. Quy trình công việc rộng và phức tạp hơn được gọi là quy trình kinh doanh, như kiểm soát quy trình đăng ký cho sinh viên (thường bao gồm một số bước và cần kiểm tra khác nhau và có các ràng buộc phức tạp hơn).

Loại thứ nhất đi vào mô hình và loại thứ hai thuộc về bộ điều khiển . Điều này là do các trường hợp trong thể loại thứ hai là logic ứng dụng rộng rãi và đưa chúng vào mô hình có thể trộn lẫn sự trừu tượng của mô hình (ví dụ, không rõ liệu chúng ta có cần đưa các quyết định đó vào lớp mô hình này hay lớp khác không, vì chúng có liên quan cho cả hai!).

Xem câu trả lời này để biết sự khác biệt cụ thể giữa mô hình và bộ điều khiển, liên kết này để biết các định nghĩa rất chính xác và cả liên kết này cho một ví dụ Android hay.

Vấn đề là các ghi chú được đề cập bởi "Bùn" và "Frank" ở trên cả hai đều có thể đúng cũng như "Pete" (logic kinh doanh có thể được đưa vào mô hình hoặc bộ điều khiển, theo loại logic kinh doanh).

Cuối cùng, lưu ý rằng MVC khác nhau từ bối cảnh đến bối cảnh. Ví dụ: trong các ứng dụng Android, một số định nghĩa thay thế được đề xuất khác với các định nghĩa dựa trên web (xem bài đăng này chẳng hạn).


Quý 2:

Logic kinh doanh tổng quát hơn và (như "decyclone" đã đề cập ở trên), chúng tôi có mối quan hệ sau đây giữa chúng:

quy tắc kinh doanh log logic kinh doanh


0

Tại sao bạn không giới thiệu một lớp dịch vụ. sau đó bộ điều khiển của bạn sẽ gọn gàng và dễ đọc hơn, sau đó tất cả các chức năng của bộ điều khiển sẽ là các hành động thuần túy. bạn có thể phân tách logic nghiệp vụ nhiều như bạn cần trong lớp dịch vụ. mã tái sử dụng là cao. không ảnh hưởng đến các mô hình và kho lưu trữ.


-5

Model = mã cho các hoạt động cơ sở dữ liệu CRUD.

Trình điều khiển = đáp ứng các hành động của người dùng và chuyển các yêu cầu của người dùng để truy xuất dữ liệu hoặc xóa / cập nhật cho mô hình, tuân theo các quy tắc kinh doanh cụ thể cho một tổ chức. Các quy tắc kinh doanh này có thể được thực hiện trong các lớp của trình trợ giúp hoặc nếu chúng không quá phức tạp, chỉ cần trực tiếp trong các hành động của bộ điều khiển. Bộ điều khiển cuối cùng yêu cầu chế độ xem tự cập nhật để cung cấp phản hồi cho người dùng dưới dạng màn hình mới hoặc thông báo như 'cập nhật, cảm ơn', v.v.,

View = UI được tạo dựa trên truy vấn trên mô hình.

Không có quy tắc cứng và nhanh về nơi quy tắc kinh doanh nên đi. Trong một số thiết kế, chúng đi vào mô hình, trong khi ở những thiết kế khác, chúng được bao gồm trong bộ điều khiển. Nhưng tôi nghĩ tốt hơn là giữ chúng với bộ điều khiển. Hãy để mô hình chỉ lo lắng về kết nối cơ sở dữ liệu.


Nếu bạn đặt quy tắc kinh doanh trong bộ điều khiển và bạn có nhiều, nhiều hành động - bạn sẽ sao chép quy tắc kinh doanh nhiều, nhiều lần? Không. Bạn sẽ tách nó theo một phương thức trợ giúp hoặc một lớp nào đó. Đặt "thứ" đó vào mô hình, nơi nó thuộc về.
G. Stoynev

3
MVC không phải là một mẫu ứng dụng cho các hoạt động của cơ sở dữ liệu CRUD (mặc dù nó có thể được sử dụng theo cách đó) do đó Model có thể là "mã cho các hoạt động của cơ sở dữ liệu CRUD". Mô hình xác định các thực thể của ứng dụng, bao gồm dữ liệu và quy tắc kinh doanh. Bộ điều khiển phối hợp sự tương tác giữa khung nhìn và mô hình. Khung nhìn là giao diện người dùng phơi bày mô hình và các hoạt động có sẵn trong các mô hình được bộ điều khiển trưng ra.
Jon Davis
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.