Milko Kosturkov
An experienced developer specializing in the web.
SMS and Voice services
MMO Games
local positioning systems
TV productions
Healthcare
e-commerce
websites
SEO
online video
By Trygve Reenskaug - Trygve Reenskaug, CC BY-SA 3.0, https://commons.wikimedia.org/w/index.php?curid=31168223
MVC was conceived as a general solution to the problem of users controlling a large and complex data set.
Something that is of interest to the user. It could be concrete, like a house or an integrated
circuit. It could be abstract, like a new idea or opinions about a paper. It could be a whole,
like a computer, or a part, like a circuit element
Models represent knowledge. A model could be a single object (rather uninteresting), or it
could be some structure of objects.
There should be a one-to-one correspondence between the model and its parts on the one hand, and the represented world as perceived by the owner of the model on the other hand
A view is attached to its model (or model part) and gets the data necessary for the presentation
from the model by asking questions...
A view is a (visual) representation of its model. It would ordinarily highlight certain attributes of the model and suppress others
... the view will therefore have to know the semantics of the attributes of the model it represents.
A controller is the link between a user and the system. It provides the user with input by
arranging for relevant views to present themselves in appropriate places on the screen. It
provides means for user output by presenting the user with menus or other means of giving
commands and data.
A controller should never supplement the views...
Conversely, a view should never know about user input, such as mouse operations and
keystrokes.
<html>
<head>
<title>Book Query</title>
</head>
<body>
<h1>Another E-Bookstore</h1>
<h3>Choose Author(s):</h3>
<form method="get">
<input type="checkbox" name="author" value="Tan Ah Teck">Tan
<input type="checkbox" name="author" value="Mohd Ali">Ali
<input type="checkbox" name="author" value="Kumar">Kumar
<input type="submit" value="Query">
</form>
<%
String[] authors = request.getParameterValues("author");
if (authors != null) {
%>
<%@ page import = "java.sql.*" %>
<%
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:8888/ebookshop", "myuser", "xxxx"); // <== Check!
// Connection conn =
// DriverManager.getConnection("jdbc:odbc:eshopODBC"); // Access
Statement stmt = conn.createStatement();
String sqlStr = "SELECT * FROM books WHERE author IN (";
sqlStr += "'" + authors[0] + "'"; // First author
for (int i = 1; i < authors.length; ++i) {
sqlStr += ", '" + authors[i] + "'"; // Subsequent authors need a leading commas
}
sqlStr += ") AND qty > 0 ORDER BY author ASC, title ASC";
// for debugging
System.out.println("Query statement is " + sqlStr);
ResultSet rset = stmt.executeQuery(sqlStr);
%>
<hr>
<form method="get" action="order.jsp">
<table border=1 cellpadding=5>
<tr>
<th>Order</th>
<th>Author</th>
<th>Title</th>
<th>Price</th>
<th>Qty</th>
</tr>
<%
while (rset.next()) {
int id = rset.getInt("id");
%>
<tr>
<td><input type="checkbox" name="id" value="<%= id %>"></td>
<td><%= rset.getString("author") %></td>
<td><%= rset.getString("title") %></td>
<td>$<%= rset.getInt("price") %></td>
<td><%= rset.getInt("qty") %></td>
</tr>
<%
}
%>
</table>
<br>
<input type="submit" value="Order">
<input type="reset" value="Clear">
</form>
<a href="<%= request.getRequestURI() %>"><h3>Back</h3></a>
<%
rset.close();
stmt.close();
conn.close();
}
%>
</body>
</html>
Music Without Borders
import java.util.*;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import shopping.CD;
public class ShoppingServlet extends HttpServlet {
public void init(ServletConfig conf) throws ServletException {
super.init(conf);
}
public void doPost (HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
HttpSession session = req.getSession(false);
if (session == null) {
res.sendRedirect("http://localhost:8080/error.html");
}
Vector buylist=
(Vector)session.getValue("shopping.shoppingcart");
String action = req.getParameter("action");
if (!action.equals("CHECKOUT")) {
if (action.equals("DELETE")) {
String del = req.getParameter("delindex");
int d = (new Integer(del)).intValue();
buylist.removeElementAt(d);
} else if (action.equals("ADD")) {
//any previous buys of same cd?
boolean match=false;
CD aCD = getCD(req);
if (buylist==null) {
//add first cd to the cart
buylist = new Vector(); //first order
buylist.addElement(aCD);
} else { // not first buy
for (int i=0; i< buylist.size(); i++) {
CD cd = (CD) buylist.elementAt(i);
if (cd.getAlbum().equals(aCD.getAlbum())) {
cd.setQuantity(cd.getQuantity()+aCD.getQuantity());
buylist.setElementAt(cd,i);
match = true;
} //end of if name matches
} // end of for
if (!match)
buylist.addElement(aCD);
}
}
session.putValue("shopping.shoppingcart", buylist);
String url="/jsp/shopping/EShop.jsp";
ServletContext sc = getServletContext();
RequestDispatcher rd = sc.getRequestDispatcher(url);
rd.forward(req, res);
} else if (action.equals("CHECKOUT")) {
float total =0;
for (int i=0; i< buylist.size();i++) {
CD anOrder = (CD) buylist.elementAt(i);
float price= anOrder.getPrice();
int qty = anOrder.getQuantity();
total += (price * qty);
}
total += 0.005;
String amount = new Float(total).toString();
int n = amount.indexOf('.');
amount = amount.substring(0,n+3);
req.setAttribute("amount",amount);
String url="/jsp/shopping/Checkout.jsp";
ServletContext sc = getServletContext();
RequestDispatcher rd = sc.getRequestDispatcher(url);
rd.forward(req,res);
}
}
private CD getCD(HttpServletRequest req) {
//imagine if all this was in a scriptlet...ugly, eh?
String myCd = req.getParameter("CD");
String qty = req.getParameter("qty");
StringTokenizer t = new StringTokenizer(myCd,"|");
String album= t.nextToken();
String artist = t.nextToken();
String country = t.nextToken();
String price = t.nextToken();
price = price.replace('$',' ').trim();
CD cd = new CD();
cd.setAlbum(album);
cd.setArtist(artist);
cd.setCountry(country);
cd.setPrice((new Float(price)).floatValue());
cd.setQuantity((new Integer(qty)).intValue());
return cd;
}
}
An entry point into whatever does the domain work (Transaction Script, Service Layer, Application Service, etc.).
Deals with all output:
$app->get('/tickets', function (Request $request, Response $response) {
$this->logger->addInfo("Ticket list");
$tickets = $this->ticket_service->getTickets();
return $this->ticket_responder->index(
$response,
["tickets" => $tickets, "router" => $this->router]
);
});
$app->get('/ticket/new', function (Request $request, Response $response) {
$components = $this->ticket_service->getComponents();
return $this->ticket_responder->add(
$response,
["components" => $components]
);
});
$app->post('/ticket/new', function (Request $request, Response $response) {
$data = $request->getParsedBody();
$this->ticket_service->createTicket($data);
return $this->ticket_responder->create($response);
});
$app->get('/ticket/{id}', function (Request $request, Response $response, $args) {
$ticket = $this->ticket_service->getTicketById($args['id']);
return $this->ticket_responder->detail(
$response,
["ticket" => $ticket]
);
})->setName('ticket-detail');
Milko Kosturkov
@mkosturkov
linkedin.com/in/milko-kosturkov
mailto: mkosturkov@gmail.com
These slides:
https://slides.com/milkokosturkov/mvc-history-misconceptions-future/
By Milko Kosturkov
All of us who use MVC on a daily basis in our projects - we're doing it wrong! What we call MVC is flawed! How did this happen? What was the original idea? What went wrong? We'll dig into the past and find the answers. Then we'll identify the problems that MVC has and present an alternative - the Action-Domain-Responder!