JCConf Taiwan 2014
MODERN
DESIGN PATTERN
ABOUT ME
王文農a.k.aSteven
Softleader engineer, for build application and framework.
Research interests are adjusted efficiencyand effectiveness of
algorithms.
Playsome of new frameworks/libraries and technology.
If you wantto be acoolguy.
JOIN SOFTLEADER.
WHAT IS DESIGN PATTERN?
Descriptions of communicating objects and
classes thatare customized to solve ageneral
design problem.
–Gamma, et. al
THE ONE CONSTANT IN SOFTWARE DEVELOPMENT:
CHANGE!
TIGHT COUPLING!
IT MIGHT GET YOU INTO TROUBLE
BEWARE OF
GOF: 23
MVC PATTERN
A PROBLEM OR A SOLUTION ?
Commonlyreasons:
Reduced Code complexity
Code reuse
Increased flexibility
Decoupled code
COOL, SOUNDS NICE, BUT
Is ittrue ?
Do allother patterns lack these coolthings ?
THE ANSWER IS NO!
Doesn'tsolve the code complexity problem
Doesn'tsolve the code reuse or no-flexibility problem
Doesn'tguarantee decoupled code
MVC COMPONENTS
HOW MVC WORKS
POOR MVC GIVE BIRTH TO
MVC DEMO WITH SERVLET
MODEL-VIEW-CONTROLLER
MODEL
publicclassModel{
privateStringname;
publicvoidsetName(Stringname){
//businesslogic
this.name=name;
}
//forviewaccess
publicStringgetName(){
returnname;
}
}
VIEW
<h1>Hello,${model.name}</h1>
<formaction="controller"method="post">
<labelfor="name">Mynameis</label>
<inputtype="text"id="name"name="name"value="${model.name}"/>
<button>Submit</button>
</form>
<%--receivedata--%>
CONTROLLER
@WebServlet(value="/controller")
publicclassControllerextendsHttpServlet{
@Override
protectedvoiddoPost(HttpServletRequestreq,HttpServletResponseresp)throwsServlet
//acceptingrequest
Stringname=req.getParameter("name");
//validaterequest
if(name.isEmpty()){
name="Guest";
}
//useModeltodobusinesslogic
Modelmodel=newModel();
model.setName(name);
//bindingmodeltoview
req.setAttribute("model",model);
//forwardtoview
req.getRequestDispatcher("/v/view.jsp").forward(req,resp);
}
@Override
protectedvoiddoGet(HttpServletRequestreq,HttpServletResponseresp)throwsServletE
//acceptingrequest
//useModeltodobusinesslogic
Modelmodel=newModel();
model.setName("Guest");
MVP DEMO WITH VAADIN
MODEL-VIEW-PRESENTER
MODEL
publicclassModel{
privateStringname;
publicvoidsetName(Stringname){
//businesslogic
this.name=name;
}
//forpresenteraccess
publicStringgetName(){
returnname;
}
}
VIEW
publicclassViewextendsCustomComponent{
privateLabeldisplay=newLabel("Hello,Guest");
privateTextFieldname=newTextField("Mynameis");
privateButtonbutton=newButton("Submit");
privatePresenterpresenter;
publicView(){
//initiallayoutandpresenter
initialLayout();
presenter=newPresenter(this);
}
protectedvoidinitialLayout(){
CustomLayoutlayout=newCustomLayout("view");
layout.addComponent(display,"display");
layout.addComponent(name,"name");
button.addClickListener(newClickListener(){
@Override
publicvoidbuttonClick(ClickEventevent){
//whenbuttonclickthendispatchtopresenter
presenter.changeDisplay();
}
});
layout.addComponent(button,"submit");
setCompositionRoot(layout);
}
//viewprovidegetters&setters
PRESENTER
publicclassPresenter{
privateViewview;
privateModelmodel;
publicPresenter(Viewview){
this.view=view;
this.model=newModel();
}
publicvoidchangeDisplay(){
Stringname=view.getInput().getValue();
//dosomelogic,eg:validate
if(name.isEmpty()){
name="Guest";
}
//callmodel
model.setName(name);
//controlview
view.setDisplay("Hello,"+model.getName());
}
}
MVVM DEMO WITH ZK
MODEL-VIEW-VIEWMODEL
MODEL
publicclassModel{
privateStringname;
publicvoidsetName(Stringname){
//businesslogic
this.name=name;
}
publicStringgetName(){
returnname;
}
}
VIEW
<zk>
<windowtitle="MVVMExample"border="normal"width="100%"
apply="org.zkoss.bind.BindComposer"
viewModel="@id('vm')@init('tw.jcconf.example.mvvm.vm.ViewModel')">
<hbox>
Hello,<labelvalue="@load(vm.model.name)"/>
</hbox>
<hbox>
<labelvalue="Mynameis"/><textboxvalue="@bind(vm.name)"/>
<buttononClick="@command('changeName')"label="Submit"/>
</hbox>
</window>
</zk>
VIEWMODEL
publicclassViewModel{
privateStringname;
privateModelmodel;
publicViewModel(){
model=newModel();
model.setName(name="Guest");
}
//eventhandler
@Command
@NotifyChange("model")
publicvoidchangeName()throwsException{
model.setName(name);
}
//ViewModelprovidergetter&setter
publicvoidsetName(Stringname){
this.name=name;
}
publicStringgetName(){
returnname;
}
publicModelgetModel(){
returnmodel;
}
}
RESTFUL PATTERN
An architectural style thatabstracts the
architectural elements within adistributed
hypermediasystem.
–Wikipedia
THE MEAS IS
Use HTTPmethods explicitly.
Be stateless.
Expose directory structure-like URIs.
Transfer XML, JavaScriptObjectNotation
(JSON), or both.
–IBM's developerWorks website
WHAT IS REST ?
HTTP ITSELF IS REST IMELEMENTATION
HOW TO USE ?
User Action HTTP Method
Create POST/PUT
Read (Retrieve) GET
Update (Modify) PUT/PATCH
Delete (Destroy) DELETE
LOOK ALIKE
User Action SQL
Create INSERT
Read (Retrieve) SELECT
Update (Modify) UPDATE
Delete (Destroy) DELETE
FOLLOW HTTP TO DESIGN RESTFUL WEB SERVICE
Nouns
Define the URL for your resources
Verbs
Choose the rightHTTP method
ContentTypes
Choose content-type which you wantto return
 
«   ‹   ›   »
CREATE
POSThttp://domain/books
{
"isbn":"123456789",
"title":"ModernDesignPattern",
"author":"StevenWang",
"publisher":"JCConfTW",
"year":"2014"
}
HTTP/1.1 200 | 401
{
"id":"9876543"
}
READ
GEThttp://domain/books/123456789
or
GEThttp://domain/books?isbn=123456789
HTTP/1.1 200 | 404
[{
"id":"9876543",
"isbn":"123456789",
"title":"ModernDesignPattern",
"author":"StevenWang",
"publisher":"JCConfTW",
"year":"2014"
}]
UPDATE
PUThttp://domain/books/9876543
or
PUThttp://domain/books
{
["id":"9876543",]
"isbn":"123456789",,
"title":"ModernDesignPattern",
"author":"StevenWang",
"publisher":"JCConfTW",
"year":"2014"
}
HTTP/1.1 200 | 401 |404
DELETE
DELETE http://domain/books/9876543
or
DELETE http://domain/books?isbn=9876543
HTTP/1.1 200 | 401 |404
RESTFUL DEMO WITH SPRING
@RestController
@RequestMapping("/books")
publicclassBooksResource{
@Autowired
BookServiceservice;
@RequestMapping(consumes="application/json",produces="application/json",method=
@ResponseBody
publicList<Book>getAll(){
returnservice.getAll();
}
@RequestMapping(value="/{isbn}",consumes="application/json",produces="applicat
@ResponseBody
publicBookgetByIsbn(@PathVariable("isbn")Stringisbn){
returnservice.getBookByIsbn(isbn);
}
@RequestMapping(consumes="application/json",produces="application/json",method=
@ResponseBody
publicBooksave(@RequestBodyBookbook){
returnservice.save(book);
}
@RequestMapping(consumes="application/json",produces="application/json",method=
@ResponseBody
publicBookupdate(@RequestBodyBookbook){
returnservice.update(book);
}
@RequestMapping(value="/{id}",consumes="application/json",produces="applicatio
publicvoiddelete(@PathVariable("id")Longid){
CQRS PATTERN
WHAT IS CQRS ?
CQRS is simply the creation of two objects where
there was previously only one. The separation
occurs based upon whether the methods are a
command or aquery (the same definition thatis
used by Meyer in Command and Query
Separation, acommand is any method that
mutates state and aquery is any method that
returns avalue).
–Wikipedia
Saywhat?
PUT ANOTHER WAY...
Command/QueryResponsibilitySegregation (CQRS) is the idea
thatyou can use adifferentmodelto update information than the
modelyou use to read information.
IN THIS CONTEXT,
Commands = Writes
Queries = Reads
OK, BUT WHY ?
WHAT IS CQRS NEED ?
MULTI-USER SYSTEM
TYPICAL APPLICATION OF THE CQRS PATTERN
COMMANDS AND EVENTS IN THE CQRS PATTERN
WHEN TO AVOID CQRS ?
So, when should you avoid CQRS?
The answer is mostof the time...
–UdiDahan
OK, SOME SUGGESTIONS
Large team.
Difficultbusiness logic.
Scalabilitymatters.
Your top people can work on domain logic.
FINALLY
PATTERNS DON’T SOLVE PROBLEMS,
THEY HELP US
JCConf TW 2014 - Modern Design Pattern

JCConf TW 2014 - Modern Design Pattern