added some shit

This commit is contained in:
Daniel Sommer 2019-02-27 22:02:33 +01:00
parent 5cba3e969d
commit 07dc0d0ff4
8 changed files with 303 additions and 78 deletions

1
.gitignore vendored
View File

@ -11,3 +11,4 @@
*.out
*.gz
*.lot
_minted*

View File

@ -15,26 +15,41 @@
\end{itemize}
3 Schichten Architektur:
\begin{itemize}
\item Presentation Layer: serverseitig, kümmert sich um Benutzerinteraktion
\item Domain Layer: enthält Business Logik (Berechnungen, Datenvalidierung, ...)
\item Data Source Layer: Zugriff auf Daten, kümmert sich um Kommunikation mit anderen Systemen (z.B.: Datenbank)
\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 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
\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}
\subsubsection{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}
\begin{itemize}
\item Client Tier (Client Machine)
\item Web Tier, Business Tier (Java EE Server)
\item EIS Tier (Database Server)
\end{itemize}
\end{itemize}
\subsubsection{Nenne die Konsequenzen der Anwendung}
\begin{itemize}
\item hilft dabei eine Applikation die in Unteraufgaben zerlegt werden können, zu strukturieren
\item jede Teilaufgabengruppe befindet sich in einem eigenen Layer
\item ermöglicht bzw. vereinfacht Austauschbarkeit
\end{itemize}
\subsection{Data Access Object (DAO) Pattern}
\subsubsection{Erkläre die Funktion + Skizze}
\begin{figure}[!htp]
@ -47,10 +62,30 @@
\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}
\subsubsection{Beschreibe ein konkretes Anwendungsbeispiel}
\begin{itemize}
\item EntityManager in JEE
\end{itemize}
\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}
\subsubsection{Nenne die Konsequenzen der Anwendung}
\begin{itemize}
\item Zugriff auf persistenten Speicher wird abstrahiert
@ -63,18 +98,194 @@
\subsubsection{Erkläre die Funktion + Skizze}
\begin{itemize}
\item Service Layer delegiert auf Business Logik und zum DAO
\item bei wenig Logik wird zumindest Transaktions, Error und Validierungshandling im Service erledigt
\item Service Layer delegiert auf Business Logik (z.B.: Zeile 82 community.setDocumentlibrary) und zum DAO (z.B.: Zeile 80, 81,82 ...)
\item bei wenig Logik wird zumindest Transaktions (z.B. Zeile 39), Error (z.B. Zeile 42-50) und Validierungshandling (z.B.: Zeile 24-27) 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;
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);
logger.info(String.format("Document %s saved in database", filename));
} 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) {
try {
Activitystream activitystream = communityDAO.findById(communityID).getActivitystream();
Date now = new Date();
Calendar calendar = Calendar.getInstance();
calendar.set(9999, Calendar.DECEMBER, 31);
Date until = calendar.getTime();
Message message = new Message(user, text, now, until, now, activitystream, null, "Document Upload", null, null);
messageDAO.insert(message);
} catch (Exception ex) {
String errorMsg = String.format("Add entry to stream for %s failed.", document.getFilename());
logger.error(errorMsg, ex);
throw new ServiceException(errorMsg);
}
}
private Documentlibrary addDocumentlibrary(Long communityID) {
logger.info("Create missing documentlibrary");
Community community;
Documentlibrary documentlibrary = new Documentlibrary();
documentlibraryDAO.insert(documentlibrary);
community = communityDAO.findById(communityID);
community.setDocumentlibrary(documentlibrary);
communityDAO.update(community);
return documentlibrary;
}
@Override
public List<DocumentDTO> getDocumentsFromCommunity(Long communityID) {
try {
List<Document> documents;
if (communityID <= 0) throw new IllegalArgumentException("community must not be empty");
Community community = communityDAO.findById(communityID);
if (community == null) throw new IllegalStateException("community " + communityID + " not found");
documents = documentDAO.findByCommunity(community);
return documents.stream().map(DocumentMapper::toDTO).collect(Collectors.toList());
} catch (IllegalArgumentException iaex) {
String errorMsg = "Could not load docs from community (illegal argument)";
logger.error(errorMsg, iaex);
throw new ServiceException(errorMsg);
} catch (Exception ex) {
String errorMsg = "Could not load docs for community.";
logger.error(errorMsg + " id " + communityID, ex);
throw new ServiceException(errorMsg);
}
}
@Override
public List<DocumentDTO> getDocumentsFromUser(String userID) {
try {
List<Document> documents;
User user = userDAO.getByUserId(userID);
if (user == null) throw new IllegalArgumentException("user must not be empty");
documents = documentDAO.findByUser(user);
return documents.stream().map(DocumentMapper::toDTO).collect(Collectors.toList());
} catch (IllegalArgumentException iaex) {
String errorMsg = "Could not load documents from user (illegal argument)";
logger.error(errorMsg, iaex);
throw new ServiceException(errorMsg);
} catch (Exception ex) {
String errorMsg = String.format("Could not load documents from user %s.", userID);
logger.error(errorMsg, ex);
throw new ServiceException(errorMsg);
}
}
@Override
public void removeDocument(Long documentID) {
String filename = "";
Document document;
try {
if (documentID <= 0) throw new IllegalArgumentException("documentID must not be zero");
document = documentDAO.findById(documentID);
if (document == null)
throw new IllegalArgumentException("document must not be empty (id " + documentID + ")");
filename = document.getFilename();
Long communityId = document.getDocumentlibrary().getCommunity().getId();
documentDAO.delete(document);
User user = document.getUser();
String msgText = "Removed Document " + filename;
addMessageToStream(communityId, user, msgText, document);
} catch (IllegalArgumentException iaex) {
String errorMsg = "Could not remove document (illegal argument)";
logger.error(errorMsg, iaex);
throw new ServiceException(errorMsg);
} catch (Exception ex) {
String errorMsg = String.format("Could not remove document %s.", filename);
logger.error(errorMsg, ex);
throw new ServiceException(errorMsg);
}
}
@Override
public DocumentDTO getDocumentById(Long documentID) {
try {
Document document = documentDAO.findById(documentID);
return DocumentMapper.toDTO(document);
} catch (Exception ex) {
String errorMsg = "Could not load document.";
logger.error(errorMsg + " id " + documentID, ex);
throw new ServiceException(errorMsg);
}
}
}
\end{minted}
\begin{figure}[!htp]
\centering
\includegraphics[width=0.45\textwidth]{pics/sl_pat1.jpg}
\includegraphics[width=0.45\textwidth]{pics/sl_pat2.jpg}
\end{figure}
\subsubsection{Beschreibe ein konkretes Anwendungsbeispiel}
\begin{itemize}
\item eine Applikation mit unterschiedlichen Clienttypen
\end{itemize}
\subsubsection{Nenne die Konsequenzen der Anwendung}
\begin{itemize}
\item Reduzierung der Abhängigkeiten zwischen Presentation und Domain Layer
@ -83,6 +294,7 @@
\item stellt Client ein grobkörniges Interface zur Verfügung
\item gut für Remote Aufrufe geeignet (weniger Aufrufe)
\end{itemize}
\subsection{Model-View-Controller Pattern}
\subsubsection{Erkläre die Funktion + Skizze}
\begin{figure}[!htp]
@ -91,18 +303,18 @@
\end{figure}
\begin{itemize}
\item MVC unterteilt eine interaktive Applikation in drei Teile:
\begin{itemize}
\item Model: Kenfunktionalität und Daten (z.B.: Datenbankzugriff)
\item View: Visualisierung bzw. User-Interaktion
\item Controller: enthält Logik und behandelt Benutzereingaben
\end{itemize}
\begin{itemize}
\item Model (ServiceLayer): Kenfunktionalität und Daten (z.B.: Datenbankzugriff)
\item View (WebApp >> xhtml Dateien): Visualisierung bzw. User-Interaktion
\item Controller (web): enthält Logik und behandelt Benutzereingaben
\end{itemize}
\item Controller und View befinden sich im Presentation Layer und haben gegenseitig Abhängigkeiten
\item Model darf keine Abhängigkeiten haben (Controller und View hängen vom Model ab)
\end{itemize}
\subsubsection{Beschreibe ein konkretes Anwendungsbeispiel}
\begin{itemize}
\item Look\&Feel fokusierte Anwendung -> so kann View ohne Große Probleme ausgetauscht werden
\end{itemize}
\begin{figure}[h!]
\centering
\includegraphics[width=0.5\textwidth]{pics/webapp-location.jpg}
\end{figure}
\subsubsection{Nenne die Konsequenzen der Anwendung}
\begin{itemize}
\item Visualisierung abhängig vom Model - nicht umgekehrt
@ -113,22 +325,22 @@
\end{itemize}
\subsection{Front Controller}
\subsubsection{Erkläre die Funktion + Skizze}
\begin{figure}[!htp]
\centering
\includegraphics[width=0.5\textwidth]{pics/fc_pat.jpg}
\end{figure}
\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}
\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}
\subsubsection{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)
@ -141,10 +353,9 @@
\end{itemize}
\subsection{View Helper}
\subsubsection{Erkläre die Funktion + Skizze}
\begin{figure}[!htp]
\begin{figure}[h!]
\centering
\includegraphics[width=0.4\textwidth]{pics/view-helper_pat1.jpg}
\includegraphics[width=0.4\textwidth]{pics/view-helper_pat2.jpg}
\includegraphics[width=0.5\textwidth]{pics/view-helper_pat1.jpg}
\end{figure}
\begin{itemize}
\item View delegiert Aufgaben an Helper (Helper adaptieren View zu Model)
@ -160,10 +371,10 @@
\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}
\begin{itemize}
\item Presentation und Data Source Layer
\item Entwickler und Designer
\end{itemize}
\end{itemize}
@ -195,10 +406,10 @@
\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}
\begin{itemize}
\item Vorteil Annotation: Typ-Sicherheit (Tippfehler passieren schnell im XML)
\item Nachteil Annotation: nicht so flexibel wie XML
\end{itemize}
\end{itemize}
\subsection{Remote Facade}
\subsubsection{Erkläre die Funktion + Skizze}
@ -280,13 +491,13 @@ Bei HTML-Änderung muss ich nur Page-Objekt ändern und ansonsten nichts angreif
\subsection{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}
\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}
\begin{itemize}
\item Verwendung für technische Probleme (User kann nichts machen außer neu starten)
\end{itemize}
\end{itemize}
\begin{figure}[!htp]
\centering
@ -299,7 +510,7 @@ Bei HTML-Änderung muss ich nur Page-Objekt ändern und ansonsten nichts angreif
\subsection{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.
Implementierungsspezifischer Exception später mit Runtime ohne Stacktrace (Sicherheit) bis zum User.
\end{itemize}
\subsection{Beschreibe 5 Best Practice Beispiele beim Einsatz von Exceptions}
\begin{itemize}
@ -335,8 +546,20 @@ Bei HTML-Änderung muss ich nur Page-Objekt ändern und ansonsten nichts angreif
\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}
\subsection{Annotationen}
\subsubsection{@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
@ -348,7 +571,7 @@ Bei HTML-Änderung muss ich nur Page-Objekt ändern und ansonsten nichts angreif
@OneToMany Beziehung
@JoinColums welche Spalten zusammen gehören FK
@OneToMany FK auf anderen Seite
@ApplicationScoped lebt die ganze Applikation lang, wird einmal gemacht.
@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
@ -358,13 +581,13 @@ Bei HTML-Änderung muss ich nur Page-Objekt ändern und ansonsten nichts angreif
\subsection{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. Zudätzlich in DaoException wrappen.
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.
Mapper von DTO in Entity und Entity ins DTO.
FrontController web.xml
ViewHelper *ServiceImpl

BIN
pics/tree-project-main.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

BIN
pics/tree-project-test.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

BIN
pics/tree-projectmain.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

BIN
pics/web-2ndpart.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
pics/webapp-location.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

View File

@ -8,20 +8,21 @@
\usepackage[hidelinks]{hyperref}
\usepackage{multicol}
\usepackage{graphicx}
%\usepackage{minted}
\usepackage[outputdir=../../auxil]{minted}
\usepackage{minted}
\setminted{fontsize=\small}
%\usepackage[outputdir=../../auxil]{minted}
% Document
\begin{document}
\author{Phillip Wo \\ Benjamin Moser \\ Daniel Sommer}
\title{Enterprise Software Architecture - FAQ Ausarbeitung}
\maketitle
\pagebreak
\tableofcontents
\pagebreak
\author{Phillip Wo \\ Benjamin Moser \\ Daniel Sommer}
\title{Enterprise Software Architecture - FAQ Ausarbeitung}
\maketitle
\pagebreak
\tableofcontents
\pagebreak
\include{parts/01_layered-arc}
%\include{parts/02_comp-based_arc}
%\include{parts/03_service-orientated_arc}
\include{parts/01_layered-arc}
%\include{parts/02_comp-based_arc}
%\include{parts/03_service-orientated_arc}
\end{document}