Web Presentation Pattern Selector
by @quochungto
Select the right web presentation pattern combination for any server-side web layer under design or refactor. Covers MVC (Model View Controller) decompositio...
Example 1 β Rails App with Fat Controllers
Scenario: A Rails e-commerce app (Rails 7, ERB templates, PostgreSQL) where product and order controller actions each contain pricing calculation logic, discount rule evaluation, and direct ActiveRecord queries. Developers report tests requiring full request stacks.
Trigger: "Our Rails controllers are too fat β business logic is in the actions and tests are slow and fragile."
Process:
1. Framework: Rails 7 β Front Controller (Router) already in place. Rails controller actions = Page Controller style.
2. Rendering: Server-rendered ERB β Template View confirmed.
3. No wizard flows β Application Controller not warranted.
4. Anti-pattern audit: Grep app/controllers/ for ActiveRecord queries and pricing logic in actions β found in OrdersController#create (82 lines, discount calculation) and ProductsController#show (direct SQL for related products).
5. Two Step View not needed β ERB templates + Rails application layout already handle shared structure.
6. Fix: extract OrderPricingService and ProductQueryService; controller actions become: decode params β call service β assign @result β render.
Output design record:
OrdersController#create pricing logic to OrderPricingService; move ProductsController#show query to ProductRepositoryExample 2 β Spring MVC App Adding a Checkout Wizard
Scenario: A Spring MVC app (Java 17, Thymeleaf templates) with a working product catalog. Adding a 5-step checkout wizard: (1) cart review, (2) address, (3) shipping options, (4) payment, (5) confirmation. Steps may conditionally skip (digital products skip shipping).
Trigger: "We need to add a multi-step checkout. How do we structure the controllers and avoid scattered navigation logic?"
Process:
1. Framework: Spring MVC β DispatcherServlet = Front Controller already in place.
2. Rendering: Server-rendered Thymeleaf β Template View confirmed.
3. Wizard flow with conditional step skipping β Application Controller IS warranted.
4. Application Controller holds: step sequence definition, which service method per step, which view per step, skip conditions (digital product β skip shipping step).
5. CheckoutController becomes thin: delegate to CheckoutApplicationController.nextStep(session, input) β get command + view; execute command; forward to view.
6. Anti-pattern check: ensure no business logic in the Thymeleaf templates (th:if on business conditions is the scriptlet equivalent β move conditions to view model).
Output design record:
CheckoutController (Page Controller style for the wizard entry point)CheckoutApplicationController owns step sequence + conditional skippingExample 3 β ASP.NET Core API Backend for a React SPA
Scenario: ASP.NET Core 8 Web API serving a React frontend. Team debating whether the "MVC pattern" applies β some say it's API-only so MVC doesn't matter.
Trigger: "We're building an API for our SPA. Does any of this web presentation pattern stuff apply to us?"
Process: 1. Framework: ASP.NET Core β middleware pipeline = Front Controller already in place. 2. Rendering: JSON API (no HTML). 3. MVC does apply to the API backend: Model = domain/service layer, View = JSON response shape (handled by serializer), Controller = API controller actions. 4. View pattern: Transform View β the JSON serializer/presenter walks domain objects and transforms them to JSON response DTOs. This is identical in structure to XSLT-based Transform View: input element types (domain objects) β output elements (JSON fields). 5. Controller pattern: Front Controller (ASP.NET Core pipeline) + Page Controller style actions in API controllers. 6. Application Controller: check for multi-step API flows (e.g., an onboarding flow across multiple API calls with server-side session state) β not present here β not warranted. 7. Anti-pattern note: "fat controller" still applies β business logic in API controller actions is the same problem as in HTML controllers.
Output design record:
clawhub install bookforge-web-presentation-pattern-selector