الگوی طراحی Front Controller یکی از الگوهای طراحیه که برای متمرکز کردن نحوه مدیریت درخواست ها ایجاد شده. این الگوی طراحی تلاش میکنه تا به عنوان یک controller جلو از از باقی controller های دیگر قرار بگیره و همه درخواست هایی که به سمت سیستم می آید رو به عنوان یک "کنترل کننده" (handler) مدیریت کنه. شما میتونید کارهایی از قبیل authentication، authorization، عملیات ثبت وقایع (logging) و ... رو بر روی درخواست ها انجام بدید و بعد درخواست ارسال شده رو در صورت موفق آمیز بودن به سمت handler اصلی (که ممکن است servlet یا view خاصی باشه که شما آن را ایجاد کرده اید) ارسال کنید.

الگوی طراحی Front Controller از 3 جزء اصلی تشکیل شده:


1- Front Controller: یک کنترل کننده واحد که تمام درخواست هایی که به سمت نرم افزار شما ارسال میشه رو میگیره (بعد از این که درخواست ها رو گرفت یه سری کار که شما میخواستید مثل ثبت رویداد نگاری و... رو انجام میده اگه همه چیز مرتب بود و منطق های پیاده سازی Front Controller اجازه میداد با کمک Dispatcher، درخواست به سمت View یا Servlet که در request اعلام شده، ارسال میشه تا ادامه کار توسط View یا Servlet بررسی و پاسخ مناسب تولید بشه)


2- Dispatcher: این جز زمانی مورد استفاده قرار میگیره که Front Controller می خواد درخواست دریافت شده رو به Servlet یا View مورد نظر درخواست شده در Request ارسال کنه. بنابراین Dispatcher برای پیدا کردن View یا Servlet متناظر مورد استفاده قرار میگیره تا درخواست دریافت شده رو به سمت View یا Servlet اصلی بفرسته.


3- View یا Servlet که درخواست از اول میخواسته به آن ها دست پیدا کنه


  • از این الگوی طراحی در DispatcherServlet چارچوب Spring، Struts و خیلی framework های دیگه استفاده شده.


در ادامه یک نمونه خیلی خیلی ساده شده از این الگوی طراحی رو براتون پیاده کردم - البته از اونجا که از حوصله من خارج بود صرفا کپی کردم و اینجا آوردم:



الگوی طراحی Front Controller

  • یادتون باشه دوباره تاکید میکنم این مثال خیلی خیلی ساده است و در پیاده سازی کاربردی میتونه پیچیدگی خیلی بیشتری داشته باشه مثلا در Dispatcher بجای استفاده از قاعده تصمیم گیری IF میشه از یک Map استفاده کرد و نوع درخواست در کلید های Map جستجو بشه بعد با reflection نهایتا درخواست به سمت view یا servlet ارسال بشه. البته باز هم میتونه خیلی پیچیده تر هم بشه.


بیاید مثال رو یکم بررسی کنیم:

دو تا کلاس StudentView و HomeView هم نقش view رو در مثال ما بازی میکنن و تا حد ممکن خیلی خیلی ساده در نظر گرفته شده

public class HomeView {
   public void show(){
      System.out.println("Displaying Home Page");
   }
}


public class StudentView {
   public void show(){
      System.out.println("Displaying Student Page");
   }
}


کلاس dispatcher کارش اینه که بر اساس درخواست ارسال شده بررسی میکنه که کدوم servlet یا view مسئول پردازش و انجام عملیات های request هست و وقتی که servlet یا view مورد نظر رو پیدا میکنه درخواست رو به سمتش می فرسته:

public class Dispatcher {
   private StudentView studentView;
   private HomeView homeView;
   
   public Dispatcher(){
      studentView = new StudentView();
      homeView = new HomeView();
   }

   public void dispatch(String request){
      if(request.equalsIgnoreCase("STUDENT")){
         studentView.show();
      }
      else{
         homeView.show();
      }	
   }
}


این کلاس همونطور که از اسمش پیدا است Front Controller هستش و تمام درخواست ها رو میگیره، log - رویداد نگری - ثبت میشه در صورتی که کاربر احراز هویت بشه درخواست به سمت dispatcher میره تا بررسی بشه نوع درخواست چیه، کدوم view یا servlet مسئول رسیدگی به درخواسته تا درخواست به سمت view یا servlet مورد نظر ارسال بشه:

public class FrontController {
	
   private Dispatcher dispatcher;

   public FrontController(){
      dispatcher = new Dispatcher();
   }

   private boolean isAuthenticUser(){
      System.out.println("User is authenticated successfully.");
      return true;
   }

   private void trackRequest(String request){
      System.out.println("Page requested: " + request);
   }

   public void dispatchRequest(String request){
      //log each request
      trackRequest(request);
      
      //authenticate the user
      if(isAuthenticUser()){
         dispatcher.dispatch(request);
      }	
   }
}


این کلاس فقط کارش اینه که بتونید خروجی رو ببینید: (اگه دقت کرده باشید متد main در این کلاس قرار گرفته و برنامه شما رو اجرا میکنه)

public class FrontControllerPatternDemo {
   public static void main(String[] args) {
   
      FrontController frontController = new FrontController();
      frontController.dispatchRequest("HOME");
      frontController.dispatchRequest("STUDENT");
   }
}


در خروجی باید یه همچین چیزی رو ببینید:

Page requested: HOME
User is authenticated successfully.
Displaying Home Page
Page requested: STUDENT
User is authenticated successfully.
Displaying Student Page