removed unecessary parts
|
@ -1,724 +0,0 @@
|
|||
\part{Pattern im Projekt}
|
||||
\section{Layers Pattern}
|
||||
\subsection{Erkläre die Funktionsweise + Skizze}
|
||||
\begin{itemize}
|
||||
\item Client schickt eine Anfrage an Layer N
|
||||
\item Layer N reicht da er nicht vollständig alleine beantworten kann, Anfragen an darunterliegenden Layer weiter
|
||||
\item Eine Anfrage kann bei Bedarf auch in mehrere Anfragen an darunterliegende Layer geteilt werden
|
||||
\item dies wird immer weiter fortgesetzt bis Layer 1 erreicht ist
|
||||
\item dabei gehen Abhängigkeiten nur von oben nach unten
|
||||
\end{itemize}
|
||||
\begin{figure}[!htp]
|
||||
\centering
|
||||
\includegraphics[width=0.5\textwidth]{pics/esa_layers.jpg}
|
||||
\end{figure}
|
||||
\subsubsection{3 Schichten Architektur:}
|
||||
\begin{itemize}
|
||||
\item Data Source Layer (data): Zugriff auf Daten, kümmert sich um Kommunikation mit anderen Systemen (z.B.: Datenbank)
|
||||
\begin{itemize}
|
||||
\item beinhaltet DAO und DAOImpl >> DocumentDAO, DocumentlibraryDAO
|
||||
\end{itemize}
|
||||
\item Domain Layer(service): enthält Business Logik (Berechnungen, Datenvalidierung, ...)
|
||||
\begin{itemize}
|
||||
\item beinhaltet
|
||||
\begin{itemize}
|
||||
\item \textbf{Service Layer Pattern} (aka Session Fassade - siehe~\ref{sec:slp})
|
||||
\item DTO >> DocumentDTO
|
||||
\item Mapper >> DocumentMapper
|
||||
\begin{minted}[breaklines=true]{java}
|
||||
public static Document toEntity(DocumentDTO documentDTO, Document document){};
|
||||
public static DocumentDTO toDTO(Document document){};
|
||||
\end{minted}
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
\item Presentation Layer(web): serverseitig, kümmert sich um Benutzerinteraktion
|
||||
\begin{itemize}
|
||||
\item Controller (ViewHelper) >> DocumentController, DocumentListController
|
||||
\item View (WebApp)
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
\begin{figure}[!htp]
|
||||
\centering
|
||||
\includegraphics[width=0.4\textwidth]{pics/tree-projectmain.png}
|
||||
\includegraphics[width=0.4\textwidth]{pics/web-2ndpart.jpg}
|
||||
\end{figure}
|
||||
\subsection{Beschreibe ein konkretes Anwendungsbeispiel}
|
||||
\begin{itemize}
|
||||
\item Java Enterprise Edition (JEE) Architektur bestehend aus
|
||||
\begin{itemize}
|
||||
\item Client Tier (Client Machine)
|
||||
\item Web Tier, Business Tier (Java EE Server)
|
||||
\item EIS Tier (Database Server)
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
\section{Data Access Object (DAO) Pattern}
|
||||
Befindet sich im Projekt in data und damit innerhalb des Data Layer.
|
||||
\subsection{Erkläre die Funktion + Skizze}
|
||||
\begin{itemize}
|
||||
\item Client erstellt ein DAO Object und kann nach Entitäten suchen, einfügen, löschen, etc.
|
||||
\item das DAO selbst soll keine spezifischen Elemente enthalten (Entity Manager, SQL Exception -> stattdessen DAOException)
|
||||
\item dadurch entsteht eine Kapselung bei der die DAOImpl ohne den Client zu verändern ausgetauscht werden kann
|
||||
\end{itemize}
|
||||
\begin{figure}[!htp]
|
||||
\centering
|
||||
\includegraphics[width=0.8\textwidth]{pics/dao_pat1.jpg}
|
||||
\end{figure}
|
||||
\begin{minted}[breaklines=true]{java}
|
||||
@ApplicationScoped
|
||||
public class DocumentDAOImpl implements DocumentDAO, Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Logger logger = LoggerFactory.getLogger(DocumentDAOImpl.class);
|
||||
@PersistenceContext
|
||||
private EntityManager entityMangaer;
|
||||
|
||||
@Override
|
||||
public List<Document> findByCommunity(Community community) {...}
|
||||
|
||||
@Override
|
||||
public List<Document> findByUser(User user) {...}
|
||||
|
||||
@Override
|
||||
public void insert(Document document) {...}
|
||||
|
||||
@Override
|
||||
public void delete(Document document) {...}
|
||||
|
||||
@Override
|
||||
public Document findById(Long id) {...}
|
||||
}
|
||||
\end{minted}
|
||||
\subsection{Nenne die Konsequenzen der Anwendung}
|
||||
\begin{itemize}
|
||||
\item Zugriff auf persistenten Speicher wird abstrahiert
|
||||
\item Details des Speichers werden versteckt
|
||||
\item ermöglicht einheitlichen Zugriff auf Daten
|
||||
\item entkoppelt Implementierung von Persistierung (Datenbank,...)
|
||||
\item ermöglicht Objektorientierte Ansicht des Speichers
|
||||
\end{itemize}
|
||||
\section{Service Layer Pattern (auch Session Fassade)}\label{sec:slp}
|
||||
\subsection{Erkläre die Funktion + Skizze}\label{subsubsec:service-layer-pattern}
|
||||
\begin{itemize}
|
||||
\item Der Service Layer delegiert auf die Business Logik (Zeile 68 community.setDocumentlibrary) und zum DAO (z.B. Zeile 66)
|
||||
\item Bei wenig Logik wird zumindest Transaktions (Zeile 40), Error (ab Zeile 42) und Validierungshandling (ab Zeile 23) im Service erledigt
|
||||
\end{itemize}
|
||||
\begin{minted}[xleftmargin=\parindent,linenos,breaklines=true]{java}
|
||||
@Local(DocumentService.class)
|
||||
@Remote(DocumentServiceRemote.class)
|
||||
@Stateless
|
||||
public class DocumentServiceImpl implements DocumentService, DocumentServiceRemote, Serializable {
|
||||
private static final long serialVersionUID = -1L;
|
||||
private static final Logger logger = LoggerFactory.getLogger(DocumentServiceImpl.class);
|
||||
|
||||
@Inject
|
||||
private DocumentDAO documentDAO;
|
||||
@Inject
|
||||
private DocumentlibraryDAO documentlibraryDAO;
|
||||
@Inject
|
||||
private CommunityDAO communityDAO;
|
||||
@Inject
|
||||
private UserDAO userDAO;
|
||||
@Inject
|
||||
private MessageDAO messageDAO;
|
||||
@Override
|
||||
public DocumentDTO addDocument(Long communityID, String userID, byte[] data, String filename) {
|
||||
Document addedDocument;
|
||||
User user;
|
||||
|
||||
// Validierungshandling gefolgt von Error Handling
|
||||
try {
|
||||
if (communityID <= 0) throw new IllegalArgumentException("community must not be empty");
|
||||
if (userID == null) throw new IllegalArgumentException("user must not be empty");
|
||||
if (data == null) throw new IllegalArgumentException("uploaded file must not be empty");
|
||||
if (filename == null) throw new IllegalArgumentException("filename must not be empty");
|
||||
|
||||
Documentlibrary documentlibrary = documentlibraryDAO.findByCommunityId(communityID);
|
||||
|
||||
//create a document library, if there isn't already one in the database
|
||||
if (documentlibrary == null) {
|
||||
documentlibrary = addDocumentlibrary(communityID);
|
||||
}
|
||||
|
||||
user = userDAO.getByUserId(userID);
|
||||
|
||||
addedDocument = new Document(documentlibrary, user, filename, data);
|
||||
documentDAO.insert(addedDocument); // Transaktionshandling
|
||||
logger.info(String.format("Document %s saved in database", filename));
|
||||
// Error Handling
|
||||
} catch (IllegalArgumentException iaex) {
|
||||
String errorMsg = "Uploading file failed (illegal argument)";
|
||||
logger.error(errorMsg, iaex);
|
||||
throw new ServiceException(errorMsg);
|
||||
|
||||
} catch (Exception ex) {
|
||||
String errorMsg = String.format("Uploading file %s failed.", filename);
|
||||
logger.error(errorMsg, ex);
|
||||
throw new ServiceException(errorMsg);
|
||||
}
|
||||
|
||||
String msgText = "Uploaded Document " + filename + " by user " + user.getUserId();
|
||||
addMessageToStream(communityID, user, msgText, addedDocument);
|
||||
return DocumentMapper.toDTO(addedDocument);
|
||||
}
|
||||
|
||||
|
||||
private void addMessageToStream(Long communityID, User user, String text, Document document) {...}
|
||||
|
||||
private Documentlibrary addDocumentlibrary(Long communityID) {
|
||||
logger.info("Create missing documentlibrary");
|
||||
Community community;
|
||||
Documentlibrary documentlibrary = new Documentlibrary();
|
||||
documentlibraryDAO.insert(documentlibrary); // Delegation zum DAO
|
||||
community = communityDAO.findById(communityID); // Delegation zum DAO
|
||||
community.setDocumentlibrary(documentlibrary); // Delegation zur Business Logik (Entity)
|
||||
communityDAO.update(community); // Delegation zum DAO
|
||||
return documentlibrary;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DocumentDTO> getDocumentsFromCommunity(Long communityID) {...}
|
||||
|
||||
@Override
|
||||
public List<DocumentDTO> getDocumentsFromUser(String userID) {...}
|
||||
|
||||
@Override
|
||||
public void removeDocument(Long documentID) {...}
|
||||
|
||||
@Override
|
||||
public DocumentDTO getDocumentById(Long documentID) {...}
|
||||
}
|
||||
\end{minted}
|
||||
\begin{figure}[!htp]
|
||||
\centering
|
||||
\includegraphics[width=0.8\textwidth]{pics/sl_pat1.jpg}
|
||||
\end{figure}
|
||||
\subsection{Nenne die Konsequenzen der Anwendung}
|
||||
\begin{itemize}
|
||||
\item Reduzierung der Abhängigkeiten zwischen Presentation und Domain Layer
|
||||
\item Zentralisiertes Sicherheits und Transaktionshandling
|
||||
\item verbirgt vor Client Komplexität der Business Logik
|
||||
\item stellt Client ein grobkörniges Interface zur Verfügung
|
||||
\item gut für Remote Aufrufe geeignet (weniger Aufrufe)
|
||||
\end{itemize}
|
||||
|
||||
\section{Model-View-Controller (MVC) Pattern}
|
||||
\subsection{Erkläre die Funktion + Skizze}
|
||||
MVC unterteilt eine interaktive Applikation in drei Teile: Model, View und Controller.
|
||||
\begin{itemize}
|
||||
\item Controller und View befinden sich im Presentation Layer und haben gegenseitig Abhängigkeiten
|
||||
\item Das Model darf keine Abhängigkeiten haben (Controller und View hängen vom Model ab)
|
||||
\end{itemize}
|
||||
\begin{figure}[!htp]
|
||||
\centering
|
||||
\includegraphics[width=0.8\textwidth]{pics/mvc_pat.jpg}
|
||||
\end{figure}
|
||||
\subsubsection{Model}
|
||||
\begin{itemize}
|
||||
\item Es befinden sich Teile im Domain und Data Source Layer.
|
||||
\item Das Model enthält die Kernfunktionalität und Daten. (z.B.: Datenbankzugriff)
|
||||
\item Im Projekt ... % TODO
|
||||
\end{itemize}
|
||||
\subsubsection{View}
|
||||
\begin{itemize}
|
||||
\item Im Projekt im Ordner WebApp zu finden.
|
||||
\item Enthält im Projekt xhtml Dateien zur Darstellung und User Interaktion
|
||||
\end{itemize}
|
||||
\subsubsection{Controller}
|
||||
\begin{itemize}
|
||||
\item Im Projekt sind Controllerklassen im Ordner web zu finden.
|
||||
\item Sie enthalten die Logik und behandeln Benutzereingaben
|
||||
\end{itemize}
|
||||
\subsection{Nenne die Konsequenzen der Anwendung}
|
||||
\begin{itemize}
|
||||
\item Visualisierung abhängig vom Model - nicht umgekehrt
|
||||
\item verschiedene Darstellungen möglich
|
||||
\item einfaches Testen der Domain-Logik
|
||||
\item gute Strukturierung
|
||||
\item View wird leichter austausch bzw. änderbar
|
||||
\end{itemize}
|
||||
\section{Front Controller}
|
||||
\subsection{Erkläre die Funktion + Skizze}
|
||||
\begin{itemize}
|
||||
\item Client schickt Request an Front Controller
|
||||
\item FC erfasst nur Infos die er für die weiter Delegation braucht
|
||||
\item FC gibt Request an entsprechenden ConcreteCommand oder View weiter
|
||||
\item es gibt zwei Implementierungsvarianten des Controller
|
||||
\begin{multicols}{2}
|
||||
\begin{itemize}
|
||||
\item Servlet
|
||||
\item ConcreteCommand
|
||||
\end{itemize}
|
||||
\end{multicols}
|
||||
\end{itemize}
|
||||
\begin{figure}[h!]
|
||||
\centering
|
||||
\includegraphics[width=0.5\textwidth]{pics/fc_pat.jpg}
|
||||
\end{figure}
|
||||
\subsection{Beschreibe ein konkretes Anwendungsbeispiel}
|
||||
\begin{itemize}
|
||||
\item Java Server Faces (bei Java Server Faces enthält das File zwar keinen Java Code, interagiert aber direkt mit Java Code einer Backing Bean)
|
||||
\item Im Projekt wurde der Front Controller in Form eines Servlet realisiert, dessen Einbindung in der Konfigurationsdatei "`web.xml"' erfolgt:
|
||||
\end{itemize}
|
||||
\begin{minted}[linenos,breaklines=true]{xml}
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
|
||||
...
|
||||
<servlet>
|
||||
<servlet-name>Faces Servlet</servlet-name>
|
||||
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
</servlet>
|
||||
<servlet-mapping>
|
||||
<servlet-name>Faces Servlet</servlet-name>
|
||||
<url-pattern>*.xhtml</url-pattern>
|
||||
</servlet-mapping>
|
||||
\end{minted}
|
||||
\subsection{Anwendung im Projekt}
|
||||
JavaServer Faces: mächtiges Framework, wo das MVC Pattern verwendet wird. Auf der einen Seite
|
||||
stehen die reinen Views (XHTML Seiten) und auf der anderen Seite Java Beans (Java Klassen), die als
|
||||
View Helper fungieren können. Beispiel: layered/MVC-JSF
|
||||
Primefaces ist eine konkrete Implementierung der JavaServer Faces (siehe POM.XML).
|
||||
|
||||
\begin{minted}[linenos,breaklines=true]{xml}
|
||||
<?xml version='1.0' encoding='UTF-8' ?>
|
||||
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
|
||||
xmlns:h="http://xmlns.jcp.org/jsf/html"
|
||||
xmlns:p="http://primefaces.org/ui"
|
||||
xmlns:f="http://xmlns.jcp.org/jsf/core"
|
||||
template="communityTemplate.xhtml">
|
||||
<ui:define name="communityContent">
|
||||
<h1>#{msg.document_manage_title}</h1>
|
||||
<f:metadata>
|
||||
<f:viewAction action="#{documentListController.loadDocumentsFromCommunity()}" />
|
||||
</f:metadata>
|
||||
|
||||
<h:form id="doclistform">
|
||||
<p:commandButton value="Refresh list" actionListener="#{documentListController.loadDocumentsFromCommunity()}" update="@form doclistform"></p:commandButton>
|
||||
<p:dataTable id="doclisttable" value="#{documentListController.communityDocuments}" var="docs">
|
||||
<p:column class="documenttimecolumn" headerText="#{msg.document_uploaded}">#{docs.createdTimestamp}</p:column>
|
||||
<p:column class="documenttimecolumn" headerText="#{msg.label_userid}">#{docs.user.userId}</p:column>
|
||||
<p:column headerText="#{msg.label_filename}">#{docs.filename}</p:column>
|
||||
<p:column headerText="" class="documentbuttoncolumn">
|
||||
<p:commandButton value="#{msg.button_download}" ajax="false"
|
||||
onclick="PrimeFaces.monitorDownload(start, stop);">
|
||||
<p:fileDownload value="#{documentController.downloadDocument(docs.id)}"/>
|
||||
</p:commandButton>
|
||||
</p:column>
|
||||
<p:column headerText="" class="documentbuttoncolumn">
|
||||
<p:commandButton id="btnDel" value="#{msg.button_delete}"
|
||||
actionListener="#{documentController.removeDocument(docs.id)}"
|
||||
update="@form doclistform">
|
||||
</p:commandButton>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</h:form>
|
||||
<h:form id="formdocupload" enctype="multipart/form-data">
|
||||
<p:fileUpload id="fileupload"
|
||||
dragDropSupport="false"
|
||||
update="@form doclistform"
|
||||
fileUploadListener="#{documentController.uploadDocument}"
|
||||
allowTypes="/(\.|\/)(pdf|jpe?g|docx)\$/" sizeLimit="5000000"
|
||||
mode="advanced" label="Add document (.pdf .jpg .docx)">
|
||||
</p:fileUpload>
|
||||
</h:form>
|
||||
<p:messages id="feedbackBox" severity="info,error" showDetail="true" showSummary="false">
|
||||
<p:autoUpdate/>
|
||||
</p:messages>
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
\end{minted}
|
||||
|
||||
\subsection{Nenne die Konsequenzen der Anwendung}
|
||||
\begin{itemize}
|
||||
\item es muss nur EIN (Front) Controller konfiguriert werden
|
||||
\item da bei jedem Request ein neues Command Objekt erzeugt wird ist Thread-Safety nicht notwendig
|
||||
\item da nur EIN Controller sind auch Erweiterungen durch z.B.: Decorator einfach (auch zur Laufzeit)
|
||||
\end{itemize}
|
||||
\section{View Helper}
|
||||
\subsection{Erkläre die Funktion + Skizze}
|
||||
\begin{figure}[h!]
|
||||
\centering
|
||||
\includegraphics[width=0.8\textwidth]{pics/view-helper_pat1.jpg}
|
||||
\end{figure}
|
||||
\begin{itemize}
|
||||
\item View (xhtml-Dateien im Ordner webapp) delegiert Aufgaben an Helper (*Controller-Klassen - z.B. DocumentController im Ordner web)
|
||||
\item Helper adaptieren View zu Model (Klassen in den Ordnern service und data)
|
||||
\item in View befindet sich HTML Code im ViewHelper Java Code zur Aufbereitung der Daten (+ wenig HTML)
|
||||
\end{itemize}
|
||||
\subsection{Nenne die Konsequenzen der Anwendung}
|
||||
\begin{itemize}
|
||||
\item kapselt Design-Code in View und View-Processing-Code Logik in Helper
|
||||
\item steigert Wiederverwendbarkeit, Wartbarkeit und Strukturierungsqualität der Anwendung
|
||||
\item vereinfacht Tests (Helperfunktionen ohne View)
|
||||
\item bessere Trennung zwischen
|
||||
\begin{itemize}
|
||||
\item Presentation und Data Source Layer
|
||||
\item Entwickler und Designer
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
|
||||
|
||||
\section{Dependency Injection (don't call us, we'll call you)}
|
||||
\subsection{Erkläre die Funktion + Skizze}
|
||||
\begin{figure}[!htp]
|
||||
\centering
|
||||
\includegraphics[width=0.5\textwidth]{pics/dependency_inj_pat.jpg}
|
||||
\includegraphics[width=0.4\textwidth]{pics/dependency_inj_spring_pat.jpg}
|
||||
\end{figure}
|
||||
\begin{itemize}
|
||||
\item Grundidee sind loose gekoppelte Objekte
|
||||
\item Objekte werden mittels externem Assembler verknüpft
|
||||
\item Abhängigkeiten bestehen nur auf Interfaces
|
||||
\item Assembler Objekt (Framework) erzeugt die Interface-Implementierungen (z.B.: durch Factory)
|
||||
\item Es wird zwischen Constructor Injection und Setter Injection unterschiedlichen
|
||||
\begin{minted}[linenos,breaklines=true]{java}
|
||||
// Constructor Injection
|
||||
puplic class Client
|
||||
{
|
||||
private Interface iface;
|
||||
public Client(Interface iface)
|
||||
{
|
||||
this.iface = iface;
|
||||
}}
|
||||
|
||||
// Setter Injection
|
||||
puplic class Client
|
||||
{
|
||||
private Interface iface;
|
||||
public setIface(Interface iface)
|
||||
{
|
||||
this.iface = iface;
|
||||
}}
|
||||
\end{minted}
|
||||
\end{itemize}
|
||||
\begin{itemize}
|
||||
\item Im Spring Context: Dependency Injection mit XML-Datei
|
||||
\item alle Beans sind dort gelistet und werden verknüpft
|
||||
\item Context wird geladen damit alles verknüpft ist
|
||||
\item erspart Factories
|
||||
\end{itemize}
|
||||
\subsection{Nenne die Konsequenzen der Anwendung}
|
||||
\begin{itemize}
|
||||
\item loose gekoppelte Objekte
|
||||
\item Referenzen nurmehr auf Interfaces
|
||||
\item hohe Flexibilität (Strategy, Proxy,..)
|
||||
\item bessere Erweiterbarkeit und Testbarkeit
|
||||
\item bei Spring kann Dependency Injection mittels XML oder Annotation erfolgen
|
||||
\begin{itemize}
|
||||
\item Vorteil Annotation: Typ-Sicherheit (Tippfehler passieren schnell im XML)
|
||||
\item Nachteil Annotation: nicht so flexibel wie XML
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
\section{Data Transfer Object (DTO) Pattern}
|
||||
\subsection{Erkläre die Funktion (Skizze - ein Grund für DTO)}
|
||||
\begin{figure}[!htp]
|
||||
\centering
|
||||
\includegraphics[width=0.9\textwidth]{pics/lok-vs-remote.jpg}
|
||||
\end{figure}
|
||||
\begin{itemize}
|
||||
\item Transportiert Daten zwischen Prozessen um Remote Methodenaufrufe zu minimieren
|
||||
\item besteht aus Fields, Getter und Setter
|
||||
\item fasst Daten verschiedener Objekte zusammen die vom Remote Objekt benötigt werden
|
||||
\item ev. Map, Record Set, ...
|
||||
\end{itemize}
|
||||
\subsection{Beschreibe ein konkretes Anwendungsbeispiel}
|
||||
% todo: Anwendungsbeispiel
|
||||
\subsection{Nenne die Konsequenzen der Anwendung}
|
||||
\begin{itemize}
|
||||
\item kapselt und versteckt
|
||||
\item nimmt Komplexität
|
||||
\item steigert Effizienz da weniger Aufrufe über Remotegrenze
|
||||
\end{itemize}
|
||||
\section{Page-Object-Pattern}
|
||||
PageObjectPattern
|
||||
|
||||
HTML – wrappen mit JavaCode, um es zu manipulieren
|
||||
|
||||
GUI-Test-Klasse und Page-Object
|
||||
|
||||
Über die Page-Object-Klasse manipuliere ich das HTML-Dokument
|
||||
|
||||
Bei HTML-Änderung muss ich nur Page-Objekt ändern und ansonsten nichts angreifen (Verkapselung)
|
||||
\section{Remote}
|
||||
\section{Beschreibe die Unterschiede zwischen lokalem und Remote Interface Design}
|
||||
\begin{itemize}
|
||||
\item Aufrufe innerhalb des Prozesses sind schneller als über Prozessgrenzen
|
||||
\item lokale Interfaces sind möglichst fein-granular während Remote Interfaces grob-granular sein müssen (weniger Aufrufe - Effizienz)
|
||||
\item viele kleine Aufrufe mit wenigen Daten sind "teuer" (Latenz durch Verbindungsherstellung)
|
||||
\end{itemize}
|
||||
\section{Beschreibe drei Situationen wo Multiple Prozesse in Applikationen verwendet werden müssen}
|
||||
\begin{itemize}
|
||||
\item Trennung zwischen Clients und Servern in Business Software
|
||||
\item Trennung zwischen server-basierter Applikationssoftware und Datenbank (SQL ist als Remote Interface designed, daher sind hier schnelle Abfragen möglich)
|
||||
\item Trennung wegen unterschiedlichen Anbietern oder Programmiersprachen
|
||||
\end{itemize}
|
||||
|
||||
\section{Beschreibe das folgende Diagramm. Was können wir daraus für das Design von Remote Interfaces folgern?}
|
||||
\begin{itemize}
|
||||
\item speziell bei "teuren" Remote Calls ist es empfehlenswert weniger Calls mit großen Datenmengen anstatt vielen Calls mit wenigen Daten zu machen
|
||||
\item dieser Gedanke befürwortet auch den Einsatz von DTO um Calls und Daten zu bündeln
|
||||
\end{itemize}
|
||||
\begin{figure}[!htp]
|
||||
\centering
|
||||
\includegraphics[width=0.9\textwidth]{pics/lok-vs-remote.jpg}
|
||||
\end{figure}
|
||||
\section{Exception Handling}
|
||||
\section{Beschreibe den Unterschied zwischen Checked und Runtime Exceptions in Java (inkl. Klassendiagramm)}
|
||||
\begin{itemize}
|
||||
\item Checked Exceptions (z.B. SQL-Exception) leiten von Exception Klasse ab und müssen behandelt werden (trows - catch)
|
||||
\begin{itemize}
|
||||
\item Verwendung für Probleme die durch User behoben werden können (alternative Aktion)
|
||||
\end{itemize}
|
||||
\item Unchecked Exceptions (z.B. NullPointerException) leiten von RuntimeException ab
|
||||
\begin{itemize}
|
||||
\item Verwendung für technische Probleme (User kann nichts machen außer neu starten)
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
\begin{figure}[!htp]
|
||||
\centering
|
||||
\includegraphics[width=0.3\textwidth]{pics/except_class_dia.jpg}
|
||||
\end{figure}
|
||||
\section{Beschreibe einen Use Case für eine Checked Exceptions in Java}
|
||||
\begin{itemize}
|
||||
\item eine Netzwerkübertragung schlägt fehl - es ist vorgesehen, dass der Applikations-User dies neu anstoßen kann
|
||||
\end{itemize}
|
||||
\section{Beschreibe einen Use Case für eine Runtime Exceptions in Java}
|
||||
\begin{itemize}
|
||||
\item Die Datenbank ist beschädigt - die Exception geht durch alle Layer erst mit
|
||||
Implementierungsspezifischer Exception später mit Runtime ohne Stacktrace (Sicherheit) bis zum User.
|
||||
\end{itemize}
|
||||
\section{Beschreibe 5 Best Practice Beispiele beim Einsatz von Exceptions}
|
||||
\begin{itemize}
|
||||
\item Exceptions nicht für Programmflusskontrolle verwenden (schlechte Performance)
|
||||
\item offene Ressourcen schließen (try-with-resources bzw. close im finally)
|
||||
\item selbst erstellte Exceptions auch mit nützlichen Infos ausstatten
|
||||
\item Implementierungsspezifische Exceptions nicht bis zum User durchwerfen (stattdessen catch + trow RuntimeException)
|
||||
\item dokumentieren mit @trows im DOC, testen mit JUnit
|
||||
\end{itemize}
|
||||
|
||||
\section{Beschreibe 5 Exception Handling Anti Pattern}
|
||||
\begin{itemize}
|
||||
\item Log and Trow (nie beides: entweder, oder)
|
||||
\item Trowing Exception bzw. catch Exception (spezifischere anstatt Basisklasse verwenden)
|
||||
\item Destructive Wrapping (wenn bei catch + trow = wrapping nicht die Original Exception weitergegeben wird)
|
||||
\item Log and return Null (provoziert an einer anderen Stelle eine NullPointerException)
|
||||
\item Catch and Ignore
|
||||
\item Unsupported Operation return Null (besser UnsupportedOperationException)
|
||||
\end{itemize}
|
||||
\section{Logging}
|
||||
\section{Nenne die Nachteile von debugging mit printf() sowie die Vorteile die Logging Frameworks wie log4j bieten}
|
||||
\subsection{Nachteile printf()}
|
||||
\begin{itemize}
|
||||
\item Produktiv-Code wird überfüllt -> erschwert Lesbarkeit
|
||||
\item Consolenausgabe wird bei vielen prints auch schnell unübersichtlich
|
||||
\item im Falle eines vorzeitigen Absturzes können Ausgabedaten verloren gehen
|
||||
\item Performance bei vielen Logprints
|
||||
\end{itemize}
|
||||
\subsection{Vorteile Logging mittels Framework (z.B.: log4j)}
|
||||
\begin{itemize}
|
||||
\item Nutzt ein einheitliches Format / Konventionen
|
||||
\item logging kann optional an und ausgeschalten werden
|
||||
\item durch verschiedene Log-level können Logs gefiltert erstellt werden
|
||||
\item Layout für Ausgabe kann zentral definiert/geändert werden
|
||||
\end{itemize}
|
||||
\section{Project Structure}
|
||||
\begin{figure}[!htp]
|
||||
\centering
|
||||
\includegraphics[width=0.4\textwidth]{pics/tree-project-main.png}
|
||||
\includegraphics[width=0.4\textwidth]{pics/tree-project-test.png}
|
||||
\end{figure}
|
||||
\section{Toni}
|
||||
\section{Annotationen}
|
||||
\subsection{@MappedSuperclass}
|
||||
\begin{itemize}
|
||||
\item ist im Hybernate Framework eine Klasse durch die gemeinsame Felder definiert werden.
|
||||
\item definiert eine abstrakte Superklasse
|
||||
\end{itemize}
|
||||
|
||||
@Produces – kommt während deployment, markiert Factory Method damit man nicht direkt auf die Klasse zugreifen muss
|
||||
@Typed – zeigt die Vererbung Wieso bei uns allein stehend?
|
||||
@Named – Zeigt bei Mehrdeutigkeit das richtige Objekt mit dem Namen
|
||||
@Resource – fast wie Dependency Injection
|
||||
@Stateless – speichert den Client Status nicht
|
||||
@Entity – Data Access Layer
|
||||
@Table – Tabellenname im SQL
|
||||
@Column – SQL-Spalten nullable=false
|
||||
@OneToMany Beziehung
|
||||
@JoinColums – welche Spalten zusammen gehören FK
|
||||
@OneToMany FK auf anderen Seite
|
||||
@ApplicationScoped – lebt die ganze Applikation lang, wird einmal gemacht.
|
||||
@PersistenceContext – persistance.xml auslesen für Treiber und andere JPA Geschichten + Data Source. Entity Manager Injection.
|
||||
@Id – das ist die id
|
||||
@GeneratedValue – Wert kommt aus der DB
|
||||
@Local – Klasse für lokale Aufrufe.
|
||||
@Remote – interprozessaufrufe. RMI
|
||||
@ApplicationException – Rollback wenn so eine Exception kommt, Nachricht zum Client.
|
||||
\section{Patterns in Practice}
|
||||
Data Access Layer
|
||||
Entity – Java Repräsentation vom DB Entity
|
||||
DAO damit man auf die Entities zugreifen kann. DB abstrahieren. Methoden mit denen man auf die DB zugreifen kann.
|
||||
DAOImpl – Implementierung
|
||||
DAOImpl – DAOException fehlt. Schlecht weil Input wird nicht kontrolliert. EntityManager in try catch, sonst kann es kleschen. Zusätzlich in DaoException wrappen.
|
||||
AbstractEntity – hier wird die id gemanaged
|
||||
Service Layer
|
||||
DTO – Aufrufgeschw. Verringern, nicht jedes Objekt einzeln aufrufen, sondern mit einmal alle notwendigen Objekte.
|
||||
Mapper – von DTO in Entity und Entity ins DTO.
|
||||
|
||||
FrontController web.xml
|
||||
ViewHelper *ServiceImpl
|
||||
\section{Konfigurationsdateien (pom.xml), (persistence.xml) und noch a bissl mehr Scheiß}
|
||||
Resource plugin – klar für Ressourcen
|
||||
Wildfly – server
|
||||
Primeafce = jsf Framework
|
||||
Jacoco = test Coverage
|
||||
Slf4j = logger
|
||||
Jaxb – xml
|
||||
Cdi = context dependancy injection
|
||||
\section{Reihenfolge - Wildfly - Abfolge - einzelne Schritte}
|
||||
Reihenfolge:
|
||||
\begin{multicols}{2}
|
||||
\begin{enumerate}
|
||||
\item Compile
|
||||
\item Surefire (unitTests)
|
||||
\item Packaging - war file erstellen
|
||||
\item Wildfly - fressen und deployen
|
||||
\item Failsafe IT-test
|
||||
\item MVN site
|
||||
\item Gui test
|
||||
\end{enumerate}
|
||||
\end{multicols}
|
||||
|
||||
\section{Frageart Prüfung}
|
||||
Welche Fehler können bei Exception-Handling vorkommen in unserem Projekt?? – wie funktioniert es grundsätzlich in unserem Code
|
||||
|
||||
DocumentDAO – DocumentService – DocumentController – so sollte Exception-Handling implementiert warden
|
||||
|
||||
DAO wirft Exception – im ServiceLayer wird dies gefangen und der Stack-Trace wird im weggeloggt und eine benutzerfreundliche Fehlermeldung wird ausgegeben (Destructive Wrapping).
|
||||
|
||||
Alle Patterns, die vorkommen – praktische Beispiele aus dem Code
|
||||
|
||||
Was sind JavaBeans? Wie funktioniert das Konzept? Wie wird es genau implementiert?
|
||||
NamedBean, TypedBean etc.
|
||||
|
||||
DTO
|
||||
|
||||
|
||||
\section{Die CONFIG-Files}
|
||||
\begin{figure}[!htp]
|
||||
\centering
|
||||
\includegraphics[width=0.7\textwidth]{pics/ConfigFiles.png}
|
||||
\end{figure}
|
||||
\subsection{web.xml}
|
||||
\begin{itemize}
|
||||
\item konfiguriert den Java Webserver (Wildfly - JBOSS)
|
||||
\item befindet sich im Ordner \textbf{src/main/webapp/WEB-INF/web.xml}
|
||||
\end{itemize}
|
||||
|
||||
\begin{minted}[linenos,breaklines=true]{xml}
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
|
||||
...
|
||||
<servlet>
|
||||
<servlet-name>Faces Servlet</servlet-name>
|
||||
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
</servlet>
|
||||
<servlet-mapping>
|
||||
<servlet-name>Faces Servlet</servlet-name>
|
||||
<url-pattern>*.xhtml</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Security roles -->
|
||||
<security-role>
|
||||
<description>administrators</description>
|
||||
<role-name>ADMIN</role-name>
|
||||
</security-role>
|
||||
<security-role>
|
||||
<description>portal administrators</description>
|
||||
<role-name>PORTALADMIN</role-name>
|
||||
</security-role>
|
||||
<security-role>
|
||||
<description>standard user</description>
|
||||
<role-name>USER</role-name>
|
||||
</security-role>
|
||||
|
||||
<!-- Security constraints -->
|
||||
<security-constraint>
|
||||
<web-resource-collection>
|
||||
<web-resource-name>admin area</web-resource-name>
|
||||
<url-pattern>/admin/*</url-pattern>
|
||||
</web-resource-collection>
|
||||
<auth-constraint>
|
||||
<role-name>ADMIN</role-name>
|
||||
</auth-constraint>
|
||||
</security-constraint>
|
||||
|
||||
<security-constraint>
|
||||
<web-resource-collection>
|
||||
<web-resource-name>community area</web-resource-name>
|
||||
<url-pattern>/community/*</url-pattern>
|
||||
</web-resource-collection>
|
||||
<auth-constraint>
|
||||
<role-name>USER</role-name>
|
||||
<role-name>PORTALADMIN</role-name>
|
||||
<role-name>ADMIN</role-name>
|
||||
</auth-constraint>
|
||||
</security-constraint>
|
||||
|
||||
<security-constraint>
|
||||
<web-resource-collection>
|
||||
<web-resource-name>user administration area</web-resource-name>
|
||||
<url-pattern>/userAdministration/*</url-pattern>
|
||||
</web-resource-collection>
|
||||
<auth-constraint>
|
||||
<role-name>USER</role-name>
|
||||
<role-name>PORTALADMIN</role-name>
|
||||
<role-name>ADMIN</role-name>
|
||||
</auth-constraint>
|
||||
</security-constraint>
|
||||
|
||||
|
||||
<security-constraint>
|
||||
<web-resource-collection>
|
||||
<web-resource-name>user functionalities</web-resource-name>
|
||||
<url-pattern>/user.xhtml</url-pattern>
|
||||
<url-pattern>/userlist.xhtml</url-pattern>
|
||||
<url-pattern>/notImplemented.xhtml</url-pattern>
|
||||
</web-resource-collection>
|
||||
<auth-constraint>
|
||||
<role-name>USER</role-name>
|
||||
<role-name>PORTALADMIN</role-name>
|
||||
<role-name>ADMIN</role-name>
|
||||
</auth-constraint>
|
||||
</security-constraint>
|
||||
|
||||
<security-constraint>
|
||||
<web-resource-collection>
|
||||
<web-resource-name>other functionalities</web-resource-name>
|
||||
<url-pattern>/notImplemented.xhtml</url-pattern>
|
||||
</web-resource-collection>
|
||||
<auth-constraint>
|
||||
<role-name>USER</role-name>
|
||||
<role-name>PORTALADMIN</role-name>
|
||||
<role-name>ADMIN</role-name>
|
||||
</auth-constraint>
|
||||
</security-constraint>
|
||||
|
||||
<login-config>
|
||||
<auth-method>FORM</auth-method>
|
||||
<realm-name>pse</realm-name>
|
||||
<form-login-config>
|
||||
<form-login-page>/login.xhtml</form-login-page>
|
||||
<form-error-page>/login.xhtml</form-error-page>
|
||||
<!-- <form-error-page>/loginerror.xhtml</form-error-page> -->
|
||||
</form-login-config>
|
||||
</login-config>
|
||||
</web-app>
|
||||
\end{minted}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,245 +0,0 @@
|
|||
\part{Component Based Architectures}
|
||||
\section{Erkläre den Begriff Software Komponente wie von Clemens Szypersky definiert}
|
||||
\begin{itemize}
|
||||
\item ist eine Einheit aus spezifizierten Interfaces mit expliziten Context-Abhängigkeiten
|
||||
\item kann solange Abhängigkeiten erfüllt, unabhängig deployed werden
|
||||
\item wird von Dritten zusammen mit anderen Components verwendet
|
||||
\end{itemize}
|
||||
\section{Infrastruktur Pattern}
|
||||
\section{Component Pattern}
|
||||
\subsection{Beschreibe die Problemstellung}
|
||||
\begin{itemize}
|
||||
\item großer Broken Funktionalität vom technischen Teil getrennt ist besser als Vermischung
|
||||
\item Änderungen an kleinem Teil können Auswirkungen auf das ganze System haben
|
||||
\item unabhängige Deployments bzw. Updates der Teile ist unmöglich -> soll aber möglich werden
|
||||
\end{itemize}
|
||||
\subsection{Erkläre die Lösung inkl. Skizze}
|
||||
\begin{figure}[!htp]
|
||||
\centering
|
||||
\includegraphics[width=0.5\textwidth]{pics/component_pat.jpg}
|
||||
\end{figure}
|
||||
\begin{itemize}
|
||||
\item Funktionalität der Anwendung wird in mehrere Teilkomponenten zerlegt
|
||||
\item jede Komponente soll ihre Verantwortlichkeiten ohne starke Abhängigkeiten \textbf{vollständig} implementieren
|
||||
\item durch Zusammenfügen der Funktionalitäten loser Komponenten wird die Anwendung realisiert
|
||||
\end{itemize}
|
||||
\subsection{Beschreibe die Konsequenzen der Anwendung}
|
||||
\begin{itemize}
|
||||
\item eine Komponente sollte sich gut an andere anpassen, jedoch nur lose an diese gekoppelt sein
|
||||
\item Comp-Interface ist von Comp-Impl getrennt
|
||||
\item Funktionalitätsänderung, erfordert nur Änderung innerhalb entsprechenden Komponente
|
||||
\end{itemize}
|
||||
\section{Container Pattern}
|
||||
\subsection{Beschreibe die Problemstellung}
|
||||
\begin{itemize}
|
||||
\item Components enthalten reine Business Logik (keine technischen Aspekte)
|
||||
\item es wird etwas zur Behandlung der technischen Aspekte und Integration benötigt...
|
||||
\item Lösung soll wiederverwendet werden können
|
||||
\end{itemize}
|
||||
\subsection{Erkläre die Lösung inkl. Skizze}
|
||||
\begin{figure}[!htp]
|
||||
\centering
|
||||
\includegraphics[width=0.5\textwidth]{pics/container_pat.jpg}
|
||||
\end{figure}
|
||||
\begin{itemize}
|
||||
\item Container ist Ausführungsumgebung für technische Aspekte der Components
|
||||
\item umhüllt Components und erweckt Anschein einer fixen Integration
|
||||
\item um Wiederverwendung zu fördern werden Frameworks verwendet (z.B.: Code Generation)
|
||||
\end{itemize}
|
||||
|
||||
\subsection{Beschreibe die Konsequenzen der Anwendung}
|
||||
\begin{itemize}
|
||||
\item zur Integration spezifizieren Annotations technische Anforderungen der Components (getrennt von Implementierung)
|
||||
\item Glue-Code-Layer (generischer Containerteil) wird zur Anpassung /Füllung erstellt
|
||||
\item für unterschiedliche Component Typen gibt es verschiedene Container
|
||||
\end{itemize}
|
||||
\section{Service Component Pattern}
|
||||
\subsection{Beschreibe die Problemstellung}
|
||||
\begin{itemize}
|
||||
\item es werden "Service Provider" benötigt, dies sind Komponenten die andere Komponenten der externe Systeme verändern
|
||||
\item dienen als Fassade für Subsystem, welches aus weiteren Komponenten besteht
|
||||
\end{itemize}
|
||||
\subsection{Erkläre die Lösung inkl. Skizze}
|
||||
\begin{figure}[!htp]
|
||||
\centering
|
||||
\includegraphics[width=0.5\textwidth]{pics/service_compontent_pat.jpg}
|
||||
\end{figure}
|
||||
\begin{itemize}
|
||||
\item Service Component: Kapselt Prozesse und Workflow
|
||||
\item Prozesse sind stateless
|
||||
\item so kann Container Components effizient verwalten
|
||||
\item jede Operation muss abgeschlossen sein
|
||||
\end{itemize}
|
||||
\subsection{Beschreibe die Konsequenzen der Anwendung}
|
||||
\begin{itemize}
|
||||
\item dient als Fassade für komplexe Systeme
|
||||
\item vereinfacht Zugriff auf diese Systeme
|
||||
\item jede Operation einer Service Component ist eigene Transaktionseinheit
|
||||
\item da stateless - gute Performance
|
||||
\end{itemize}
|
||||
|
||||
|
||||
\section{Session Component Pattern}
|
||||
\subsection{Beschreibe die Problemstellung}
|
||||
\begin{itemize}
|
||||
\item Service Component reicht nicht aus
|
||||
\item es soll auch ein Client oder Session-Status gespeichert werden
|
||||
\item Status ist nicht persistent und wird durch Garbage-Collection wieder entfernt
|
||||
\end{itemize}
|
||||
|
||||
\subsection{Erkläre die Lösung inkl. Skizze}
|
||||
\begin{figure}[!htp]
|
||||
\centering
|
||||
\includegraphics[width=0.5\textwidth]{pics/session_component_pat.jpg}
|
||||
\end{figure}
|
||||
\begin{itemize}
|
||||
\item SessionComponents merken Client-spezifischen Zustand (nicht persistent)
|
||||
\item Overhead gering da es keine Nebenläufigkeit gibt
|
||||
\item Ressourcenverbrauch wird auch vom Container niedrig gehalten
|
||||
\end{itemize}
|
||||
\subsection{Beschreibe die Konsequenzen der Anwendung}
|
||||
\begin{itemize}
|
||||
\item nur ein Client pro Komponente erlaubt
|
||||
\item Server kann Speicher ausgehen (\#Session-Components = \#Clients)
|
||||
\item um Speicherproblem gegenzuwirken wird Passivation verwendet
|
||||
\end{itemize}
|
||||
|
||||
\section{Implementierungs Pattern}
|
||||
\section{Virtual Instance Pattern}
|
||||
\subsection{Beschreibe die Problemstellung}
|
||||
\begin{itemize}
|
||||
\item viele Komponenten-Instanzen können zu Ressourcenknappheit (Speicher, Container, Systemressourcen) führen
|
||||
\end{itemize}
|
||||
\subsection{Erkläre die Lösung inkl. Skizze}
|
||||
\begin{figure}[!htp]
|
||||
\centering
|
||||
\includegraphics[width=0.5\textwidth]{pics/virtual_instance_pat.jpg}
|
||||
\end{figure}
|
||||
\begin{itemize}
|
||||
\item es wird nur eine virtuelle Komponenten-Referenz geführt
|
||||
\item erst bei Bedarf (Clientaufruf) wird auf eine reale Instanz verwiesen
|
||||
\item nach Nutzung wird reale Instanz wieder in Instanzenpool zurückgegeben
|
||||
\item Arten virtueller Instanzen:
|
||||
\begin{itemize}
|
||||
\item Instance Pooling (wie beschrieben)
|
||||
\item Passivation (reale Instanzen werden zwischenzeitlich auf Festplatte geschrieben und aus Speicher gelöscht, bei Bedarf wieder geladen)
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
\subsection{Beschreibe die Konsequenzen der Anwendung}
|
||||
\begin{itemize}
|
||||
\item Anzahl realer Instanzen im Speicher meist wesentlich geringer als virtueller
|
||||
\item somit ist Aufwand und Speicherbedarf des Containers geringer
|
||||
\end{itemize}
|
||||
\section{Instance Pooling Pattern}
|
||||
\subsection{Beschreibe die Problemstellung}
|
||||
\begin{itemize}
|
||||
\item Komponenteninstanzen erstellen und entfernen ist "teuer" (Overhead)
|
||||
\end{itemize}
|
||||
\subsection{Erkläre die Lösung inkl. Skizze}
|
||||
\begin{figure}[!htp]
|
||||
\centering
|
||||
\includegraphics[width=0.5\textwidth]{pics/instance_pooling_pat.jpg}
|
||||
\end{figure}
|
||||
\begin{itemize}
|
||||
\item im Container wird ein Pool von Komponenteninstanzen erstellt
|
||||
\item wird virtuelle aufgerufen, wird Poolinstanz zugeteilt
|
||||
\item nach Nutzung kommt diese wieder in den Pool
|
||||
\item Zustandsänderungen werden durch Lifecycle Callbacks kontrolliert
|
||||
\end{itemize}
|
||||
\subsection{Beschreibe die Konsequenzen der Anwendung}
|
||||
\begin{itemize}
|
||||
\item bei Container Instance Pooling, zwei Status:
|
||||
\begin{itemize}
|
||||
\item pooled state: Instanz hat keine logische Identität
|
||||
\item active state: Instanz repräsentiert logische Identität, sowie funktionalen Zustand dieser
|
||||
\end{itemize}
|
||||
\item Komponenteninstanzen für Pooling befinden sich immer im Speicher
|
||||
\item Anzahl echter Instanzen schwankt mit Nutzung
|
||||
\item Component-Proxy wird verwendet um Lifecycle Operation auszulösen, bevor Poolinstanz verwendet wird
|
||||
\end{itemize}
|
||||
|
||||
|
||||
\section{Passivation Pattern}
|
||||
\subsection{Beschreibe die Problemstellung}
|
||||
\begin{itemize}
|
||||
\item Session Components haben Status ohne Repräsentation im Speicher
|
||||
\item es gibt Zeiträume der Inaktivität
|
||||
\item es sollen Ressourcen gespart werden
|
||||
\item z.B. Einkaufswagen eines Online Shops
|
||||
\end{itemize}
|
||||
\subsection{Erkläre die Lösung inkl. Skizze}
|
||||
\begin{figure}[!htp]
|
||||
\centering
|
||||
\includegraphics[width=0.5\textwidth]{pics/passivation_pat.jpg}
|
||||
\end{figure}
|
||||
\begin{itemize}
|
||||
\item Komponenteninstanzen können durch Container temporär aus Speicher entfernt werden
|
||||
\item Zustand wird persistent gespeichert und aus Hauptspeicher gelöscht
|
||||
\item wird Instanz benötigt wird diese von Festplatte in Hauptspeicher geladen
|
||||
\end{itemize}
|
||||
\subsection{Beschreibe die Konsequenzen der Anwendung}
|
||||
\begin{itemize}
|
||||
\item Instanzen werden wirklich aus Speicher entfernt
|
||||
\item bei neuerlicher Herstellung müssen auch Verbindungen zu anderen Ressourcen neu geladen werden
|
||||
\item es müssen Lifecycle Callbacks implementiert werden (teilweise vom Container automatisch)
|
||||
\item bedeutet deutlichen Overhead und sollte vermieden werden (besser mehr Speicher)
|
||||
\end{itemize}
|
||||
|
||||
\section{Component Proxy Pattern}
|
||||
\subsection{Beschreibe die Problemstellung}
|
||||
\begin{itemize}
|
||||
\item Clients müssen auf virtuelle Komponenteninstanzen referenzieren
|
||||
\item Container muss bei Client Aufruf für virtuelle, physikalische Instanz bereitstellen
|
||||
\item zuvor wird durch Lifecycle Callbacks auf freie geprüft
|
||||
\end{itemize}
|
||||
|
||||
|
||||
\subsection{Erkläre die Lösung inkl. Skizze}
|
||||
\begin{figure}[!htp]
|
||||
\centering
|
||||
\includegraphics[width=0.5\textwidth]{pics/component_proxy_pat.jpg}
|
||||
\end{figure}
|
||||
\begin{itemize}
|
||||
\item es wird ein Proxy für physikalische Komponenteninstanzen bereitgestellt
|
||||
\item Clients haben nie eine direkte Referenz sondern agieren nur mit Proxy
|
||||
\item Proxy handelt Instance Pooling und Passivation
|
||||
\item zur Performancesteigerung bedient ein Proxy mehrere virtuelle Komponenteninstanzen
|
||||
\end{itemize}
|
||||
|
||||
\subsection{Beschreibe die Konsequenzen der Anwendung}
|
||||
\begin{itemize}
|
||||
\item dem Client wird durch den Proxy etwas gegeben, das ohne echte Komponenteninstanz aufgerufen werden kann
|
||||
\item Client Methodenaufrufe enthalten ID der logischen Komponenteninstanz zur korrekten Weiterleitung
|
||||
\item Proxy implementiert keine Logik - leitet nur weiter
|
||||
\item Proxy kann generiert werden, meist als Teil des Glue-Code-Layers
|
||||
\end{itemize}
|
||||
|
||||
|
||||
\section{Glue-Code Pattern}
|
||||
\subsection{Beschreibe die Problemstellung}
|
||||
\begin{itemize}
|
||||
\item Container soll wiederverwendet werden, dazu muss Funktionalität generisch sein
|
||||
\item Komponenten besitzen spezielle Schnittstelle und Annotationen welche spezielle Config für technische Anforderungen enthalten
|
||||
\item völlig generische Container können keine unterschiedlichen Komponenten beherbergen
|
||||
\end{itemize}
|
||||
\subsection{Erkläre die Lösung inkl. Skizze}
|
||||
\begin{figure}[!htp]
|
||||
\centering
|
||||
\includegraphics[width=0.5\textwidth]{pics/glue_code_pat.jpg}
|
||||
\end{figure}
|
||||
\begin{itemize}
|
||||
\item Schicht aus generiertem Code als Adapter zwischen generischem Teil des Containers und Komponentenimplementierung
|
||||
\item pro spezifischer Komponente wird eigene Glue-Code-Schicht erzeugt
|
||||
\item Compontent-Proxy ist Teil dieser Schicht
|
||||
\end{itemize}
|
||||
|
||||
\subsection{Beschreibe die Konsequenzen der Anwendung}
|
||||
\begin{itemize}
|
||||
\item in Java mit Reflection umsetzbar (ermöglicht dynamischen Operationsaufruf)
|
||||
\item Reflection viel langsamer als spezifischer generierter Code
|
||||
\item Komponenten-Deployment:
|
||||
\begin{itemize}
|
||||
\item Zeitpunkt der Integrationsmaßnahmen des Containers
|
||||
\item Zeitpunkt der Glue-Code-Layer Generierung
|
||||
\end{itemize}
|
||||
\end{itemize}
|
|
@ -1,593 +0,0 @@
|
|||
\part{Service-Oriented Architecture (SOA)}
|
||||
\section{SOA}
|
||||
\section{Auf welche drei technischen Konzepte basiert SOA?}
|
||||
\begin{itemize}
|
||||
\item Services: unabhängige Business-Funktionalität
|
||||
\item Enterprise service bus (ESB): Infrastruktur, zwischen verteilten Service-Systemen
|
||||
\begin{itemize}
|
||||
\item erledigt Datenkonvertierung und Verteilung
|
||||
\item wird meist durch große, kommerzielle Sofwarepakete realisiert
|
||||
\end{itemize}
|
||||
\item Lose Kopplung: reduziert Systemabhängikeiten.
|
||||
\begin{itemize}
|
||||
\item einzelne Services sollen auch dann arbeiten, wenn andere nicht verfügbar oder langsam sind
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
\section{Beschreibe die Eigenschaften von großen Verteilten Systemen}
|
||||
\begin{itemize}
|
||||
\item Heterogen -> unterschiedliche
|
||||
\begin{itemize}
|
||||
\item Plattformen
|
||||
\item Programmiersprachen
|
||||
\end{itemize}
|
||||
\item Komplex
|
||||
\item Nicht perfekt (wäre zu teuer)
|
||||
\item Redundant (alle Redundanz zu eliminieren verlangsamt das System)
|
||||
\end{itemize}
|
||||
\section{Beschreibe den Begriff Business View im Kontext von SOA}
|
||||
\begin{itemize}
|
||||
\item Geschäftsprozessmodellierung wird verwendet um alle Aspekte eines GP grafisch zu beschreiben
|
||||
\item Standards zur Modellierung, damit Experten daraus GP entwerfen können:
|
||||
\begin{itemize}
|
||||
\item Business Process Execution Language (BPEL) im XML Format
|
||||
\item Unified Modeling Language (UML)
|
||||
\end{itemize}
|
||||
\item Process View entspricht Top-Down-Ansatz der Systemmodellierung (Prozess auf kleinere herunter brechen)
|
||||
\end{itemize}
|
||||
\section{Beschreibe den Begriff Service View auf ein Software-System im Kontext von SOA}
|
||||
\begin{itemize}
|
||||
\item entspricht Bottom-Up-Ansatz der Systemmodellierung (Services in größere Einheiten zusammenfassen bis GP vollständig)
|
||||
\item Schnittstellen-Definition ist Kern der Service-orientierten Architektur
|
||||
\item Schnittstellen-Beschreibung:
|
||||
\begin{itemize}
|
||||
\item syntaktisch durch Signatur (Input, Output, Exception)
|
||||
\item semantisch
|
||||
\end{itemize}
|
||||
\item Vertrag: ist vollständige Spezifizierung eines Services zwischen Consumer und Provider
|
||||
\end{itemize}
|
||||
\section{Beschreibe drei unterschiedliche Service Kategorien}
|
||||
\subsection{Basic Services}
|
||||
\begin{itemize}
|
||||
\item grundlegende, an vielen Stellen gebrauchte Business-Funktionalität
|
||||
\item meist kurze Laufzeit
|
||||
\item stateless
|
||||
\end{itemize}
|
||||
\subsection{Composed Services}
|
||||
\begin{itemize}
|
||||
\item aus Basic Services zusammengesetzt („Orchestration“)
|
||||
\item auf höherer Ebene als Basic Services angesiedelt
|
||||
\item stateless
|
||||
\item kurze Laufzeit
|
||||
\item oft Adapter Services um anderen Services eine Schnittstelle zu bieten
|
||||
\end{itemize}
|
||||
\subsection{Process Services}
|
||||
\begin{itemize}
|
||||
\item Längerfristige Prozesse, die Geschäftsprozesse umsetzen
|
||||
\item Interagieren mit Benutzer oder anderen Systemen
|
||||
\item BPEL ermöglicht \textbf{laufenden} Process Services nicht, Benutzerinteraktion auszulösen (beeinflusst Design)
|
||||
\item statefull (z.B. wie weit ist Benutzer im Prozess)
|
||||
\end{itemize}
|
||||
|
||||
\section{Erkläre die beiden Ansätze für SOA System-Design inkl. Skizze}
|
||||
\begin{itemize}
|
||||
\item Kommunikation zwischen Komponenten funktioniert über Schnittstellen
|
||||
\item Schnittstellen sind public und published, deshalb schwer änderbar
|
||||
\item wird eine neue Version veröffentlicht werden Vorversionen meist noch angeboten
|
||||
\end{itemize}
|
||||
\begin{figure}[!htp]
|
||||
\centering
|
||||
\includegraphics[width=0.5\textwidth]{pics/topDown-bottomUp.jpg}
|
||||
\end{figure}
|
||||
\subsection{Top Down}
|
||||
|
||||
\begin{itemize}
|
||||
\item Prozess auf kleiner Prozesse herunterbrechen, bis Ebene von Basic Services erreicht ist
|
||||
\end{itemize}
|
||||
\subsection{Bottom Up}
|
||||
\begin{itemize}
|
||||
\item Services in größere Einheiten zusammenfassen, bis Geschäftsprozess vollständig abgebildet
|
||||
\end{itemize}
|
||||
\section{Beschreibe das Konzept des Enterprise Service Bus inkl. Skizze}
|
||||
|
||||
\begin{itemize}
|
||||
\item ist Kommunikationsmedium zwischen einzelnen Services
|
||||
\item Hauptaufgaben sind:
|
||||
\begin{itemize}
|
||||
\item Datentransformation (Umwandlung von Datenpaketen und Feldern dieser)
|
||||
\item Routing
|
||||
\begin{itemize}
|
||||
\item Services finden
|
||||
\item Daten zwischen Services vermitteln
|
||||
\item Loadbalancing zwischen Serviceanbietern
|
||||
\end{itemize}
|
||||
\item Protokolle und Middleware kann Heterogen sein
|
||||
\item ESB: REST, CORBA, SOAP
|
||||
\item REST verwendet http für Transport
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
|
||||
\begin{figure}[!htp]
|
||||
\centering
|
||||
\includegraphics[width=0.3\textwidth]{pics/esb_1.jpg}
|
||||
\includegraphics[width=0.3\textwidth]{pics/esb_2.jpg}
|
||||
\includegraphics[width=0.3\textwidth]{pics/esb_3.jpg}
|
||||
\end{figure}
|
||||
\section{Beschreibe den Unterschied zwischen P2P Verbindungen und dem Konzept ESB als Mediator}
|
||||
|
||||
\begin{itemize}
|
||||
\item Unterschied: Kopplung der Consumer an physikalische Verbindung (P2P enger)
|
||||
\end{itemize}
|
||||
\subsection{Point-to-Point}
|
||||
\begin{itemize}
|
||||
\item Consumer muss Endpunkt kennen da Empfänger bestimmt sein muss
|
||||
\item ist Verbindung nicht möglich, schlägt Aufruf fehl
|
||||
\end{itemize}
|
||||
\subsection{ESB als Mediator}
|
||||
\begin{itemize}
|
||||
\item Ziel-Service wird vom Consumer mittels Tag angegeben
|
||||
\item ESB kümmert sich um die Zustellung -> Vorteil: dynamische Änderungen möglich
|
||||
\end{itemize}
|
||||
\section{Beschreibe das Konzept der loosen Kopplung und die beiden wichtigsten damit verbundenen Themen}
|
||||
\subsection{Konzept}
|
||||
\begin{itemize}
|
||||
\item bezeichnet einen geringen Grad der Abhängigkeit zwischen Hard- oder Software-Komponenten
|
||||
\item ermöglicht
|
||||
\begin{multicols}{3}
|
||||
\begin{itemize}
|
||||
\item Skalierbarkeit
|
||||
\item Flexibilität
|
||||
\item Fehlertoleranz
|
||||
\end{itemize}
|
||||
\end{multicols}
|
||||
\end{itemize}
|
||||
\subsection{damit verbundene Konzepte}
|
||||
\begin{itemize}
|
||||
\item Asynchrone Kommunikation
|
||||
\begin{itemize}
|
||||
\item Sender und Empfänger sind nicht synchronisiert
|
||||
\item nach dem Versand kann sofort andere Arbeit ausgeführt werden
|
||||
\item trifft Antwort ein wird diese ursprünglichem Request zugeordnet
|
||||
\end{itemize}
|
||||
\item Heterogene Datentypen
|
||||
\begin{itemize}
|
||||
\item da Daten in großen Systemen unterschiedlich sind, werden Mappings benötigt
|
||||
\item Mappings gehen auf technische und semantische Aspekte ein
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
\section{Microservice Architekturen}
|
||||
|
||||
\section{Beschreibe die wesentlichsten Unterschiede zwischen einer monolithischen Anwendung und dem Mikroservices Ansatz}
|
||||
\subsection{Monolithisch}
|
||||
\begin{itemize}
|
||||
\item Enterprise Applications bestehen oft aus drei Teilen
|
||||
\begin{itemize}
|
||||
\item Client-seitigem User Interface
|
||||
\item Server-seitiger monolithischer Applikation
|
||||
\item Datenbank
|
||||
\end{itemize}
|
||||
\item da die Applikation \textbf{eine} Einheit ist, muss sie bei Änderungen neu gebuilded und deployed werden
|
||||
\end{itemize}
|
||||
\subsection{Microservices}
|
||||
\begin{itemize}
|
||||
\item sind gut skalierbar
|
||||
\item Applikation besteht aus vielen kleinen Services
|
||||
\item jedes Service läuft in eigenem Prozess und deckt einzelne Funktionalität vollständig ab
|
||||
\item für die Interservicekommunikation werden leichtgewichtige Kommunikationswege verwendet (z.B.: HTTP - kein ESB mehr nötig)
|
||||
\item Services können unabhängig voneinander deployed werden
|
||||
\end{itemize}
|
||||
|
||||
\section{Vergleiche die Unterschiedlichen Skalierungstrategien von monolitischen Applikationen und Mikroservices}
|
||||
\subsection{Monolithisch}
|
||||
\begin{itemize}
|
||||
\item gesamte Applikation muss skaliert werden
|
||||
\item erfolgt durch mehrerer Instanzen (horizontale Skalierung) bzw. Load Balancing
|
||||
\item Nachteil: alles und nicht nur benötigtes wird dupliziert -> Ressourcenbelastung
|
||||
\end{itemize}
|
||||
\subsection{Microservices}
|
||||
\begin{itemize}
|
||||
\item Service-Grenzen sind funktional orientiert
|
||||
\item es können speziell benötigte Services öfter instanziert werden
|
||||
\item Nachteil: Interprozesskommunikation nimmt aufgrund der Verteilung auf viele kleine Servicekomponenten zu
|
||||
\end{itemize}
|
||||
|
||||
\section{Erkläre den Unterschied zwischen Libraries und Services}
|
||||
\subsection{Library}
|
||||
\begin{itemize}
|
||||
\item Komponenten, die in eine Applikation verlinkt werden und lokal (im selben Prozess) verwendet werden
|
||||
\end{itemize}
|
||||
\subsection{Services}
|
||||
\begin{itemize}
|
||||
\item besitzen immer eine Remote Schnittstelle
|
||||
\item befinden sich in eigenem Prozess (stärker entkoppelt)
|
||||
\item Aufruf über Web Services oder Remote Procedure Calls
|
||||
\item Konsequenzen:
|
||||
\begin{itemize}
|
||||
\item getrennt auslieferbar
|
||||
\item Explizite Schnittstelle
|
||||
\item Services sind published -> schwer änderbar
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
|
||||
\section{Beschreibe die Beziehung zwischen einer Team Struktur und dem Design einer Software}
|
||||
\subsection{Silo-Ansatz}
|
||||
\begin{itemize}
|
||||
\item Zuständigkeiten bei großen Applikationen werden oft an technologische Grenzen angepasst
|
||||
\item so entstehen Teams für UI, Server-Side oder Datenbank Teams
|
||||
\item kleine Änderungen führen so bereits zu hohen Kosten da Team übergreifend gearbeitet werden muss
|
||||
\end{itemize}
|
||||
\subsection{Cross-Functional Ansatz}
|
||||
\begin{itemize}
|
||||
\item bei Microservices wird ähnlich wie bei Scrum ein cross-functional Ansatz verfolgt
|
||||
\item ein Team ist somit für das gesamte Service, welches nur eine gesamte Funktionalität abdeckt, verantwortlich
|
||||
\end{itemize}
|
||||
|
||||
\section{Erkläre das Konzept "smart endpoints and dump pipes"}
|
||||
\begin{itemize}
|
||||
\item wird anstatt eines ESB, welcher oft smarte Mechanismen für Routing und Transforming anbietet, verwendet
|
||||
\item Smart Endpoints sind z.B. RabbitMQ oder REST
|
||||
\item diese verwenden einfache Protokolle wie z.B. HTTP zur Übertragung
|
||||
\item Microservices agieren wie Filter bei Unix und wenden ihre Logik auf Anfragen an bevor die Antwort erzeugt wird
|
||||
\end{itemize}
|
||||
|
||||
\section{Was sind die Herausforderungen von dezentralisiertem Datenmanagement?}
|
||||
\begin{itemize}
|
||||
\item Monolitische Applikationen bevorzugen eine Datenbank für alle Daten des Systems
|
||||
\item dies Ansatz wird oft auch von Unternehmen bevorzugt
|
||||
\item Microservices verwenden hingegen den "Polyglot Persistence" Ansatz -> für einzelne Services jeweils eine eigene Datenbank
|
||||
\item Konsequenz: transaktionslose Koordination zwischen Services
|
||||
\item Herausforderung: Aufsplittung der Datenbank beim Wechsel von Monolith zu Microservice Ansatz
|
||||
\end{itemize}
|
||||
|
||||
\section{Beschreibe die wichtigsten Design-Überlegungen im Zusammenhang mit Mircroservices ("Design for Failure", "Evulutionary Design")}
|
||||
\subsection{Design for failure}
|
||||
\begin{itemize}
|
||||
\item bei Microservices nimmt Fehlerpotential durch Interprozesskommunikation massiv zu
|
||||
\item jeder Aufruf kann bei Nichtverfügbarkeit des Services fehlschlagen
|
||||
\item Software muss daher Fehlertolerant konzipiert sein
|
||||
\item es gibt diverse Monitoring-Tools um Fehler und Probleme zur Laufzeit zu erkennen
|
||||
\end{itemize}
|
||||
\subsection{Evolutionary Design}
|
||||
\begin{itemize}
|
||||
\item das Setzen der Grenzen der Micro-Service Komponenten nach einer Aufteilung ist herausfordernd
|
||||
\item Änderungen sollen nach Aufteilung nur das entsprechende Modul betreffen
|
||||
\item Module sollen unabhängig voneinander geändert werden können
|
||||
\item Evolutionary Design
|
||||
\begin{itemize}
|
||||
\item Beginne mit Monolith und trenne erst auf Microservices wenn dieser zum Problem wird
|
||||
\item kommt hauptsächlich im Kontext mit Extreme-Programming zum Einsatz
|
||||
\item Weiterentwicklung des Designs erfolgt durch \textbf{Refactoring}
|
||||
\item ist das Gegenteil von geplantem Design, da Designelemente erst wenn notwendig eingebaut werden
|
||||
\item Design for the future wird vermieden
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
\section{Von Objekten zum Service}
|
||||
\section{Beschreibe die Nachteile von klassischen verteilten Objektarchitekturen}
|
||||
\begin{itemize}
|
||||
\item Die Kommunikation von verteilten Objekte erfolgt oft über \textbf{nicht standardisierte} TCP-Ports verschiedenster Middleware-Libraries (z.B. CORBA, DCOM, RMI) - oft durch die meisten Firewalls standardm. blockiert,
|
||||
\item größere Serverauslastung durch viele Anfragen vom Client, da Objektstatus darüber ausgetauscht wird,
|
||||
\item Load-Balancing schwieriger zu implementieren und zu verwalten,
|
||||
\item Reservierter Speicher durch den Client muss vom Server automatisch wieder freigegeben werden (z.B. bei Ausfall des Clients)
|
||||
\end{itemize}
|
||||
\section{Erkläre die unterschiedlichen Formen der Kopplung}
|
||||
Kopplung beschreibt den Grat der Abhängigkeiten eines Moduls von einem anderen Modul (z.B. Client vom Server). Dabei gibt es verschiedene Formen::
|
||||
\begin{itemize}
|
||||
\item Functional Coupling:
|
||||
\begin{itemize}
|
||||
\item Clients hängen von der in Web-Services implementierten Logik ab - bei Fehlern oder Inkonsistenzen sind sie betroffen,
|
||||
\end{itemize}
|
||||
\item Data Structure Coupling:
|
||||
\begin{itemize}
|
||||
\item Clients müssen die Datenstrukturen eines Services verstehen (in Bezug auf z.B. Datentypen oder Character-Encodings der ausgetauschten Nachrichten)
|
||||
\end{itemize}
|
||||
\item Temporal Coupling:
|
||||
\begin{itemize}
|
||||
\item hoch, wenn Request sofort nach dem Empfang verarbeitet werden muss (Request/Response pattern),
|
||||
\item kann gesenkt werden, wenn die Zeit, wann request verarbeitet werden muss, ausgedehnt oder verschoben wird (Request/Acknowledge pattern)
|
||||
\end{itemize}
|
||||
\item URL coupling
|
||||
\begin{itemize}
|
||||
\item Clients sind oft stark an Service-URLs gebunden, da oft statisch oder nach einem einfachen Schema definiert.
|
||||
\end{itemize}
|
||||
\item Durch Vermeidung der Kopplung auf Computing-Plattformen können die Nachteile von Software-Wiederverwendung verringert werden.
|
||||
\end{itemize}
|
||||
\section{Web Service API Styles}
|
||||
\subsection{Beschreibe aktuelle Designüberlegungen für Web Service APIs}
|
||||
\begin{itemize}
|
||||
\item Kapselung:
|
||||
\begin{itemize}
|
||||
\item Services sollten Implementierungsdetails verstecken,
|
||||
\item Client sollte über Domain-Model, Datenbanktabllen oder Stored-Procedure-Designs nicht Bescheid wissen,
|
||||
\item Service-APIs sollten "top-down" desgined werden (API wird an Anforderungen seitens Client-Applikationen angepasst)
|
||||
\end{itemize}
|
||||
\item Service-Contract:
|
||||
\begin{itemize}
|
||||
\item Spezifiziert die Art der Interaktionen zwischen Services und Clients,
|
||||
\item z.B. welche Bedingung vor Aufruf wahr sein muss (\textbf{pre-condition}),
|
||||
\item oder die Ereignisse nach Ausführung des Services (\textbf{post-condition}),
|
||||
\item die meisten Contracts können nur die Basisinformationen eines Services abbilden (z.B. bei WSDL Web-Service-Description-Language die syntaktische Spezifikation).
|
||||
\end{itemize}
|
||||
\item Autonomie/Unabhängigkeit:
|
||||
\begin{itemize}
|
||||
\item Services sollten eigene Ausführung kontrollieren und nur wenige Abhängigkeiten nach außen aufweisen,
|
||||
\item Web-Services sollten verteilte Transaktionen \textbf{verhindern}
|
||||
\item Web-Services können Kompensierung durch die Bereitstellung von gegenteiligen Service-Paaren (logische Funktion genau invers),
|
||||
\item Daten in verteilten Systemen können nicht vollständig synchron sein
|
||||
\end{itemize}
|
||||
\item Latenz:
|
||||
\begin{itemize}
|
||||
\item Zeit eines Clients für die Beantwortung von Anfragen an Web-Services signifikant höher als ähnlicher Aufruf innerhalb desselben Prozesses,
|
||||
\item Web-Services sollten daher APIs erstellen, welche die Anzahl der netzwerkbelastenden Aktionen gering hält
|
||||
\end{itemize}
|
||||
\item Partial failures:
|
||||
\begin{itemize}
|
||||
\item Clients müssen auf die Fehlfunktion von Services vorbereitet werden,
|
||||
\item Situationen, in denen der Netzwerkverkehr abbricht oder ausgelastet ist, müssen stets berücksichtigt werden
|
||||
\end{itemize}
|
||||
\item Message Encoding:
|
||||
\begin{itemize}
|
||||
\item Web-Services verwenden textbasierte Nachrichten,
|
||||
\item manchmal sind sie jedoch in Binärform umgewandelt zur Verminderung von payload und damit Senkung der benöt. Netzwerkbandbreite
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
\subsection{RPC API}
|
||||
\subsection{Erkläre die Funktionalität inkl. Skizze}
|
||||
\begin{itemize}
|
||||
\item Client sendet Nachricht zu Remote-Server und blockiert, während er auf die Response wartet,
|
||||
\item Die Nachricht in der Anfrage identifiziert den auszuführenden Prozess und beinhaltet Parameter, welche direkt den Parametern der Remote-Prozedur entsprechen,
|
||||
\item Sobald der Service ausgeführt wurde, wird die Anfrage des Clients bearbeitet und eine Antwort wird zurückgeschickt,
|
||||
\item Client kann anschließend die Ergebnisse extrahieren und die Ausführung fortsetzen.
|
||||
\item Mittels WSDL kann die Bearbeitbarkeit durch den Entwickler durch automatische Codegenerierung vereinfacht werden - Defin. mittels XSD oder WSDL
|
||||
\end{itemize}
|
||||
\begin{figure}[!htp]
|
||||
\centering
|
||||
\includegraphics[width=0.5\textwidth]{pics/rpc_api.jpg}
|
||||
\end{figure}
|
||||
\begin{itemize}
|
||||
\item Message-API
|
||||
\end{itemize}
|
||||
\subsection{Beschreibe die Konsequenzen der Nutzung}
|
||||
\begin{itemize}
|
||||
\item Die Wahrscheinlichkeit, dass Entwickler Signaturen erstellen wie bei normalen Klassenmethoden (z.B. mit langen Parameterlisten) ist hoch - dadurch Einschränkungen in Flexibilität und Erhöhung der Instabilität
|
||||
\item Proxys werden meist mittels clientseitiger Codegeneratoren (z.B. basierend auf WSDL) generiert - der Proxy muss somit bei jeder Änderung der WSDL-Beschreibung mitgeändert werden,
|
||||
\item Durch die Client-Proxys wird es schwierig, festzustellen, wann Remote-Prozeduren aufgerufen werden sollen - daher meiden Entwickler oft die notwendige Implementierung von Exception-Handling im Netzwerkbereich (Verbindungsverlust, Servercrash und belegte Dienste)
|
||||
\end{itemize}
|
||||
\subsection{Message API}
|
||||
\subsection{Erkläre die Funktionalität inkl. Skizze}
|
||||
\begin{itemize}
|
||||
\item Dienste, die Message-APIs verwenden, empfangen ein oder mehrere selbstbeschreibende Nachrichtentypen mithilfe einer gegebenen URL
|
||||
\item Aufruf einer Message-API oft durch Standardformate wie SOAP oder XML
|
||||
\item Client sendet Nachricht an eine bestimmte URL und ist blockiert, während er auf die Antwort wartet
|
||||
\item Wenn Nachricht bei Server ankommt, wird sie deseralisiert und inspiziert und an den zuständigen Handler weitergeleitet,
|
||||
\item Sobald der Handler aufgerufen wurde, ist er in der Lage, den Request des Clients verarbeiten und eine Response zurücksenden,
|
||||
\item Nachrichten werden meist über XML Schema-Definitionen definiert,
|
||||
\item Die API stellt meist einen empfangenden Endpunkt zur Verfügung, während der Web-Service als Versender agiert,
|
||||
\item Clients versenden meist einen der drei Message-Typen:
|
||||
\begin{itemize}
|
||||
\item Command-Message,
|
||||
\item Event-Message,
|
||||
\item Document-Message
|
||||
\end{itemize}
|
||||
\item Message-APIs stellen Ergebnisse oft auch über Messages zur Verfügung.
|
||||
\end{itemize}
|
||||
\begin{figure}[!htp]
|
||||
\centering
|
||||
\includegraphics[width=0.5\textwidth]{pics/message_api.jpg}
|
||||
\end{figure}
|
||||
\subsection{Beschreibe die Konsequenzen der Nutzung}
|
||||
\begin{itemize}
|
||||
\item Message-APIs setzen zur Unterstützung clientseitiger Code-Generierung oft Service-Descriptors, wie z.B. WSDL ein,
|
||||
\item Logik zur Verarbeitung von speziellen Nachrichtentypen wird durch Command-Invoker in Gang gebracht,
|
||||
\item Vereinfachung durch Trennung der Verarbeitungslogik vom empfangenden Web-Service
|
||||
\end{itemize}
|
||||
\subsection{Resource API}
|
||||
\subsection{Erkläre die Funktionalität inkl. Skizze}
|
||||
\begin{itemize}
|
||||
\item Verwendung durch Services mittels Anfrage-URL und HTTP-Methoden des Clients begleitet durch \textbf{media type}, um Anfrage des Clients zu erkennen
|
||||
\item Anfragen oft nach dem Prinzip von \textbf{Respresentational State Transfer (REST)}
|
||||
\item Beispiele für eine \textbf{ressource}:
|
||||
\begin{itemize}
|
||||
\item Textdatei,
|
||||
\item Mediendatei,
|
||||
\item einzelne Spalte in Datenbanktabelle,
|
||||
\item Collection mit Daten etc.
|
||||
\end{itemize}
|
||||
\item Clients manipulieren desn Status der Ressource durch \textbf{representations}
|
||||
\item Verwendete HTTP-Methoden durch Resource-API:
|
||||
\begin{itemize}
|
||||
\item PUT - Ressourcenupdate,
|
||||
\item GET - Abruf der Repräsentation einer Ressource,
|
||||
\item DELETE - Löschen einer Ressource,
|
||||
\item POST - Erstellen oder Updaten einer Ressource,
|
||||
\item HEAD - ähnlich wie GET, nur ohne Abruf der Repräsentation - verwendet, um Metadaten der media-types zu erhalten,
|
||||
\item OPTIONS - liefert die HTTP-Methoden der Ziel-URL zurück
|
||||
\end{itemize}
|
||||
\item Vorteile:
|
||||
\begin{itemize}
|
||||
\item Spezifikation durch HTTP definiert - Client muss keine neue API einsetzen!
|
||||
\item Status-Codes von HTTP für Rückmeldung an Client können hier auch verwendet werden,
|
||||
\item Regeln für \textbf{idempotent} und \textbf{safe} von HTTP gelten
|
||||
\end{itemize}
|
||||
\item \textbf{media types} einer Resource-API-Anfrage müssen klar definiert werden.
|
||||
\item Definiert werden \textbf{media types} durch:
|
||||
\begin{itemize}
|
||||
\item Character-Encodings,
|
||||
\item Regeln für das Parsen der Daten,
|
||||
\item Standards für die Koppelung mit anderen Ressourcen,
|
||||
\end{itemize}
|
||||
\item Clients müssen über die media types des Services und die Verwendung dieser Bescheid wissen.
|
||||
\end{itemize}
|
||||
\begin{figure}[!htp]
|
||||
\centering
|
||||
\includegraphics[width=0.5\textwidth]{pics/ressource_api.jpg}
|
||||
\end{figure}
|
||||
\subsection{Beschreibe die Konsequenzen der Nutzung}
|
||||
\begin{itemize}
|
||||
\item Resource-APIs sind eine gute Wahl bei großer Anzahl von zugreifenden Clients,
|
||||
\item Resource-APIs machen die Weitergabe der Verwendungsart der Services durch den URL-Standard sehr einfach. Nachteil: Auch durch potenzielle Angreifer einfach zu verstehen und auszunützen - Security-Probleme
|
||||
\item Code-Generierung durch Entwickler kann meist nicht verwendet werden, da Service-Descriptors durch Resource-APIs nicht angeboten werden,
|
||||
\item Resource-APIs bieten die Möglichkeit, die Präferenzen des Clients über die mitgegebenen \textbf{media types} abzufragen und dieselbe Ressource im richtigen Format zurückzuliefern.
|
||||
\end{itemize}
|
||||
\section{Web Service Infrastruktur}
|
||||
\section{Service Connector Pattern}
|
||||
\subsection{Erkläre die Funktionalität inkl. Skizze}
|
||||
\begin{itemize}
|
||||
\item Service-Connectors vereinfachen die Verwendung von Services durch Verdecken der API-Komplexität,
|
||||
\item viele generische Funktionen werden gekapselt und mit zusätzlicher Logik, die der Service benötigt, erweitert:
|
||||
\begin{itemize}
|
||||
\item Service Location und Connection-Management wird implementiert:
|
||||
\begin{itemize}
|
||||
\item Ermitteln der Service-Adressen,
|
||||
\item Aufbau der Verbindung zum Service,
|
||||
\item Aufzeichnung aller verbindungsspezifischen Fehler.
|
||||
\end{itemize}
|
||||
\item Nach der Verbindung des Clients mit dem Connector leitet er die Anfrage im Auftrag des Clients weiter
|
||||
\item Connectors empfangen auch die Responses des Services und stellen Hilfsfunktionen zur Unterstützung von Client-Applikationen (z.B. Datentypübersetzung oder Aufzeichnung aller HTTP status-codes) bereit,
|
||||
\item Ein Connector kapselt die gesamte Verbindungslogik des Clients zur spezifischen Kommunikation mit dem Service
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
\begin{figure}[!htp]
|
||||
\centering
|
||||
\includegraphics[width=0.5\textwidth]{pics/serv_connector_api.JPG}
|
||||
\end{figure}
|
||||
\subsection{Beschreibe die Konsequenzen der Nutzung}
|
||||
\begin{itemize}
|
||||
\item Nutzung eines Connectors als Test-Double in automatisierten Tests, ohne den Web-Service ansprechen zu müssen,
|
||||
\item generische Logik zur Verwendung durch den Client wird eingesetzt, wie z.B.:
|
||||
\begin{itemize}
|
||||
\item Logging,
|
||||
\item Validierung,
|
||||
\item Exception Handling,
|
||||
\item Eingabe von Benutzeranmeldedaten (siehe Service-Inceptor-Pattern)
|
||||
\end{itemize}
|
||||
\item Ein Connector hängt von den Services, für die er erstellt wurde, ab. Bei Generierung der Services durch einen Descriptor (z.B. WSDL) muss der Entwickler informiert werden - Änderung des Descriptors und Neugenerierung dringend erforderlich
|
||||
\item Clients können Exception-Handling in Bezug auf Netzwerkfehler (verlorene Verbindungen, Server-Crashes, belegte Services) oft schwer implementieren, da Informationen über den Ablauf im Hintergrund (Kommunikation mit Service) durch den Connector versteckt werden.
|
||||
\end{itemize}
|
||||
|
||||
\section{Service Descriptor Pattern}
|
||||
\subsection{Erkläre die Funktionalität inkl. Skizze}
|
||||
|
||||
\begin{itemize}
|
||||
\item bietet eine \emph{Maschinen lesbare} Auflistung an logischen Operationen oder Ressourcen die eine Organisation bietet
|
||||
\item die Metadaten von jeder logischen Operationen oder Ressource identifizieren ein Webservice und geben die Typen (Nachrichten oder Medien) an die es empfangen und zurückgeben kann.
|
||||
\item Service Metadaten werden mit \textbf{XML} beschrieben -> bei Webservice nennt man das \textbf{WSDL} (Web Service Description Language) oder \textbf{WADL} bei Web Applikationen
|
||||
\end{itemize}
|
||||
|
||||
\begin{figure}[!htp]
|
||||
\centering
|
||||
\includegraphics[width=0.5\textwidth]{pics/service_descriptor_contFirst.jpg}
|
||||
\includegraphics[width=0.5\textwidth]{pics/service_descriptor_codeFirst.jpg}
|
||||
\end{figure}
|
||||
\subsection{Beschreibe die Konsequenzen der Nutzung}
|
||||
|
||||
\begin{itemize}
|
||||
\item kann als Vertrag zwischen Server und Client angesehen werden wie eine Interaktion auszusehen hat.
|
||||
\item üblicherweise in WSDL beschrieben (siehe oben)
|
||||
\item Service Designer sollte Client-Service Interaktionen berücksichtigen (Netzwerkeffizienz)
|
||||
\item Client benötigt viele Netzwerkanfragen um eine Anfrage abzuschließen.
|
||||
\item Systeme aus weniger, größeren Komponenten als feinkörnige Systeme sollten bevorzugt werden.
|
||||
\item Eine grobkörnige Beschreibung eines Systems betrifft große Unterkomponenten, während eine feinkörnige Beschreibung kleinere Komponenten betrifft, aus denen die größeren zusammengesetzt sind.
|
||||
\item \textbf{Dieser Ansatz ist bekannt als das Remote Facade Pattern.}
|
||||
\item Service Connectors die vom Service Descriptor generiert werden sind eng verbunden mit ihnen und müssen neu generiert werden wenn es Änderungen gibt
|
||||
\item Verwendung von Service Descriptor mindert nicht die Notwendigkeit eine gute Dokumentation zu verfassen. Diese ist für Client Entwickler wichtig um Dienste korrekt zu verwenden.
|
||||
\end{itemize}
|
||||
|
||||
\paragraph{Contract-First vs. Code-First}
|
||||
\begin{itemize}
|
||||
\item Contract-First
|
||||
\begin{itemize}
|
||||
\item Service Descriptors werden dazu verwendet die Server-seitigen Artefakte zu generieren. Definiert in XML und XSD
|
||||
\item Compiler kann DTO und Service Interface Klassen auf Basis des "Vertrages" generieren (in der jeweilig benötigten Programmiersprache)
|
||||
\end{itemize}
|
||||
\item Code-First
|
||||
\begin{itemize}
|
||||
\item Service Deskriptoren werden automatisch von
|
||||
Web-Service-Frameworks zur Laufzeit erstellt. Klassen, die als Service-Controller bezeichnet werden, werden in Java erstellt und annotiert. Diese Annotationen werden vom Service-Framework verwendet, welche Controller-Methoden aufgerufen werden sollen.
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
|
||||
|
||||
\section{Consumer-Driven Contracts Pattern}
|
||||
\subsection{Erkläre die Funktionalität inkl. Skizze}
|
||||
|
||||
Egal wie viel Zeit und Mühe in ein Design investiert wird, ein Dienst muss möglicherweise noch geändert werden. Veröffentlichte APIs die erweitert werden oder andere unerwartete Änderungen.
|
||||
|
||||
Service Anbieter können davon profitieren, wenn sie wissen, welche (und wie) Clients ihren Service verwenden.
|
||||
|
||||
Das hilft Serviceentwickler beim vornehmen an Änderungen der API, um deren Auswirkungen zu verstehen.
|
||||
|
||||
\begin{itemize}
|
||||
\item Serviceentwickler bekommen Integrations-Tests von jedem Client.
|
||||
\item Der Entwickler kann dann sehen welche Auswirkung seine Änderungen auf die verschiedenen Clients haben.
|
||||
\item Fehlgeschlagene Tests erleichtern die Fehlersuche.
|
||||
|
||||
\end{itemize}
|
||||
|
||||
|
||||
|
||||
\begin{figure}[!htp]
|
||||
\centering
|
||||
\includegraphics[width=0.5\textwidth]{pics/customer_driven_contracts.jpg}
|
||||
\end{figure}
|
||||
\subsection{Beschreibe die Konsequenzen der Nutzung}
|
||||
|
||||
\begin{itemize}
|
||||
\item Consumer-Driven Contracts werden geschrieben um Integrationstests ausführen zu können.
|
||||
\item Sollten versioniert werden, um Änderungen besser nachverfolgen zu können. (zusätzliche Aufteilung je nach Client)
|
||||
\item Contract tests sollten nach jeder Änderung am API oder der internen Logik überprüft werden.
|
||||
\item Dieses Pattern wird verwendet, wenn Entwickler ihre Clients kennen und die Clients auch Contracts zurückschicken können.
|
||||
\end{itemize}
|
||||
|
||||
\begin{itemize}
|
||||
\item Test Strategie
|
||||
\begin{itemize}
|
||||
\item sollte happy-path und falsche Verwendung vom API testen.
|
||||
\end{itemize}
|
||||
\item Asynchrone Services und jene mit langer Laufzeit
|
||||
\begin{itemize}
|
||||
\item Request/Acknowledge ist schwer zu testen
|
||||
\end{itemize}
|
||||
\item Dem Client die Spezifikation des API zu ermöglichen kann die Integrität dieser API in frage stellen.
|
||||
\end{itemize}
|
||||
|
||||
|
||||
|
||||
|
||||
\section{API Gateway Pattern}
|
||||
|
||||
|
||||
|
||||
\subsection{Erkläre die Funktionalität inkl. Skizze}
|
||||
|
||||
APIs die von Microservices zur Verfügung gestellt unterscheiden sich oft von den Anforderungen der Clients (Different clients need different data (desktop browser vs. mobile client))
|
||||
|
||||
Bei sehr detailieren APIs muss ein Client häufig mit mehreren Services interagieren. Auch die Netzwerkgeschwindigkeit ist bei jedem Client unterschiedlich.
|
||||
|
||||
|
||||
Um das zu umgehen wird ein API-Gateway eingefügt der einen zentralen Eintrittspunkt für Clients darstellt.
|
||||
|
||||
|
||||
Es gibt 2 Möglichkeiten wie ein Gateway Anfragen abarbeiten kann:
|
||||
|
||||
\begin{itemize}
|
||||
\item einfaches routen zum entsprechendem Service
|
||||
\item Anfragen an mehrere Services schicken
|
||||
\end{itemize}
|
||||
|
||||
|
||||
Anstatt eine einheitliche API für alle bereitzustellen, wird ein
|
||||
Gateway verwendet. Dieser kann für jeden Client eine andere API verfügbar machen.
|
||||
|
||||
\begin{figure}[!htp]
|
||||
\centering
|
||||
\includegraphics[width=0.5\textwidth]{pics/api_gateway.jpg}
|
||||
\end{figure}
|
||||
\subsection{Beschreibe die Konsequenzen der Nutzung}
|
||||
|
||||
\begin{itemize}
|
||||
\item Das Gateway isoliert den Client von den Microservices
|
||||
\item das optimale API je nach Client-Typ kann bereitgestellt werden
|
||||
\item reduziert die Anzahl an Anfragen
|
||||
\item vereinfacht den Client -> die Logik um verschiedene Services aufzurufen wird auf das Gateway verlagert.
|
||||
\item das Gateway ist eine weitere Komponente die Entwickelt und verwaltet werden muss...
|
||||
\item längere Antwortzeiten -> zusätzlicher Schritt (jedoch sind die Kosten für den extra Aufruf nicht sehr hoch)
|
||||
\end{itemize}
|
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 77 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 17 KiB |
BIN
pics/esb_1.jpg
Before Width: | Height: | Size: 82 KiB |
BIN
pics/esb_2.jpg
Before Width: | Height: | Size: 215 KiB |
BIN
pics/esb_3.jpg
Before Width: | Height: | Size: 119 KiB |
Before Width: | Height: | Size: 63 KiB |
Before Width: | Height: | Size: 72 KiB |
Before Width: | Height: | Size: 72 KiB |
Before Width: | Height: | Size: 58 KiB |
Before Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 22 KiB |
BIN
pics/rpc_api.jpg
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 58 KiB |
Before Width: | Height: | Size: 60 KiB |
Before Width: | Height: | Size: 6.7 KiB |
Before Width: | Height: | Size: 8.1 KiB |
Before Width: | Height: | Size: 96 KiB |
Before Width: | Height: | Size: 71 KiB |
Before Width: | Height: | Size: 235 KiB |
Before Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 103 KiB |
Before Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 71 KiB |
717
sw-arc.tex
|
@ -15,14 +15,721 @@
|
|||
% Document
|
||||
\begin{document}
|
||||
\author{Phillip Wo \\ Benjamin Moser \\ Daniel Sommer}
|
||||
\title{Enterprise Software Architecture - FAQ Ausarbeitung}
|
||||
\title{PSE Ausarbeitung}
|
||||
\maketitle
|
||||
\pagebreak
|
||||
\tableofcontents
|
||||
\pagebreak
|
||||
|
||||
\include{parts/01_layered-arc}
|
||||
%\include{parts/02_comp-based_arc}
|
||||
%\include{parts/03_service-orientated_arc}
|
||||
\part{Pattern im Projekt}
|
||||
\section{Layers Pattern}
|
||||
\subsection{Erkläre die Funktionsweise + Skizze}
|
||||
\begin{itemize}
|
||||
\item Client schickt eine Anfrage an Layer N
|
||||
\item Layer N reicht da er nicht vollständig alleine beantworten kann, Anfragen an darunterliegenden Layer weiter
|
||||
\item Eine Anfrage kann bei Bedarf auch in mehrere Anfragen an darunterliegende Layer geteilt werden
|
||||
\item dies wird immer weiter fortgesetzt bis Layer 1 erreicht ist
|
||||
\item dabei gehen Abhängigkeiten nur von oben nach unten
|
||||
\end{itemize}
|
||||
\begin{figure}[!htp]
|
||||
\centering
|
||||
\includegraphics[width=0.5\textwidth]{pics/esa_layers.jpg}
|
||||
\end{figure}
|
||||
\subsubsection{3 Schichten Architektur:}
|
||||
\begin{itemize}
|
||||
\item Data Source Layer (data): Zugriff auf Daten, kümmert sich um Kommunikation mit anderen Systemen (z.B.: Datenbank)
|
||||
\begin{itemize}
|
||||
\item beinhaltet DAO und DAOImpl >> DocumentDAO, DocumentlibraryDAO
|
||||
\end{itemize}
|
||||
\item Domain Layer(service): enthält Business Logik (Berechnungen, Datenvalidierung, ...)
|
||||
\begin{itemize}
|
||||
\item beinhaltet
|
||||
\begin{itemize}
|
||||
\item \textbf{Service Layer Pattern} (aka Session Fassade - siehe~\ref{sec:slp})
|
||||
\item DTO >> DocumentDTO
|
||||
\item Mapper >> DocumentMapper
|
||||
\begin{minted}[breaklines=true]{java}
|
||||
public static Document toEntity(DocumentDTO documentDTO, Document document){};
|
||||
public static DocumentDTO toDTO(Document document){};
|
||||
\end{minted}
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
\item Presentation Layer(web): serverseitig, kümmert sich um Benutzerinteraktion
|
||||
\begin{itemize}
|
||||
\item Controller (ViewHelper) >> DocumentController, DocumentListController
|
||||
\item View (WebApp)
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
\begin{figure}[!htp]
|
||||
\centering
|
||||
\includegraphics[width=0.4\textwidth]{pics/src_structure.png}
|
||||
\end{figure}
|
||||
\subsection{Beschreibe ein konkretes Anwendungsbeispiel}
|
||||
\begin{itemize}
|
||||
\item Java Enterprise Edition (JEE) Architektur bestehend aus
|
||||
\begin{itemize}
|
||||
\item Client Tier (Client Machine)
|
||||
\item Web Tier, Business Tier (Java EE Server)
|
||||
\item EIS Tier (Database Server)
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
\section{Data Access Object (DAO) Pattern}
|
||||
Befindet sich im Projekt in data und damit innerhalb des Data Layer.
|
||||
\subsection{Erkläre die Funktion + Skizze}
|
||||
\begin{itemize}
|
||||
\item Client erstellt ein DAO Object und kann nach Entitäten suchen, einfügen, löschen, etc.
|
||||
\item das DAO selbst soll keine spezifischen Elemente enthalten (Entity Manager, SQL Exception -> stattdessen DAOException)
|
||||
\item dadurch entsteht eine Kapselung bei der die DAOImpl ohne den Client zu verändern ausgetauscht werden kann
|
||||
\end{itemize}
|
||||
\begin{figure}[!htp]
|
||||
\centering
|
||||
\includegraphics[width=0.8\textwidth]{pics/dao_pat1.jpg}
|
||||
\end{figure}
|
||||
\begin{minted}[breaklines=true]{java}
|
||||
@ApplicationScoped
|
||||
public class DocumentDAOImpl implements DocumentDAO, Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Logger logger = LoggerFactory.getLogger(DocumentDAOImpl.class);
|
||||
@PersistenceContext
|
||||
private EntityManager entityMangaer;
|
||||
|
||||
\end{document}
|
||||
@Override
|
||||
public List<Document> findByCommunity(Community community) {...}
|
||||
|
||||
@Override
|
||||
public List<Document> findByUser(User user) {...}
|
||||
|
||||
@Override
|
||||
public void insert(Document document) {...}
|
||||
|
||||
@Override
|
||||
public void delete(Document document) {...}
|
||||
|
||||
@Override
|
||||
public Document findById(Long id) {...}
|
||||
}
|
||||
\end{minted}
|
||||
\subsection{Nenne die Konsequenzen der Anwendung}
|
||||
\begin{itemize}
|
||||
\item Zugriff auf persistenten Speicher wird abstrahiert
|
||||
\item Details des Speichers werden versteckt
|
||||
\item ermöglicht einheitlichen Zugriff auf Daten
|
||||
\item entkoppelt Implementierung von Persistierung (Datenbank,...)
|
||||
\item ermöglicht Objektorientierte Ansicht des Speichers
|
||||
\end{itemize}
|
||||
\section{Service Layer Pattern (auch Session Fassade)}\label{sec:slp}
|
||||
\subsection{Erkläre die Funktion + Skizze}\label{subsubsec:service-layer-pattern}
|
||||
\begin{itemize}
|
||||
\item Der Service Layer delegiert auf die Business Logik (Zeile 68 community.setDocumentlibrary) und zum DAO (z.B. Zeile 66)
|
||||
\item Bei wenig Logik wird zumindest Transaktions (Zeile 40), Error (ab Zeile 42) und Validierungshandling (ab Zeile 23) im Service erledigt
|
||||
\end{itemize}
|
||||
\begin{minted}[xleftmargin=\parindent,linenos,breaklines=true]{java}
|
||||
@Local(DocumentService.class)
|
||||
@Remote(DocumentServiceRemote.class)
|
||||
@Stateless
|
||||
public class DocumentServiceImpl implements DocumentService, DocumentServiceRemote, Serializable {
|
||||
private static final long serialVersionUID = -1L;
|
||||
private static final Logger logger = LoggerFactory.getLogger(DocumentServiceImpl.class);
|
||||
|
||||
@Inject
|
||||
private DocumentDAO documentDAO;
|
||||
@Inject
|
||||
private DocumentlibraryDAO documentlibraryDAO;
|
||||
@Inject
|
||||
private CommunityDAO communityDAO;
|
||||
@Inject
|
||||
private UserDAO userDAO;
|
||||
@Inject
|
||||
private MessageDAO messageDAO;
|
||||
@Override
|
||||
public DocumentDTO addDocument(Long communityID, String userID, byte[] data, String filename) {
|
||||
Document addedDocument;
|
||||
User user;
|
||||
|
||||
// Validierungshandling gefolgt von Error Handling
|
||||
try {
|
||||
if (communityID <= 0) throw new IllegalArgumentException("community must not be empty");
|
||||
if (userID == null) throw new IllegalArgumentException("user must not be empty");
|
||||
if (data == null) throw new IllegalArgumentException("uploaded file must not be empty");
|
||||
if (filename == null) throw new IllegalArgumentException("filename must not be empty");
|
||||
|
||||
Documentlibrary documentlibrary = documentlibraryDAO.findByCommunityId(communityID);
|
||||
|
||||
//create a document library, if there isn't already one in the database
|
||||
if (documentlibrary == null) {
|
||||
documentlibrary = addDocumentlibrary(communityID);
|
||||
}
|
||||
|
||||
user = userDAO.getByUserId(userID);
|
||||
|
||||
addedDocument = new Document(documentlibrary, user, filename, data);
|
||||
documentDAO.insert(addedDocument); // Transaktionshandling
|
||||
logger.info(String.format("Document %s saved in database", filename));
|
||||
// Error Handling
|
||||
} catch (IllegalArgumentException iaex) {
|
||||
String errorMsg = "Uploading file failed (illegal argument)";
|
||||
logger.error(errorMsg, iaex);
|
||||
throw new ServiceException(errorMsg);
|
||||
|
||||
} catch (Exception ex) {
|
||||
String errorMsg = String.format("Uploading file %s failed.", filename);
|
||||
logger.error(errorMsg, ex);
|
||||
throw new ServiceException(errorMsg);
|
||||
}
|
||||
|
||||
String msgText = "Uploaded Document " + filename + " by user " + user.getUserId();
|
||||
addMessageToStream(communityID, user, msgText, addedDocument);
|
||||
return DocumentMapper.toDTO(addedDocument);
|
||||
}
|
||||
|
||||
|
||||
private void addMessageToStream(Long communityID, User user, String text, Document document) {...}
|
||||
|
||||
private Documentlibrary addDocumentlibrary(Long communityID) {
|
||||
logger.info("Create missing documentlibrary");
|
||||
Community community;
|
||||
Documentlibrary documentlibrary = new Documentlibrary();
|
||||
documentlibraryDAO.insert(documentlibrary); // Delegation zum DAO
|
||||
community = communityDAO.findById(communityID); // Delegation zum DAO
|
||||
community.setDocumentlibrary(documentlibrary); // Delegation zur Business Logik (Entity)
|
||||
communityDAO.update(community); // Delegation zum DAO
|
||||
return documentlibrary;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DocumentDTO> getDocumentsFromCommunity(Long communityID) {...}
|
||||
|
||||
@Override
|
||||
public List<DocumentDTO> getDocumentsFromUser(String userID) {...}
|
||||
|
||||
@Override
|
||||
public void removeDocument(Long documentID) {...}
|
||||
|
||||
@Override
|
||||
public DocumentDTO getDocumentById(Long documentID) {...}
|
||||
}
|
||||
\end{minted}
|
||||
\begin{figure}[!htp]
|
||||
\centering
|
||||
\includegraphics[width=0.8\textwidth]{pics/sl_pat1.jpg}
|
||||
\end{figure}
|
||||
\subsection{Nenne die Konsequenzen der Anwendung}
|
||||
\begin{itemize}
|
||||
\item Reduzierung der Abhängigkeiten zwischen Presentation und Domain Layer
|
||||
\item Zentralisiertes Sicherheits und Transaktionshandling
|
||||
\item verbirgt vor Client Komplexität der Business Logik
|
||||
\item stellt Client ein grobkörniges Interface zur Verfügung
|
||||
\item gut für Remote Aufrufe geeignet (weniger Aufrufe)
|
||||
\end{itemize}
|
||||
|
||||
\section{Model-View-Controller (MVC) Pattern}
|
||||
\subsection{Erkläre die Funktion + Skizze}
|
||||
MVC unterteilt eine interaktive Applikation in drei Teile: Model, View und Controller.
|
||||
\begin{itemize}
|
||||
\item Controller und View befinden sich im Presentation Layer und haben gegenseitig Abhängigkeiten
|
||||
\item Das Model darf keine Abhängigkeiten haben (Controller und View hängen vom Model ab)
|
||||
\end{itemize}
|
||||
\begin{figure}[!htp]
|
||||
\centering
|
||||
\includegraphics[width=0.8\textwidth]{pics/mvc_pat.jpg}
|
||||
\end{figure}
|
||||
\subsubsection{Model}
|
||||
\begin{itemize}
|
||||
\item Es befinden sich Teile im Domain und Data Source Layer.
|
||||
\item Das Model enthält die Kernfunktionalität und Daten. (z.B.: Datenbankzugriff)
|
||||
\item Im Projekt ... % TODO
|
||||
\end{itemize}
|
||||
\subsubsection{View}
|
||||
\begin{itemize}
|
||||
\item Im Projekt im Ordner WebApp zu finden.
|
||||
\item Enthält im Projekt xhtml Dateien zur Darstellung und User Interaktion
|
||||
\end{itemize}
|
||||
\subsubsection{Controller}
|
||||
\begin{itemize}
|
||||
\item Im Projekt sind Controllerklassen im Ordner web zu finden.
|
||||
\item Sie enthalten die Logik und behandeln Benutzereingaben
|
||||
\end{itemize}
|
||||
\subsection{Nenne die Konsequenzen der Anwendung}
|
||||
\begin{itemize}
|
||||
\item Visualisierung abhängig vom Model - nicht umgekehrt
|
||||
\item verschiedene Darstellungen möglich
|
||||
\item einfaches Testen der Domain-Logik
|
||||
\item gute Strukturierung
|
||||
\item View wird leichter austausch bzw. änderbar
|
||||
\end{itemize}
|
||||
\section{Front Controller}
|
||||
\subsection{Erkläre die Funktion + Skizze}
|
||||
\begin{itemize}
|
||||
\item Client schickt Request an Front Controller
|
||||
\item FC erfasst nur Infos die er für die weiter Delegation braucht
|
||||
\item FC gibt Request an entsprechenden ConcreteCommand oder View weiter
|
||||
\item es gibt zwei Implementierungsvarianten des Controller
|
||||
\begin{multicols}{2}
|
||||
\begin{itemize}
|
||||
\item Servlet
|
||||
\item ConcreteCommand
|
||||
\end{itemize}
|
||||
\end{multicols}
|
||||
\end{itemize}
|
||||
\begin{figure}[h!]
|
||||
\centering
|
||||
\includegraphics[width=0.5\textwidth]{pics/fc_pat.jpg}
|
||||
\end{figure}
|
||||
\subsection{Beschreibe ein konkretes Anwendungsbeispiel}
|
||||
\begin{itemize}
|
||||
\item Java Server Faces (bei Java Server Faces enthält das File zwar keinen Java Code, interagiert aber direkt mit Java Code einer Backing Bean)
|
||||
\item Im Projekt wurde der Front Controller in Form eines Servlet realisiert, dessen Einbindung in der Konfigurationsdatei "`web.xml"' erfolgt:
|
||||
\end{itemize}
|
||||
\begin{minted}[linenos,breaklines=true]{xml}
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
|
||||
...
|
||||
<servlet>
|
||||
<servlet-name>Faces Servlet</servlet-name>
|
||||
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
</servlet>
|
||||
<servlet-mapping>
|
||||
<servlet-name>Faces Servlet</servlet-name>
|
||||
<url-pattern>*.xhtml</url-pattern>
|
||||
</servlet-mapping>
|
||||
\end{minted}
|
||||
\subsection{Anwendung im Projekt}
|
||||
JavaServer Faces: mächtiges Framework, wo das MVC Pattern verwendet wird. Auf der einen Seite
|
||||
stehen die reinen Views (XHTML Seiten) und auf der anderen Seite Java Beans (Java Klassen), die als
|
||||
View Helper fungieren können. Beispiel: layered/MVC-JSF
|
||||
Primefaces ist eine konkrete Implementierung der JavaServer Faces (siehe POM.XML).
|
||||
|
||||
\begin{minted}[linenos,breaklines=true]{xml}
|
||||
<?xml version='1.0' encoding='UTF-8' ?>
|
||||
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
|
||||
xmlns:h="http://xmlns.jcp.org/jsf/html"
|
||||
xmlns:p="http://primefaces.org/ui"
|
||||
xmlns:f="http://xmlns.jcp.org/jsf/core"
|
||||
template="communityTemplate.xhtml">
|
||||
<ui:define name="communityContent">
|
||||
<h1>#{msg.document_manage_title}</h1>
|
||||
<f:metadata>
|
||||
<f:viewAction action="#{documentListController.loadDocumentsFromCommunity()}" />
|
||||
</f:metadata>
|
||||
|
||||
<h:form id="doclistform">
|
||||
<p:commandButton value="Refresh list" actionListener="#{documentListController.loadDocumentsFromCommunity()}" update="@form doclistform"></p:commandButton>
|
||||
<p:dataTable id="doclisttable" value="#{documentListController.communityDocuments}" var="docs">
|
||||
<p:column class="documenttimecolumn" headerText="#{msg.document_uploaded}">#{docs.createdTimestamp}</p:column>
|
||||
<p:column class="documenttimecolumn" headerText="#{msg.label_userid}">#{docs.user.userId}</p:column>
|
||||
<p:column headerText="#{msg.label_filename}">#{docs.filename}</p:column>
|
||||
<p:column headerText="" class="documentbuttoncolumn">
|
||||
<p:commandButton value="#{msg.button_download}" ajax="false"
|
||||
onclick="PrimeFaces.monitorDownload(start, stop);">
|
||||
<p:fileDownload value="#{documentController.downloadDocument(docs.id)}"/>
|
||||
</p:commandButton>
|
||||
</p:column>
|
||||
<p:column headerText="" class="documentbuttoncolumn">
|
||||
<p:commandButton id="btnDel" value="#{msg.button_delete}"
|
||||
actionListener="#{documentController.removeDocument(docs.id)}"
|
||||
update="@form doclistform">
|
||||
</p:commandButton>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</h:form>
|
||||
<h:form id="formdocupload" enctype="multipart/form-data">
|
||||
<p:fileUpload id="fileupload"
|
||||
dragDropSupport="false"
|
||||
update="@form doclistform"
|
||||
fileUploadListener="#{documentController.uploadDocument}"
|
||||
allowTypes="/(\.|\/)(pdf|jpe?g|docx)\$/" sizeLimit="5000000"
|
||||
mode="advanced" label="Add document (.pdf .jpg .docx)">
|
||||
</p:fileUpload>
|
||||
</h:form>
|
||||
<p:messages id="feedbackBox" severity="info,error" showDetail="true" showSummary="false">
|
||||
<p:autoUpdate/>
|
||||
</p:messages>
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
\end{minted}
|
||||
|
||||
\subsection{Nenne die Konsequenzen der Anwendung}
|
||||
\begin{itemize}
|
||||
\item es muss nur EIN (Front) Controller konfiguriert werden
|
||||
\item da bei jedem Request ein neues Command Objekt erzeugt wird ist Thread-Safety nicht notwendig
|
||||
\item da nur EIN Controller sind auch Erweiterungen durch z.B.: Decorator einfach (auch zur Laufzeit)
|
||||
\end{itemize}
|
||||
\section{View Helper}
|
||||
\subsection{Erkläre die Funktion + Skizze}
|
||||
\begin{figure}[h!]
|
||||
\centering
|
||||
\includegraphics[width=0.8\textwidth]{pics/view-helper_pat1.jpg}
|
||||
\end{figure}
|
||||
\begin{itemize}
|
||||
\item View (xhtml-Dateien im Ordner webapp) delegiert Aufgaben an Helper (*Controller-Klassen - z.B. DocumentController im Ordner web)
|
||||
\item Helper adaptieren View zu Model (Klassen in den Ordnern service und data)
|
||||
\item in View befindet sich HTML Code im ViewHelper Java Code zur Aufbereitung der Daten (+ wenig HTML)
|
||||
\end{itemize}
|
||||
\subsection{Nenne die Konsequenzen der Anwendung}
|
||||
\begin{itemize}
|
||||
\item kapselt Design-Code in View und View-Processing-Code Logik in Helper
|
||||
\item steigert Wiederverwendbarkeit, Wartbarkeit und Strukturierungsqualität der Anwendung
|
||||
\item vereinfacht Tests (Helperfunktionen ohne View)
|
||||
\item bessere Trennung zwischen
|
||||
\begin{itemize}
|
||||
\item Presentation und Data Source Layer
|
||||
\item Entwickler und Designer
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
|
||||
|
||||
\section{Dependency Injection (don't call us, we'll call you)}
|
||||
\subsection{Erkläre die Funktion + Skizze}
|
||||
\begin{figure}[!htp]
|
||||
\centering
|
||||
\includegraphics[width=0.5\textwidth]{pics/dependency_inj_pat.jpg}
|
||||
\includegraphics[width=0.4\textwidth]{pics/dependency_inj_spring_pat.jpg}
|
||||
\end{figure}
|
||||
\begin{itemize}
|
||||
\item Grundidee sind loose gekoppelte Objekte
|
||||
\item Objekte werden mittels externem Assembler verknüpft
|
||||
\item Abhängigkeiten bestehen nur auf Interfaces
|
||||
\item Assembler Objekt (Framework) erzeugt die Interface-Implementierungen (z.B.: durch Factory)
|
||||
\item Es wird zwischen Constructor Injection und Setter Injection unterschiedlichen
|
||||
\begin{minted}[linenos,breaklines=true]{java}
|
||||
// Constructor Injection
|
||||
puplic class Client
|
||||
{
|
||||
private Interface iface;
|
||||
public Client(Interface iface)
|
||||
{
|
||||
this.iface = iface;
|
||||
}}
|
||||
|
||||
// Setter Injection
|
||||
puplic class Client
|
||||
{
|
||||
private Interface iface;
|
||||
public setIface(Interface iface)
|
||||
{
|
||||
this.iface = iface;
|
||||
}}
|
||||
\end{minted}
|
||||
\end{itemize}
|
||||
\begin{itemize}
|
||||
\item Im Spring Context: Dependency Injection mit XML-Datei
|
||||
\item alle Beans sind dort gelistet und werden verknüpft
|
||||
\item Context wird geladen damit alles verknüpft ist
|
||||
\item erspart Factories
|
||||
\end{itemize}
|
||||
\subsection{Nenne die Konsequenzen der Anwendung}
|
||||
\begin{itemize}
|
||||
\item loose gekoppelte Objekte
|
||||
\item Referenzen nurmehr auf Interfaces
|
||||
\item hohe Flexibilität (Strategy, Proxy,..)
|
||||
\item bessere Erweiterbarkeit und Testbarkeit
|
||||
\item bei Spring kann Dependency Injection mittels XML oder Annotation erfolgen
|
||||
\begin{itemize}
|
||||
\item Vorteil Annotation: Typ-Sicherheit (Tippfehler passieren schnell im XML)
|
||||
\item Nachteil Annotation: nicht so flexibel wie XML
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
\section{Data Transfer Object (DTO) Pattern}
|
||||
\subsection{Erkläre die Funktion (Skizze - ein Grund für DTO)}
|
||||
\begin{figure}[!htp]
|
||||
\centering
|
||||
\includegraphics[width=0.9\textwidth]{pics/lok-vs-remote.jpg}
|
||||
\end{figure}
|
||||
\begin{itemize}
|
||||
\item Transportiert Daten zwischen Prozessen um Remote Methodenaufrufe zu minimieren
|
||||
\item besteht aus Fields, Getter und Setter
|
||||
\item fasst Daten verschiedener Objekte zusammen die vom Remote Objekt benötigt werden
|
||||
\item ev. Map, Record Set, ...
|
||||
\end{itemize}
|
||||
\subsection{Beschreibe ein konkretes Anwendungsbeispiel}
|
||||
% todo: Anwendungsbeispiel
|
||||
\subsection{Nenne die Konsequenzen der Anwendung}
|
||||
\begin{itemize}
|
||||
\item kapselt und versteckt
|
||||
\item nimmt Komplexität
|
||||
\item steigert Effizienz da weniger Aufrufe über Remotegrenze
|
||||
\end{itemize}
|
||||
\section{Page-Object-Pattern}
|
||||
PageObjectPattern
|
||||
|
||||
HTML – wrappen mit JavaCode, um es zu manipulieren
|
||||
|
||||
GUI-Test-Klasse und Page-Object
|
||||
|
||||
Über die Page-Object-Klasse manipuliere ich das HTML-Dokument
|
||||
|
||||
Bei HTML-Änderung muss ich nur Page-Objekt ändern und ansonsten nichts angreifen (Verkapselung)
|
||||
\section{Remote}
|
||||
\section{Beschreibe die Unterschiede zwischen lokalem und Remote Interface Design}
|
||||
\begin{itemize}
|
||||
\item Aufrufe innerhalb des Prozesses sind schneller als über Prozessgrenzen
|
||||
\item lokale Interfaces sind möglichst fein-granular während Remote Interfaces grob-granular sein müssen (weniger Aufrufe - Effizienz)
|
||||
\item viele kleine Aufrufe mit wenigen Daten sind "teuer" (Latenz durch Verbindungsherstellung)
|
||||
\end{itemize}
|
||||
\section{Beschreibe drei Situationen wo Multiple Prozesse in Applikationen verwendet werden müssen}
|
||||
\begin{itemize}
|
||||
\item Trennung zwischen Clients und Servern in Business Software
|
||||
\item Trennung zwischen server-basierter Applikationssoftware und Datenbank (SQL ist als Remote Interface designed, daher sind hier schnelle Abfragen möglich)
|
||||
\item Trennung wegen unterschiedlichen Anbietern oder Programmiersprachen
|
||||
\end{itemize}
|
||||
|
||||
\section{Beschreibe das folgende Diagramm. Was können wir daraus für das Design von Remote Interfaces folgern?}
|
||||
\begin{itemize}
|
||||
\item speziell bei "teuren" Remote Calls ist es empfehlenswert weniger Calls mit großen Datenmengen anstatt vielen Calls mit wenigen Daten zu machen
|
||||
\item dieser Gedanke befürwortet auch den Einsatz von DTO um Calls und Daten zu bündeln
|
||||
\end{itemize}
|
||||
\begin{figure}[!htp]
|
||||
\centering
|
||||
\includegraphics[width=0.9\textwidth]{pics/lok-vs-remote.jpg}
|
||||
\end{figure}
|
||||
\section{Exception Handling}
|
||||
\section{Beschreibe den Unterschied zwischen Checked und Runtime Exceptions in Java (inkl. Klassendiagramm)}
|
||||
\begin{itemize}
|
||||
\item Checked Exceptions (z.B. SQL-Exception) leiten von Exception Klasse ab und müssen behandelt werden (trows - catch)
|
||||
\begin{itemize}
|
||||
\item Verwendung für Probleme die durch User behoben werden können (alternative Aktion)
|
||||
\end{itemize}
|
||||
\item Unchecked Exceptions (z.B. NullPointerException) leiten von RuntimeException ab
|
||||
\begin{itemize}
|
||||
\item Verwendung für technische Probleme (User kann nichts machen außer neu starten)
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
\begin{figure}[!htp]
|
||||
\centering
|
||||
\includegraphics[width=0.3\textwidth]{pics/except_class_dia.jpg}
|
||||
\end{figure}
|
||||
\section{Beschreibe einen Use Case für eine Checked Exceptions in Java}
|
||||
\begin{itemize}
|
||||
\item eine Netzwerkübertragung schlägt fehl - es ist vorgesehen, dass der Applikations-User dies neu anstoßen kann
|
||||
\end{itemize}
|
||||
\section{Beschreibe einen Use Case für eine Runtime Exceptions in Java}
|
||||
\begin{itemize}
|
||||
\item Die Datenbank ist beschädigt - die Exception geht durch alle Layer erst mit
|
||||
Implementierungsspezifischer Exception später mit Runtime ohne Stacktrace (Sicherheit) bis zum User.
|
||||
\end{itemize}
|
||||
\section{Beschreibe 5 Best Practice Beispiele beim Einsatz von Exceptions}
|
||||
\begin{itemize}
|
||||
\item Exceptions nicht für Programmflusskontrolle verwenden (schlechte Performance)
|
||||
\item offene Ressourcen schließen (try-with-resources bzw. close im finally)
|
||||
\item selbst erstellte Exceptions auch mit nützlichen Infos ausstatten
|
||||
\item Implementierungsspezifische Exceptions nicht bis zum User durchwerfen (stattdessen catch + trow RuntimeException)
|
||||
\item dokumentieren mit @trows im DOC, testen mit JUnit
|
||||
\end{itemize}
|
||||
|
||||
\section{Beschreibe 5 Exception Handling Anti Pattern}
|
||||
\begin{itemize}
|
||||
\item Log and Trow (nie beides: entweder, oder)
|
||||
\item Trowing Exception bzw. catch Exception (spezifischere anstatt Basisklasse verwenden)
|
||||
\item Destructive Wrapping (wenn bei catch + trow = wrapping nicht die Original Exception weitergegeben wird)
|
||||
\item Log and return Null (provoziert an einer anderen Stelle eine NullPointerException)
|
||||
\item Catch and Ignore
|
||||
\item Unsupported Operation return Null (besser UnsupportedOperationException)
|
||||
\end{itemize}
|
||||
\section{Logging}
|
||||
\section{Nenne die Nachteile von debugging mit printf() sowie die Vorteile die Logging Frameworks wie log4j bieten}
|
||||
\subsection{Nachteile printf()}
|
||||
\begin{itemize}
|
||||
\item Produktiv-Code wird überfüllt -> erschwert Lesbarkeit
|
||||
\item Consolenausgabe wird bei vielen prints auch schnell unübersichtlich
|
||||
\item im Falle eines vorzeitigen Absturzes können Ausgabedaten verloren gehen
|
||||
\item Performance bei vielen Logprints
|
||||
\end{itemize}
|
||||
\subsection{Vorteile Logging mittels Framework (z.B.: log4j)}
|
||||
\begin{itemize}
|
||||
\item Nutzt ein einheitliches Format / Konventionen
|
||||
\item logging kann optional an und ausgeschalten werden
|
||||
\item durch verschiedene Log-level können Logs gefiltert erstellt werden
|
||||
\item Layout für Ausgabe kann zentral definiert/geändert werden
|
||||
\end{itemize}
|
||||
\part{Project Structure}
|
||||
\section{Annotationen}
|
||||
\subsection{@MappedSuperclass}
|
||||
\begin{itemize}
|
||||
\item ist im Hybernate Framework eine Klasse durch die gemeinsame Felder definiert werden.
|
||||
\item definiert eine abstrakte Superklasse
|
||||
\end{itemize}
|
||||
|
||||
@Produces – kommt während deployment, markiert Factory Method damit man nicht direkt auf die Klasse zugreifen muss
|
||||
@Typed – zeigt die Vererbung Wieso bei uns allein stehend?
|
||||
@Named – Zeigt bei Mehrdeutigkeit das richtige Objekt mit dem Namen
|
||||
@Resource – fast wie Dependency Injection
|
||||
@Stateless – speichert den Client Status nicht
|
||||
@Entity – Data Access Layer
|
||||
@Table – Tabellenname im SQL
|
||||
@Column – SQL-Spalten nullable=false
|
||||
@OneToMany Beziehung
|
||||
@JoinColums – welche Spalten zusammen gehören FK
|
||||
@OneToMany FK auf anderen Seite
|
||||
@ApplicationScoped – lebt die ganze Applikation lang, wird einmal gemacht.
|
||||
@PersistenceContext – persistance.xml auslesen für Treiber und andere JPA Geschichten + Data Source. Entity Manager Injection.
|
||||
@Id – das ist die id
|
||||
@GeneratedValue – Wert kommt aus der DB
|
||||
@Local – Klasse für lokale Aufrufe.
|
||||
@Remote – interprozessaufrufe. RMI
|
||||
@ApplicationException – Rollback wenn so eine Exception kommt, Nachricht zum Client.
|
||||
\section{Patterns in Practice}
|
||||
Data Access Layer
|
||||
Entity – Java Repräsentation vom DB Entity
|
||||
DAO damit man auf die Entities zugreifen kann. DB abstrahieren. Methoden mit denen man auf die DB zugreifen kann.
|
||||
DAOImpl – Implementierung
|
||||
DAOImpl – DAOException fehlt. Schlecht weil Input wird nicht kontrolliert. EntityManager in try catch, sonst kann es kleschen. Zusätzlich in DaoException wrappen.
|
||||
AbstractEntity – hier wird die id gemanaged
|
||||
Service Layer
|
||||
DTO – Aufrufgeschw. Verringern, nicht jedes Objekt einzeln aufrufen, sondern mit einmal alle notwendigen Objekte.
|
||||
Mapper – von DTO in Entity und Entity ins DTO.
|
||||
|
||||
FrontController web.xml
|
||||
ViewHelper *ServiceImpl
|
||||
\section{Konfigurationsdateien (pom.xml), (persistence.xml) und noch a bissl mehr Scheiß}
|
||||
Resource plugin – klar für Ressourcen
|
||||
Wildfly – server
|
||||
Primeafce = jsf Framework
|
||||
Jacoco = test Coverage
|
||||
Slf4j = logger
|
||||
Jaxb – xml
|
||||
Cdi = context dependancy injection
|
||||
\section{Reihenfolge - Wildfly - Abfolge - einzelne Schritte}
|
||||
Reihenfolge:
|
||||
\begin{multicols}{2}
|
||||
\begin{enumerate}
|
||||
\item Compile
|
||||
\item Surefire (unitTests)
|
||||
\item Packaging - war file erstellen
|
||||
\item Wildfly - fressen und deployen
|
||||
\item Failsafe IT-test
|
||||
\item MVN site
|
||||
\item Gui test
|
||||
\end{enumerate}
|
||||
\end{multicols}
|
||||
|
||||
\section{Frageart Prüfung}
|
||||
Welche Fehler können bei Exception-Handling vorkommen in unserem Projekt?? – wie funktioniert es grundsätzlich in unserem Code
|
||||
|
||||
DocumentDAO – DocumentService – DocumentController – so sollte Exception-Handling implementiert warden
|
||||
|
||||
DAO wirft Exception – im ServiceLayer wird dies gefangen und der Stack-Trace wird im weggeloggt und eine benutzerfreundliche Fehlermeldung wird ausgegeben (Destructive Wrapping).
|
||||
|
||||
Alle Patterns, die vorkommen – praktische Beispiele aus dem Code
|
||||
|
||||
Was sind JavaBeans? Wie funktioniert das Konzept? Wie wird es genau implementiert?
|
||||
NamedBean, TypedBean etc.
|
||||
|
||||
DTO
|
||||
|
||||
|
||||
\section{Die CONFIG-Files}
|
||||
\begin{figure}[!htp]
|
||||
\centering
|
||||
\includegraphics[width=0.7\textwidth]{pics/ConfigFiles.png}
|
||||
\end{figure}
|
||||
\subsection{web.xml}
|
||||
\begin{itemize}
|
||||
\item konfiguriert den Java Webserver (Wildfly - JBOSS)
|
||||
\item befindet sich im Ordner \textbf{src/main/webapp/WEB-INF/web.xml}
|
||||
\end{itemize}
|
||||
|
||||
\begin{minted}[linenos,breaklines=true]{xml}
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
|
||||
...
|
||||
<servlet>
|
||||
<servlet-name>Faces Servlet</servlet-name>
|
||||
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
</servlet>
|
||||
<servlet-mapping>
|
||||
<servlet-name>Faces Servlet</servlet-name>
|
||||
<url-pattern>*.xhtml</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Security roles -->
|
||||
<security-role>
|
||||
<description>administrators</description>
|
||||
<role-name>ADMIN</role-name>
|
||||
</security-role>
|
||||
<security-role>
|
||||
<description>portal administrators</description>
|
||||
<role-name>PORTALADMIN</role-name>
|
||||
</security-role>
|
||||
<security-role>
|
||||
<description>standard user</description>
|
||||
<role-name>USER</role-name>
|
||||
</security-role>
|
||||
|
||||
<!-- Security constraints -->
|
||||
<security-constraint>
|
||||
<web-resource-collection>
|
||||
<web-resource-name>admin area</web-resource-name>
|
||||
<url-pattern>/admin/*</url-pattern>
|
||||
</web-resource-collection>
|
||||
<auth-constraint>
|
||||
<role-name>ADMIN</role-name>
|
||||
</auth-constraint>
|
||||
</security-constraint>
|
||||
|
||||
<security-constraint>
|
||||
<web-resource-collection>
|
||||
<web-resource-name>community area</web-resource-name>
|
||||
<url-pattern>/community/*</url-pattern>
|
||||
</web-resource-collection>
|
||||
<auth-constraint>
|
||||
<role-name>USER</role-name>
|
||||
<role-name>PORTALADMIN</role-name>
|
||||
<role-name>ADMIN</role-name>
|
||||
</auth-constraint>
|
||||
</security-constraint>
|
||||
|
||||
<security-constraint>
|
||||
<web-resource-collection>
|
||||
<web-resource-name>user administration area</web-resource-name>
|
||||
<url-pattern>/userAdministration/*</url-pattern>
|
||||
</web-resource-collection>
|
||||
<auth-constraint>
|
||||
<role-name>USER</role-name>
|
||||
<role-name>PORTALADMIN</role-name>
|
||||
<role-name>ADMIN</role-name>
|
||||
</auth-constraint>
|
||||
</security-constraint>
|
||||
|
||||
|
||||
<security-constraint>
|
||||
<web-resource-collection>
|
||||
<web-resource-name>user functionalities</web-resource-name>
|
||||
<url-pattern>/user.xhtml</url-pattern>
|
||||
<url-pattern>/userlist.xhtml</url-pattern>
|
||||
<url-pattern>/notImplemented.xhtml</url-pattern>
|
||||
</web-resource-collection>
|
||||
<auth-constraint>
|
||||
<role-name>USER</role-name>
|
||||
<role-name>PORTALADMIN</role-name>
|
||||
<role-name>ADMIN</role-name>
|
||||
</auth-constraint>
|
||||
</security-constraint>
|
||||
|
||||
<security-constraint>
|
||||
<web-resource-collection>
|
||||
<web-resource-name>other functionalities</web-resource-name>
|
||||
<url-pattern>/notImplemented.xhtml</url-pattern>
|
||||
</web-resource-collection>
|
||||
<auth-constraint>
|
||||
<role-name>USER</role-name>
|
||||
<role-name>PORTALADMIN</role-name>
|
||||
<role-name>ADMIN</role-name>
|
||||
</auth-constraint>
|
||||
</security-constraint>
|
||||
|
||||
<login-config>
|
||||
<auth-method>FORM</auth-method>
|
||||
<realm-name>pse</realm-name>
|
||||
<form-login-config>
|
||||
<form-login-page>/login.xhtml</form-login-page>
|
||||
<form-error-page>/login.xhtml</form-error-page>
|
||||
<!-- <form-error-page>/loginerror.xhtml</form-error-page> -->
|
||||
</form-login-config>
|
||||
</login-config>
|
||||
</web-app>
|
||||
\end{minted}
|
||||
\end{document}
|