Abstractie (Dutch)

91

description

De slides van mijn college over abstractie, zoals gegeven aan de Rijksuniversiteit Groningen.

Transcript of Abstractie (Dutch)

Page 1: Abstractie (Dutch)
Page 2: Abstractie (Dutch)
Page 3: Abstractie (Dutch)
Page 4: Abstractie (Dutch)
Page 5: Abstractie (Dutch)
Page 6: Abstractie (Dutch)
Page 7: Abstractie (Dutch)
Page 8: Abstractie (Dutch)

Write('A');

Page 9: Abstractie (Dutch)

abstractie

Page 10: Abstractie (Dutch)

wat?waarom?hoe?valkuilenconclusie

Page 11: Abstractie (Dutch)

wat?

Page 12: Abstractie (Dutch)

“Abstraction is the process of generalization by reducing the information content of a concept in

order to retain only information which is relevant for a particular purpose.”

-- Wikipedia (ed.)

Page 13: Abstractie (Dutch)

waarom?

Page 14: Abstractie (Dutch)
Page 15: Abstractie (Dutch)

bestanden

mappen

multi-tasking

vensters

knoppen

invoer velden

Page 16: Abstractie (Dutch)

hoe?

Page 17: Abstractie (Dutch)

printChar('N');printChar('a');printChar('a');printChar('m');printChar(':');printChar(' ');

