531 lines
21 KiB
TeX
531 lines
21 KiB
TeX
|
||
\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.8\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 enthält Entities –> Java Repräsentation vom DB Entity
|
||
\begin{itemize}
|
||
\item im Projekt wurde eine AbstractEntity erstellt, welche die id managed
|
||
\end{itemize}
|
||
\item beinhaltet DAO und DAOImpl >> DocumentDAO, DocumentlibraryDAO
|
||
\begin{itemize}
|
||
\item damit man auf die Entities zugreifen kann.
|
||
\item um die DB zu abstrahieren.
|
||
\item enthält Methoden mit denen auf die DB zugegriffen wird
|
||
\item eine DAOException kontrolliert den Input
|
||
\begin{itemize}
|
||
\item der EntityManager Aufruf in DAOImpl befindet sich innerhalb eines Try Blocks
|
||
\item im catch wird der Cause in die DaoException gewrapped
|
||
\end{itemize}
|
||
% TODO: ??
|
||
\end{itemize}
|
||
\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}[tph!]
|
||
\centering
|
||
\includegraphics[width=0.4\textwidth]{pics/layer-pattern}
|
||
\end{figure}
|
||
\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 - in unserem Projekt im Domain Layer}\label{sec:slp}
|
||
\subsection{Erkläre die Funktion + Skizze}\label{subsubsec:service-layer-pattern}
|
||
\begin{itemize}
|
||
\item Der Service Layer (Ordner "`service"' im Projekt) 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{figure}[!htp]
|
||
\centering
|
||
\includegraphics[width=0.9\textwidth]{pics/sl_pat1.jpg}
|
||
\includegraphics[width=0.6\textwidth]{pics/domain-layer.png}
|
||
\end{figure}
|
||
\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}
|
||
|
||
\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 wird dies durch die Ordner \textit{service} und \textit{data} repräsentiert
|
||
\end{itemize}
|
||
\subsubsection{View}
|
||
\begin{itemize}
|
||
\item Im Projekt im Ordner \textit{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 \textit{web} zu finden.
|
||
\item Sie enthalten die Logik und behandeln Benutzereingaben
|
||
\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}
|
||
\subsection{Servlet}
|
||
\begin{itemize}
|
||
\item Im Projekt wurde der Front Controller in Form eines Servlet realisiert,
|
||
\item die Einbindung erfolgt in der Konfigurationsdatei \textit{src/main/webapp/WEB-INF/web.xml},
|
||
\item Servlet ist eine Java-API, welche auf einem Server betrieben wird,
|
||
\item die Verarbeitung von Requests und Responses wird ermöglicht,
|
||
\item JSF und JSP können darauf aufsetzen, in unserem Projekt wurde JSF verwendet
|
||
\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}
|
||
\subsubsection{Java Server Faces (JSF)}
|
||
\begin{itemize}
|
||
\item JSF basiert auf dem MVC-Pattern
|
||
\item JSF-View-Code ist im Projekt im Ordner \textit{src/main/webapp/*} zu finden
|
||
\item JSF-Logik befindet sich in den Java-Beans (im Projekt \textit{/src/main/java/at/fhj/swd/psoe/web/*})
|
||
\item in unserem Projekt gibt es zu jeder xhtml-View eine eigene Controller-Klasse, welche dem ViewHelper-Pattern entspricht
|
||
\item in unserem Projekt kommt PrimeFaces zum Einsatz (eine konkrete Implementierungsart von JSF => Einbindung in pom.xml)
|
||
%TODO Toni fragen MVC-Aufteilung JSF
|
||
\end{itemize}
|
||
\begin{figure}[h!]
|
||
\centering
|
||
\includegraphics[width=0.5\textwidth]{pics/fc_pat.jpg}
|
||
\end{figure}
|
||
\begin{minted}[linenos,breaklines=true]{xml}
|
||
<!-- Pfad: /src/main/webapp/community/documentManagement.xhtml -->
|
||
|
||
<?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 (\textit{/src/main/java/at/fhj/swd/psoe/web/*})}
|
||
\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 \textit{/src/main/webapp/*}) delegiert Aufgaben an Helper (z.B. DocumentController im Ordner web)
|
||
\item Helper adaptieren View zu Model (Klassen in den Ordnern \textit{src/main/java/at/fhj/swd/psoe/service/*} und \textit{src/main/java/at/fhj/swd/psoe/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 (CDI-Framework -> eingebunden im \textit{./pom.xml})}
|
||
\subsection{Erkläre die Funktion + Skizze}
|
||
%TODO Zarwos is die Dependency-Injection in unserem Projekt guat und wo is se, verdammte Scheiße noch amol, wo konfigurierst denn den Dreck donn überhaupt???
|
||
\begin{figure}[!htp]
|
||
\centering
|
||
\includegraphics[width=0.8\textwidth]{pics/dependency_inj_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:
|
||
\begin{itemize}
|
||
\item 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}
|
||
\end{itemize}
|
||
\subsection{Nenne die Konsequenzen der Anwendung}
|
||
\begin{itemize}
|
||
\item loose gekoppelte Objekte
|
||
\item Referenzen nur noch 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, ... -> um Anzahl der Aufrufe zu minimieren
|
||
\end{itemize}
|
||
\begin{minted}[linenos,breaklines=true]{java}
|
||
package at.fhj.swd.psoe.service.dto;
|
||
|
||
import java.io.Serializable;
|
||
import java.util.Date;
|
||
|
||
public class DocumentDTO implements Serializable {
|
||
private static final long serialVersionUID = 4016557982897997689L;
|
||
|
||
private Long id;
|
||
private Long documentlibraryID;
|
||
private String filename;
|
||
private UserDTO user;
|
||
private byte[] data;
|
||
private Date createdTimestamp;
|
||
|
||
public DocumentDTO() {}
|
||
|
||
public Long getId() {
|
||
return id;
|
||
}
|
||
|
||
public void setId(Long id) {
|
||
this.id = id;
|
||
}
|
||
|
||
public Long getDocumentlibraryID() {
|
||
return documentlibraryID;
|
||
}
|
||
|
||
public void setDocumentlibraryID(Long documentlibraryID) {
|
||
this.documentlibraryID = documentlibraryID;
|
||
}
|
||
|
||
public String getFilename() {
|
||
return filename;
|
||
}
|
||
|
||
public void setFilename(String filename) {
|
||
this.filename = filename;
|
||
}
|
||
|
||
public UserDTO getUser() {
|
||
return user;
|
||
}
|
||
|
||
public void setUser(UserDTO user) {
|
||
this.user = user;
|
||
}
|
||
|
||
public byte[] getData() {
|
||
return data;
|
||
}
|
||
|
||
public void setData(byte[] data) {
|
||
this.data = data;
|
||
}
|
||
|
||
public Date getCreatedTimestamp() {
|
||
return createdTimestamp;
|
||
}
|
||
|
||
public void setCreatedTimestamp(Date createdTimestamp) {
|
||
this.createdTimestamp = createdTimestamp;
|
||
}
|
||
|
||
@Override
|
||
public String toString() {
|
||
return "DocumentDTO{" +
|
||
"id=" + id +
|
||
", documentlibraryID=" + documentlibraryID +
|
||
", filename='" + filename + '\'' +
|
||
'}';
|
||
}
|
||
|
||
@Override
|
||
public boolean equals(Object o) {
|
||
if (this == o) return true;
|
||
if (!(o instanceof DocumentDTO)) return false;
|
||
|
||
DocumentDTO that = (DocumentDTO) o;
|
||
|
||
return id.equals(that.id);
|
||
}
|
||
|
||
@Override
|
||
public int hashCode() {
|
||
return id.hashCode();
|
||
}
|
||
}
|
||
\end{minted}
|
||
\subsection{Konsequenzen der Anwendung}
|
||
\begin{itemize}
|
||
\item kapselt und versteckt
|
||
\item nimmt Komplexität
|
||
\item steigert Effizienz da weniger Aufrufe über Remotegrenze
|
||
\end{itemize} |