Chapter III Web Presentation Mode
Architects are leaner and more able to design the first work. At the first design time and clear what you do, so be more cautious. The second is one of the most dangerous works, at which time he modifies and polishes the first work, and uses the idea of marginal design for the first design as a second work, resulting in a design that is overdone.
The initial web was simple, with just a few simple HTML pages that made it possible to share information. As the business evolved, it was necessary to decide what to display based on the business, so CGI programming was developed, a lot of business logic was written to the CGI, and then output to the page. With the development of the CGI programming model is challenged to meet the needs of development, so the development of the asp/jsp and other foliar programming models, so that the business logic can be embedded in the HTML page, so that a large number of duplicated code in the system, resulting in difficult to maintain.
When designing a web system, there is a contradiction between simple and complex conflicts. We strive for simplicity and competence in the design of our systems. However, in order to reuse and increase the complexity of business, it is inevitable to apply complex design methods. How do you balance the two? One way to help us measure this is whether the complexity of the introduction is to meet current needs or to meet future needs. If it is the former it can add complexity, which is reasonable. If it is reserved for the future, it is designed to overdo it. So at design time, be aware of critical web programming issues, possible solutions, and pros and cons.
Mode overview
This pattern cluster starts directly from the long-standing MVC, which has been tested since the business logic and presentation logic have been separated. This pattern was originally written at the design stage and was finally mapped by Microsoft to the ASP. NET MVC platform.
When you implement MVC with Microsoft®asp.net, you start with a simple system example: write on a page, and embed the application logic in the presentation element. As systems become more complex, the code-behind feature of ASP. NET is used to separate the presentation Code (view) from the model controller code. This always works well until the requirements force you to consider reusing the model code without the controller to avoid application redundancy. At this point, you need to create a standalone model to abstract the business logic and use the code-behind feature to adapt the model to the View Code. Then, the implementation process ends the discussion of the meaning of the MVC method test.
To date, models and views have been emphasized when using the Model-view-controller mode, and the controller plays a relatively minor role. In fact, the controller that works in this mode is an implicit controller in ASP. It is responsible for perceiving user events (requests and postbacks) and writing these events to the appropriate system response.
In a WEB-based dynamic application, many common tasks are repeated each time a page request is made, such as user authentication, validation, extracting request parameters, and finding the database associated with the presentation. If you do not manage these tasks, you will quickly lead to unnecessary code duplication. Because these tasks are completely related to perceiving user events and determining the correct system response, the logical location to place the behavior is in the controller.
More powerful controls
The next pattern in this cluster is the page controller, which is optimized for Model-view-controller and can meet the complexity of the next level. This mode uses a controller in the page range, accepts input from the page request, invokes the requested action against the model, and then determines the correct view to use as the result page. Repetitive logic, such as acknowledgments, is moved to the base controller class.
Using ASP. Page controller illustrates the power of ASP. NET built-in page controllers with common skin examples. The implementation process also uses the template method mode with the page Controller mode to define the algorithm framework in the operation, and takes some of these steps to the child class.
As applications become more complex, the page controller eventually accumulates a lot of logic in the base class, which is usually addressed by deepening the inheritance hierarchy of the page controller. If the application is complex, both of these factors can cause code to be difficult to maintain and extend. Similarly, some applications need to dynamically configure the navigation map, which may span multiple page controllers. When this level of complexity is reached, the Front controller (front-end controllers) should be considered.
The Front Controller, the next pattern in the directory, is also an optimization of the model-view-controller. In the front-end controller, all requests are routed through a single (usually two-part) controller. The first part of the controller is the handler, and the second part is the hierarchy of the Commands (command). The command itself is part of the controller and represents the specific action that the controller triggers. After you perform this operation, the command chooses which view to use to render the page. Typically, the built-in controller framework uses a configuration file to map requests to operations, so it is easy to change after they are built. The disadvantage, of course, is the inherent complexity of this design.
Filters and Caches
The last two patterns in this cluster involve filters and caches.
The I ntercepting filter (Intercept filter) provides a solution to the following issues: how to implement common preprocessing and post-processing for HTTP requests. In intercepting Filter, it is best to perform common non-application-specific tasks such as security checks, logging, compression, encoding, and decoding. Intercepting Filter typically involves performing a specific task. When you perform multiple tasks on HTTP requests, multiple filters are linked together. Using the HTTP module in ASP. Intercepting Filter emphasizes that it is easy to implement this pattern in ASP.
Page cache addresses the increasing scalability and performance requirements of WEB applications by preserving replicas of frequently used dynamic Web pages that are extremely expensive to create. After the page is initially created, a copy is sent in response to subsequent requests. Page Cache also discusses several key caching design factors, such as cache refresh, data refresh, and cache granularity. The use of absolute expiration in ASP. Page cache illustrates the Web-caching feature of ASP.
Pagecontroller ( page Controller)
Context
You have decided to use the Model-view-controller (MVC) pattern to separate the user interface components of a dynamic WEB application from the business logic. The application you are building will construct the Web page dynamically, but navigation between pages is static.
Problem
How do you best build controllers for moderately complex WEB applications that avoid code duplication and enable reusability and flexibility?
Impact factors
The following factors affect the system in this case, and these factors must be reconciled when considering the above problem solution:
The MVC pattern typically focuses on the separation between the model and the view, and less attention is paid to the controller. In many rich client scenarios, the separation between the controller and the view is relatively minor, so [Fowler03] is often ignored. In a thin client application, however, views and controllers are inherently delimited because the display is performed in the client browser, and the controller is part of the server-side application. Therefore, it is necessary to study the controller more carefully.
In a dynamic WEB application, multi-user actions can cause different controller logic and then display the same page. For example, in a simple Web-based e-mail application, both sending and deleting messages from the Inbox may return the user to the (refreshed) Inbox page. Although both activities show the same page after they are completed, the application must perform different actions based on the previous page and the button that the user clicked.
The code that displays most dynamic Web pages includes very similar steps: Validating a user's identity, extracting page parameters from a query string or form field, gathering session information, retrieving data from a data source, generating dynamic portions of a page, and adding applicable headers and footers. This can lead to a lot of code duplication.
Scripted server Pages, such as ASP. NET) can be easy to create, but can have some drawbacks when the application grows. Scripted pages are not good at separating controllers and views, thus reducing the likelihood of reuse. For example, if multiple operations will result in the same page, it can be difficult to reuse the display code between multiple controllers because the display code is mixed with the controller code. Scripted server Pages that are scattered between business logic and display logic are also more difficult to test and debug. Finally, developing scripted server Pages requires mastering both the development of business logic and the creation of beautiful and efficient HTML pages, and few people have these two skills. Based on the above considerations, it is necessary to minimize scripted server page code and to develop business logic in real classes.
As described in the MVC pattern, testing user interface code is often time-consuming and monotonous. Testing business logic is simpler and more repeatable if you can separate the user-interface-specific code from the actual business logic. This is true for both the display section and the Application Controller section.
A common look and navigation structure can often improve the usability and brand awareness of WEB applications. However, a common appearance may cause the display code to be duplicated, especially if the code is embedded in a scripted server page. Therefore, a mechanism is needed to improve the reusability of display logic between pages.
Solution Solutions
Use the page Controller pattern to accept input from a page request, invoke the action that the request performs on the model, and determine the correct view to apply to the results page. Separates the dispatch logic from all view-related code. If appropriate, create a common base class for all page controllers to avoid duplication of code and improve consistency and testability. Figure 1 shows the relationship between the page controller and the model and view.
The page controller can receive page requests, extract all relevant data, invoke all updates to the model, and forward requests to the view. The view will then retrieve the data to be displayed based on the model. Defining a standalone page controller separates the model from the WEB request details (such as session management, or using query strings or hidden form fields to pass parameters to the page). In this basic form, a controller is created for each link in the Web application. The controller will thus become very simple because only one operation must be considered at a time.
Creating a standalone controller for each Web page (or operation) can cause a lot of code duplication. Therefore, you should create a Basecontroller class to incorporate common functions such as validation parameters (see Figure 2). Each standalone page controller can inherit this common functionality from Basecontroller. In addition to inheriting from a common base class, you can define a set of helper classes that the controller can call to perform common functions.
This method works well if most pages are similar and you can put common functionality in a base class. The more pages change, the more levels you have to insert into the inheritance tree. For example, all pages parse parameters, but only the page that displays the list retrieves the data from the database, and the page that needs to enter the data updates the model without retrieving the data. It is now possible to introduce two new base classes, Listcontroller and Dataentrycontroller, all of which are inherited by Basecontroller. The list page can then inherit from Listcontroller, while the data entry page can inherit from Dataentrycontroller. Although this approach works well in this simple example, the inheritance tree can be very deep and complex when dealing with real business applications. You may want to add conditional logic to the base class to accommodate some variants, but doing so will violate the encapsulation principle, and the base class can therefore cause considerable inconvenience in changing the system. Therefore, when your application becomes more complex, you should consider using helper classes or Front Controller patterns.
Because page controllers are often required for Web applications, most Web application frameworks implement page controllers by default. Most frameworks include page controllers in the form of server Pages (such as ASP, JSP, and PHP). The server page actually combines the functionality of the view and the controller, but does not provide a corresponding separation between the display code and the controller code. Unfortunately, for some frameworks, mixed view-related code is easy with controller-related code, but it is difficult to properly separate the controller logic. As a result, the Page Controller approach is poorly-regarded among many developers. Many developers now associate Page controllers with poor design, and associate Front controllers with better designs. In fact, this feeling is due to the imperfect situation of the specific implementation; Page controller and Front controller are excellent architectural choices.
Therefore, it is best to put the controller logic separately into a standalone class that can be called from the server page. The ASP. NET page framework provides a perfect mechanism to implement this separation, known as the code-behind class.
Variant
In most cases, the page controller depends on the specifics of the HTTP-based WEB request. Therefore, page controller code typically contains references to HTTP headers, query strings, form fields, multipart form requests, and so on. Therefore, it is very difficult to test the controller code outside of the WEB application framework. The only way is to test the controller by simulating the HTTP request and analyzing the results. This type of testing is time-consuming and error-prone. Therefore, to improve testability, you can put web-dependent code and web-independent code into two separate classes (see Figure 3).
In this example, Aspnetcontroller encapsulates all the dependencies on the application framework (ASP. NET). For example, it can extract all incoming parameters from a Web request and pass it to Basecontroller using a Web-independent interface (for example, using a collection). This approach not only improves testability, but also allows reuse of the controller code through other user interfaces, such as a rich client interface or a custom scripting language.
The disadvantage of this approach is that it adds overhead. A new class is now in place and must be converted before each request is processed. Therefore, as far as possible the controller is affected by the environment, and weigh the choice to reduce dependence and improve development efficiency and execution efficiency.
Result context
The following advantages and disadvantages exist with the Page Controller pattern.
Advantages
Simplicity. Because each Dynamic Web page is handled by a specific controller, these controllers need only a limited range of processing to maintain simplicity. Because each page controller processes only one Web page, page controllers are especially useful for WEB applications that have a simple navigation structure.
Built-in frame functionality. In most of its basic forms, the controller has been placed into most WEB application platforms. For example, if a user clicks a link in a Web page to a dynamic page generated by an ASP. NET script, the WEB server parses the URL associated with the link and executes the associated ASP. In effect, these ASP. NET pages are the controllers of the actions that the user performs. The ASP. NET page framework also provides a code-behind class for executing controller code. The code-behind class provides a better separation between the controller and the view, and allows you to create a feature controller base class that merges the common functions of all controllers. For an example, see Implement Page Controller in ASP.
Enhanced re-usability. Creating a controller base class can reduce code duplication and allow common code to be reused on different page controllers. You can reuse code by implementing repetitive logic in the base class. Then, all the specific Page Controller objects will automatically inherit this logic. If the implementation of the logic differs for different pages, you can still use the Template Method in the base class and implement the basic execution structure, and the implementation of the specific sub-steps may vary depending on the page.
Scalability. By using helper classes, you can easily extend the page controller. If the logic in the controller is too complex, you can delegate some logic to the helper class. In addition to inheritance, helper classes provide another mechanism for reuse.
Separation of developer responsibilities. Using the Page Controller class helps separate the responsibilities of the members of the development team. Controller developers must be familiar with the domain model and business logic implemented by the application. On the other hand, view designers can focus on the display style of the results.
Disadvantages
Because of its simplicity, Page Controller is the default implementation for most dynamic WEB applications. However, you should be aware of the following limitations:
One controller per page. The main disadvantage of page controller is to create a controller for each Web page. This feature is ideal for applications that have a set of static pages and simple navigation paths. Some of the more complex applications require dynamic mapping of navigation maps between pages and pages. If this logic is dispersed across a number of page controllers, it can cause the application to be difficult to maintain, even if some logic can be placed in the base controller. In addition, the built-in functionality of the WEB framework may reduce the flexibility of naming URLs and resource paths (although a lower-level mechanism such as ISAPI filters can be used to compensate for some degree). In these scenarios, consider intercepting all WEB requests using the Front Controller and forwarding those requests to the appropriate handlers according to the configurable rules.
Darker inheritance tree. Inheritance seems to be one of the cutest and most annoying features of object-based programming. If you reuse common functionality only by using inheritance, you might reduce the flexibility of the inheritance hierarchy. For more information, see Implementing Page Controller in ASP.
Dependency on the WEB framework. In the basic form, the page controller still relies on the WEB application environment and cannot be tested separately. You can use the wrapper mechanism to separate the Web-dependent parts, but you need to add a level of indirection.
Test considerations
Because the page controller relies on the specifics of the Web application framework (for example, query strings and HTTP headers), it is not possible to instantiate and test the controller class outside of the web framework. If you need to run a set of automated unit tests on the controller class, you must start the WEB application each time you test. The HTTP request must then be submitted in a format that performs the required functionality. This configuration brings many dependencies and adverse effects to the test. To improve testability, consider separating the business logic (including the controller logic that becomes more complex) from the Web-dependent code.
Using the Micrisoft.net Design Scenario Chapter III Web representation pattern