char[] vnBuffer = new char[255];int vnLength = 0;char inp;do { inp = readChar(); vnBuffer[vnLength] = inp; vnLength++;while (inp != '\n');

printChar('A');printChar('c');printChar('h');printChar('t');printChar('e');printChar('r');printChar('n');printChar('a');printChar('a');printChar('m');printChar(':');

char[] anBuffer = new char[255];int anLength = 0;do { inp = readChar(); anBuffer[anLength] = inp; anLength++;while (inp != '\n');

printChar('H');printChar('a');printChar('l');printChar('l');printChar('o');printChar(' ');int i = 0;while(i < vnLength) { printChar(vnBuffer[i]); i++;}printChar(' ');i = 0;while(i < anLength) { printChar(anBuffer[i]); i++;}

Page 18: Abstractie (Dutch)

printChar('N');printChar('a');printChar('a');printChar('m');printChar(':');printChar(' ');

char[] vnBuffer = new char[255];int vnLength = 0;char inp;do { inp = readChar(); vnBuffer[vnLength] = inp; vnLength++;while (inp != '\n');

printChar('A');printChar('c');printChar('h');printChar('t');printChar('e');printChar('r');printChar('n');printChar('a');printChar('a');printChar('m');printChar(':');

char[] anBuffer = new char[255];int anLength = 0;do { inp = readChar(); anBuffer[anLength] = inp; anLength++;while (inp != '\n');

printChar('H');printChar('a');printChar('l');printChar('l');printChar('o');printChar(' ');int i = 0;while(i < vnLength) { printChar(vnBuffer[i]); i++;}printChar(' ');i = 0;while(i < anLength) { printChar(anBuffer[i]); i++;}

Page 19: Abstractie (Dutch)

printChar('N');printChar('a');printChar('a');printChar('m');printChar(':');printChar(' ');

char[] vnBuffer = new char[255];int vnLength = 0;char inp;do { inp = readChar(); vnBuffer[vnLength] = inp; vnLength++;while (inp != '\n');

printChar('A');printChar('c');printChar('h');printChar('t');printChar('e');printChar('r');printChar('n');printChar('a');printChar('a');printChar('m');printChar(':');

char[] anBuffer = new char[255];int anLength = 0;do { inp = readChar(); anBuffer[anLength] = inp; anLength++;while (inp != '\n');

printChar('H');printChar('a');printChar('l');printChar('l');printChar('o');printChar(' ');int i = 0;while(i < vnLength) { printChar(vnBuffer[i]); i++;}printChar(' ');i = 0;while(i < anLength) { printChar(anBuffer[i]); i++;}

Page 20: Abstractie (Dutch)

printChars(new char[] { 'N', 'a', 'a', 'm', ':', ' '}, 6);char[] vnBuf = new char[255];int vnLength = readChars(vnBuf);

printChars(new char[] { 'A', 'c', 'h', 't', 'e', 'r', 'n', 'a', 'a', 'm', ':', ' '}, 12);char[] anBuf = new char[255];int anLength = readChars(vnBuf);

printChars(new char[] {'H', 'a', 'l', 'l', 'o', ' '}, 6);printChars(vnBuf, vnLength);printChars(anBuf, anLength);

Page 21: Abstractie (Dutch)

String voornaam = readLine("Naam: ");String achternaam = readLine("Achternaam: ");print("Hallo " + voornaam + " " + achternaam);

Page 22: Abstractie (Dutch)

FullName fn = FullName.read();fn.printGreeting();

Page 23: Abstractie (Dutch)

readNameAndPrintGreeting();

Page 24: Abstractie (Dutch)

goed abstractie niveau?

Page 25: Abstractie (Dutch)

readNameAndPrintGreeting();

nieuwe eis: vraag ook naar leeftijd

Page 26: Abstractie (Dutch)

readNameAndPrintGreeting();

nieuwe eis: vraag ook naar leeftijd✖

Page 27: Abstractie (Dutch)

FullName fn = FullName.read();fn.printGreeting();

nieuwe eis: vraag ook naar leeftijd

Page 28: Abstractie (Dutch)

FullName fn = FullName.read();fn.printGreeting();

nieuwe eis: vraag ook naar leeftijd✖

Page 29: Abstractie (Dutch)

String voornaam = readLine("Naam: ");String achternaam = readLine("Achternaam: ");print("Hallo " + voornaam + " " + achternaam);

nieuwe eis: vraag ook naar leeftijd

Page 30: Abstractie (Dutch)

String voornaam = readLine("Naam: ");String achternaam = readLine("Achternaam: ");int leeftijd = stringToInt(readLine("Leeftijd: "));print("Hallo " + voornaam + " " + achternaam + ", jij bent " + leeftijd + " jaar oud.");

nieuwe eis: vraag ook naar leeftijd ✔

Page 31: Abstractie (Dutch)

goed abstractie niveau afhankelijk van

Page 32: Abstractie (Dutch)

goed abstractie niveau afhankelijk van

gebruik nu

Page 33: Abstractie (Dutch)

goed abstractie niveau afhankelijk van

gebruik nu

gebruik later

Page 34: Abstractie (Dutch)

Web applicaties in Java/Seam

Page 35: Abstractie (Dutch)

View ControllerModel

Page 36: Abstractie (Dutch)

Data: Hibernate@Entitypublic class Blog { protected String _title = ""; public String getTitle() { return _title; } public void setTitle(String value) { _title = value; } @ManyToOne protected User _author; public User getAuthor() { return _author; } public void setAuthor(User author) { _title = value; } @OneToMany(mappedBy="_blog", targetEntity=BlogEntry.class) @Cascade(...) protected List<BlogEntry> _entries; public List<BlogEntry> getEntries() { return _entries; } public void setEntries(List<BlogEntry> entries) { _entries = entries; }}

Page 37: Abstractie (Dutch)

View: JSF<html ...> ... <body> ... <h:form> <table> <tr><td><h:outputText value="Title: "/></td><td><h:inputText value="#{editBlogEntry.e.title}" /></td></tr><tr><td><h:outputText value="Created: "/></td><td><rich:calendar value="#{editBlogEntry.e.created}" popup="true" datePattern="dd/MM/yyyy" .../></td></tr><tr><td><h:outputText value="Content: "/></td><td><h:inputTextarea value="#{editBlogEntry.e.content}"/></td></tr><tr><td><h:outputText value="Status: "/></td><td><h:selectOneMenu value="#{editBlogEntry.e.status}"> <s:selectItems value="#{editBlogEntry.blogEntryStatusList}" var="blogEntryStatus" label="#{blogEntryStatus.name}" /> <s:convertEntity/> </h:selectOneMenu></td></tr> </table> <h:actionLink action=”#{editBlogEntry.save()}”/></h:form> ... </body> </html>

Page 38: Abstractie (Dutch)

Controller@Stateful @Name(“editBlogEntry”)public class EditBlogEntry { ... @In @Out private BlogEntry e;

public void setE(e) { this.e = e; }

public BlogEntry getE() { return this.e; }

public void save() { em.persist(e); } ...}

Page 39: Abstractie (Dutch)

Configuratie<?xml version="1.0" ?><web-app ...> <context-param> <param-name>facelets.LIBRARIES</param-name> <param-value>/WEB-INF/blog.taglib.xml</param-value> </context-param> <filter> <filter-name>Seam Filter</filter-name> <filter-class>org.jboss.seam.servlet.SeamFilter</filter-class> </filter> <filter> <filter-name>UrlRewriteFilter</filter-name> <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class> <init-param> <param-name>logLevel</param-name> <param-value>WARN</param-value> </init-param> </filter> <filter-mapping> <filter-name>Seam Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>UrlRewriteFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet> <servlet-name>Seam Resource Servlet</servlet-name> <servlet-class>org.jboss.seam.servlet.SeamResourceServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>*.seam</url-pattern> </servlet-mapping> ...</web-app>

Page 40: Abstractie (Dutch)

allemaal hetzelfde

Page 41: Abstractie (Dutch)

allemaal hetzelfde

Gebruiker

Page 42: Abstractie (Dutch)

allemaal hetzelfde

Gebruikermakenwijzigenverwijderenkoppelen

Page 43: Abstractie (Dutch)

allemaal hetzelfde

Gebruikermakenwijzigenverwijderenkoppelen

Bericht

Page 44: Abstractie (Dutch)

allemaal hetzelfde

Gebruikermakenwijzigenverwijderenkoppelen

Berichtmakenwijzigenverwijderenkoppelen

Page 45: Abstractie (Dutch)

allemaal hetzelfde

Gebruikermakenwijzigenverwijderenkoppelen

Berichtmakenwijzigenverwijderenkoppelen

Reactie

Page 46: Abstractie (Dutch)

allemaal hetzelfde

Gebruikermakenwijzigenverwijderenkoppelen

Berichtmakenwijzigenverwijderenkoppelen

Reactiemakenwijzigenverwijderenkoppelen

Page 47: Abstractie (Dutch)

allemaal hetzelfde

Gebruikermakenwijzigenverwijderenkoppelen

Berichtmakenwijzigenverwijderenkoppelen

Reactiemakenwijzigenverwijderenkoppelen

boiler plate code

Page 48: Abstractie (Dutch)
Page 49: Abstractie (Dutch)
Page 50: Abstractie (Dutch)

Data@Entitypublic class Blog { protected String _title = ""; public String getTitle() { return _title; } public void setTitle(String value) { _title = value; } @ManyToOne protected User _author; public User getAuthor() { return _author; } public void setAuthor(User author) { _title = value; } @OneToMany(mappedBy="_blog", targetEntity=BlogEntry.class) @Cascade(...) protected List<BlogEntry> _entries; public List<BlogEntry> getEntries() { return _entries; } public void setEntries(List<BlogEntry> entries) { _entries = entries; }}

Page 51: Abstractie (Dutch)

Data

entity Blog { author -> User (inverse=User.blogs) title :: String entries <> Set<BlogEntry>}

@Entitypublic class Blog { protected String _title = ""; public String getTitle() { return _title; } public void setTitle(String value) { _title = value; } @ManyToOne protected User _author; public User getAuthor() { return _author; } public void setAuthor(User author) { _title = value; } @OneToMany(mappedBy="_blog", targetEntity=BlogEntry.class) @Cascade(...) protected List<BlogEntry> _entries; public List<BlogEntry> getEntries() { return _entries; } public void setEntries(List<BlogEntry> entries) { _entries = entries; }}

Page 52: Abstractie (Dutch)

Pagina’s<html ...> ... <body> ... <h:form> <table> <tr><td><h:outputText value="Title: "/></td><td><h:inputText value="#{editBlogEntry.e.title}" /></td></tr><tr><td><h:outputText value="Created: "/></td><td><rich:calendar value="#{editBlogEntry.e.created}" popup="true" datePattern="dd/MM/yyyy" .../></td></tr><tr><td><h:outputText value="Content: "/></td><td><h:inputTextarea value="#{editBlogEntry.e.content}"/></td></tr><tr><td><h:outputText value="Status: "/></td><td><h:selectOneMenu value="#{editBlogEntry.e.status}"> <s:selectItems value="#{editBlogEntry.blogEntryStatusList}" var="blogEntryStatus" label="#{blogEntryStatus.name}" /> <s:convertEntity/> </h:selectOneMenu></td></tr> </table> <h:actionLink action=”#{editBlogEntry.save()}”/></h:form> ... </body> </html>

@Stateful @Name(“editBlogEntry”)public class EditBlogEntry { ... @In @Out private BlogEntry e;

public void setE(e) { this.e = e; }

public BlogEntry getE() { return this.e; }

public void save() { em.persist(e); } ...}

Page 53: Abstractie (Dutch)

Pagina’s

define page editBlogEntry(e : BlogEntry) { form{ table{ row{ "Title: " input(e.title) } row{ "Created: " input(e.created) } row{ "Content: " input(e.content) } row{ "Status: " input(e.status) } action("Save", save()) } } action save() { e.save(); return blogEntry(e); }}

<html ...> ... <body> ... <h:form> <table> <tr><td><h:outputText value="Title: "/></td><td><h:inputText value="#{editBlogEntry.e.title}" /></td></tr><tr><td><h:outputText value="Created: "/></td><td><rich:calendar value="#{editBlogEntry.e.created}" popup="true" datePattern="dd/MM/yyyy" .../></td></tr><tr><td><h:outputText value="Content: "/></td><td><h:inputTextarea value="#{editBlogEntry.e.content}"/></td></tr><tr><td><h:outputText value="Status: "/></td><td><h:selectOneMenu value="#{editBlogEntry.e.status}"> <s:selectItems value="#{editBlogEntry.blogEntryStatusList}" var="blogEntryStatus" label="#{blogEntryStatus.name}" /> <s:convertEntity/> </h:selectOneMenu></td></tr> </table> <h:actionLink action=”#{editBlogEntry.save()}”/></h:form> ... </body> </html>

@Stateful @Name(“editBlogEntry”)public class EditBlogEntry { ... @In @Out private BlogEntry e;

public void setE(e) { this.e = e; }

public BlogEntry getE() { return this.e; }

public void save() { em.persist(e); } ...}

Page 54: Abstractie (Dutch)

Pagina’s<html ...> ... <body> ... <h:form> <table> <tr><td><h:outputText value="Title: "/></td><td><h:inputText value="#{editBlogEntry.e.title}" /></td></tr><tr><td><h:outputText value="Created: "/></td><td><rich:calendar value="#{editBlogEntry.e.created}" popup="true" datePattern="dd/MM/yyyy" .../></td></tr><tr><td><h:outputText value="Content: "/></td><td><h:inputTextarea value="#{editBlogEntry.e.content}"/></td></tr><tr><td><h:outputText value="Status: "/></td><td><h:selectOneMenu value="#{editBlogEntry.e.status}"> <s:selectItems value="#{editBlogEntry.blogEntryStatusList}" var="blogEntryStatus" label="#{blogEntryStatus.name}" /> <s:convertEntity/> </h:selectOneMenu></td></tr> </table> <h:actionLink action=”#{editBlogEntry.save()}”/></h:form> ... </body> </html>

@Stateful @Name(“editBlogEntry”)public class EditBlogEntry { ... @In @Out private BlogEntry e;

public void setE(e) { this.e = e; }

public BlogEntry getE() { return this.e; }

public void save() { em.persist(e); } ...}

Page 55: Abstractie (Dutch)

Pagina’s

define page editBlogEntry(e : BlogEntry) { derive editPage from e}

<html ...> ... <body> ... <h:form> <table> <tr><td><h:outputText value="Title: "/></td><td><h:inputText value="#{editBlogEntry.e.title}" /></td></tr><tr><td><h:outputText value="Created: "/></td><td><rich:calendar value="#{editBlogEntry.e.created}" popup="true" datePattern="dd/MM/yyyy" .../></td></tr><tr><td><h:outputText value="Content: "/></td><td><h:inputTextarea value="#{editBlogEntry.e.content}"/></td></tr><tr><td><h:outputText value="Status: "/></td><td><h:selectOneMenu value="#{editBlogEntry.e.status}"> <s:selectItems value="#{editBlogEntry.blogEntryStatusList}" var="blogEntryStatus" label="#{blogEntryStatus.name}" /> <s:convertEntity/> </h:selectOneMenu></td></tr> </table> <h:actionLink action=”#{editBlogEntry.save()}”/></h:form> ... </body> </html>

@Stateful @Name(“editBlogEntry”)public class EditBlogEntry { ... @In @Out private BlogEntry e;

public void setE(e) { this.e = e; }

public BlogEntry getE() { return this.e; }

public void save() { em.persist(e); } ...}

Page 56: Abstractie (Dutch)
Page 57: Abstractie (Dutch)

10-50x

Page 58: Abstractie (Dutch)

WebDSL code

WebDSL compiler

Java applicatie(Java, JSF, Hibernate)

Page 59: Abstractie (Dutch)

valkuilen

Page 60: Abstractie (Dutch)

entity User { username :: String password :: Secret}

entity Update { user -> User date :: DateTime text :: Text}

Page 61: Abstractie (Dutch)

entity User { username :: String password :: Secret}

entity Update { user -> User date :: DateTime text :: Text}

define page home() { for(u : Update) { output(u.user.username) ": " output(u.text) spacer }}

Page 62: Abstractie (Dutch)

entity User { username :: String password :: Secret}

entity Update { user -> User date :: DateTime text :: Text}

define page home() { for(u : Update) { output(u.user.username) ": " output(u.text) spacer }}

Page 63: Abstractie (Dutch)

define page home() { header{ "Twitr" } spacer for(u : Update) { output(u.user.username) ": " output(u.text) spacer } "(C) Zef Hemel"}

Page 64: Abstractie (Dutch)

define page login() { header{ "Twitr" } spacer var u : User

form { "Login: " input(u) action("Login", login())

action login() { session.user := u; return home(); } } spacer "(C) Zef Hemel"}

Page 65: Abstractie (Dutch)

define page login() { header{ "Twitr" } spacer var u : User

form { "Login: " input(u) action("Login", login())

action login() { session.user := u; return home(); } } spacer "(C) Zef Hemel"}

Page 66: Abstractie (Dutch)

template abstractie!

Page 67: Abstractie (Dutch)

define template main() { header{ "Twitr" } spacer body() "(C) Zef Hemel"}

define page home() { main() define body() { for(u : Update) { output(u.user.username) ": " output(u.text) spacer } }}

Page 68: Abstractie (Dutch)

WebDSL code

WebDSL compiler

Template expander

Java applicatie(Java, JSF, Hibernate)

Page 69: Abstractie (Dutch)

template expanderdefine page home() { main() define body() for(u : Update) { output(u.user.username) ": " output(u.text) spacer } }}

define page home() { header{ "Twitr" } spacer for(u : Update) { output(u.user.username) ": " output(u.text) spacer } "(C) Zef Hemel"}

Page 70: Abstractie (Dutch)

maar...

JSF had ook al templates

Page 71: Abstractie (Dutch)

WebDSL code

WebDSL compiler

Template expander

Java applicatie(Java, JSF, Hibernate)templates

Page 72: Abstractie (Dutch)

WebDSL code

WebDSL compiler

Template expander

Java applicatie(Java, JSF, Hibernate)templates

templates

Page 73: Abstractie (Dutch)

WebDSL code

WebDSL compiler

Template expander

Java applicatie(Java, JSF, Hibernate)templates

templates

herimplementeerttemplates

Page 74: Abstractie (Dutch)

abstraction inversion

WebDSL code

WebDSL compiler

Template expander

Java applicatie(Java, JSF, Hibernate)templates

templates

herimplementeerttemplates

Page 75: Abstractie (Dutch)

abstraction inversion

WebDSL code

WebDSL compiler

Template expander

Java applicatie(Java, JSF, Hibernate)templates

templates

herimplementeerttemplates

slechte abstractie

Page 76: Abstractie (Dutch)
Page 77: Abstractie (Dutch)

“All non-trivial abstractions, to some

degree, are leaky.”

-- Joel Spolsky

Page 78: Abstractie (Dutch)

abstracties verbergen implementatie

Page 79: Abstractie (Dutch)

abstracties verbergen implementatie

dat lukt eigenlijk nooit volledig

Page 80: Abstractie (Dutch)

abstracties verbergen implementatie

dat lukt eigenlijk nooit volledig

WebDSL templates

Page 81: Abstractie (Dutch)

abstracties verbergen implementatie

dat lukt eigenlijk nooit volledig

WebDSL templatesNFS/SMB

Page 82: Abstractie (Dutch)

abstracties verbergen implementatie

dat lukt eigenlijk nooit volledig

WebDSL templatesNFS/SMBtwee-dimensionale arrays

Page 83: Abstractie (Dutch)

abstracties verbergen implementatie

dat lukt eigenlijk nooit volledig

WebDSL templatesNFS/SMBtwee-dimensionale arraysSQL

Page 84: Abstractie (Dutch)

conclusie

Page 85: Abstractie (Dutch)

abstractie is essentieel

Page 86: Abstractie (Dutch)

abstractie is essentieelmoeilijk

Page 87: Abstractie (Dutch)

denk kritisch na

Page 88: Abstractie (Dutch)

denk kritisch na

heb ik dit vaker gedaan?

Page 89: Abstractie (Dutch)

denk kritisch na

heb ik dit vaker gedaan?gaat iemand dit vaker doen?

Page 90: Abstractie (Dutch)

ja?

abstraheer