Created by Angelo Maron

Ähnliche Dokumente
Eine Anwendung mit InstantRails 1.7

Rails Ruby on Rails Ajax on Rails. Clemens H. Cap

Objektorientierte Programmierung für Anfänger am Beispiel PHP

Binäre Bäume. 1. Allgemeines. 2. Funktionsweise. 2.1 Eintragen

Klassenentwurf. Wie schreiben wir Klassen, die leicht zu verstehen, wartbar und wiederverwendbar sind? Objektorientierte Programmierung mit Java

Datenbank-Verschlüsselung mit DbDefence und Webanwendungen.

Professionelle Seminare im Bereich MS-Office

! " # $ " % & Nicki Wruck worldwidewruck

SEMINAR Modifikation für die Nutzung des Community Builders

Design Patterns 2. Model-View-Controller in der Praxis

Mocha. Ein Ruby Mocking und Stubbing Framework. von Thilo Utke. Werd ich drüber reden Erst was zu mit.

Idimager ein Bildverwaltungsprogramm-DAM Software

Step by Step Softwareverteilung unter Novell. von Christian Bartl

teischl.com Software Design & Services e.u. office@teischl.com

Infinigate (Schweiz) AG. Secure Guest Access. - Handout -

Design Pattern - Strukturmuster. CAS SWE - OOAD Marco Hunziker Klaus Imfeld Frédéric Bächler Marcel Lüthi

Xcode/Cocoa/Objective-C Crashkurs Programmieren unter Mac OS X

Glaube an die Existenz von Regeln für Vergleiche und Kenntnis der Regeln

Design anpassen eine kurze Einführung

Web 2. Gang. Python User Group Köln Christopher Arndt

YouTube: Video-Untertitel übersetzen

Verhindert, dass eine Methode überschrieben wird. public final int holekontostand() {...} public final class Girokonto extends Konto {...

Hardware - Software - Net zwerke

RL

MARCANT - File Delivery System

Die Windows 7 Sicherung im Detail

Test-Driven Design: Ein einfaches Beispiel

Gründe für fehlende Vorsorgemaßnahmen gegen Krankheit

Family Safety (Kinderschutz) einrichten unter Windows 7

Technische Analyse der Zukunft

OUTSOURCING ADVISOR. Analyse von SW-Anwendungen und IT-Dienstleistungen auf ihre Global Sourcing Eignung. Bewertung von Dienstleistern und Standorten

UpToNet DMS Posteingang

Meet the Germans. Lerntipp zur Schulung der Fertigkeit des Sprechens. Lerntipp und Redemittel zur Präsentation oder einen Vortrag halten

Der Kalender im ipad

.htaccess HOWTO. zum Schutz von Dateien und Verzeichnissen mittels Passwortabfrage

ZfP-Sonderpreis der DGZfP beim Regionalwettbewerb Jugend forscht BREMERHAVEN. Der Zauberwürfel-Roboter. Paul Giese. Schule: Wilhelm-Raabe-Schule

Wir wünschen Ihnen viel Freude und Erfolg mit Ihrem neuen X-PRO-USB-Interface. Ihr Hacker-Team

Komponententest. Testen von Software Systemen. Übung 02 SS 2009 Version:

SDD System Design Document

Wie verbinde ich ein JBOD-System mit dem QStore QMX? - 1

Tipps & Tricks Neuerungen Nr. 5/ Externe Web-Shops im UniKat für Laborverbrauchsmaterial & Chemikalien

PowerPoint vertonen. by H.Schönbauer 1

Installation und Inbetriebnahme von Microsoft Visual C Express

HANDOUT VON: EIGENES SSL-ZERTIFIKAT FÜR DEN WHS. Copyright 2011 by s.winkler all rights reserved!

CSS-Grundlagen. Etwas über Browser. Kapitel. Die Vorbereitung

Vgl. Kapitel 5 aus Systematisches Requirements Engineering, Christoph Ebert

Step by Step VPN unter Windows Server von Christian Bartl

Zugriff auf Daten der Wago über eine Webseite

Inhaltsverzeichnis. 1. Empfängerübersicht / Empfänger hinzufügen 2. Erstellen eines neuen Newsletters / Mailings 3. Versand eines Newsletters

Künstliches binäres Neuron

Die Captimizer BTZ-Datei 2015

Leichte-Sprache-Bilder

Daten am USB Stick mit TrueCrypt schützen

BMC Control M Tipps & Tricks 2. Martin Dienstl, BMC Software martin_dienstl@bmc.com

WEBAPPLIKATIONEN MIT PHP. Wo gibt es Hilfe? Wie fang ich an?

Dokumentation für das Spiel Pong

Agile Vorgehensmodelle in der Softwareentwicklung: Scrum

COMPUTER MULTIMEDIA SERVICE

SharePoint Demonstration

Django - ein Python Web-Framework

GDPdU Export. Modulbeschreibung. GDPdU Export. Software-Lösungen. Stand: Seite 1

Zählen von Objekten einer bestimmten Klasse

II. Grundlagen der Programmierung. 9. Datenstrukturen. Daten zusammenfassen. In Java (Forts.): In Java:

Inhalt... 1 Einleitung... 1 Systemanforderungen... 1 Software Download... 1 Prüfdokumentation... 4 Probleme... 5 Hintergrund... 5

php Hier soll ein Überblick über das Erstellen von php Programmen gegeben werden. Inhaltsverzeichnis 1.Überblick Parameterübergabe...

Step by Step Webserver unter Windows Server von Christian Bartl

Control-M Workload Change Management 8

8 Design Patterns. Events

A.u.S. Spielgeräte GmbH A-1210 Wien Scheydgasse 48 Tel.+43-(0) Fax. +43-(0)

Handbuch ECDL 2003 Modul 2: Computermanagement und Dateiverwaltung Dateien löschen und wiederherstellen

Magento MultiStore einrichten unter ispcp

Dr. Kraus & Partner Ihr Angebot zu Konfliktmanagement

Daniel Warneke Ein Vortrag im Rahmen des Proseminars Software Pioneers

Installation Hardlockserver-Dongle

Anleitung. So erstellen Sie eine Familienkarte für Ihre Gemeinde. 1. Google-Konto eröffnen

Optimierung einer Lernumgebung für berufstätige Studierende

Vermeiden Sie es sich bei einer deutlich erfahreneren Person "dranzuhängen", Sie sind persönlich verantwortlich für Ihren Lernerfolg.

Jede Zahl muss dabei einzeln umgerechnet werden. Beginnen wir also ganz am Anfang mit der Zahl,192.

Taking RM Agile. Erfahrungen aus dem Übergang von traditioneller Entwicklung zu Scrum

(1) Mit dem Administrator Modul werden die Datenbank, Gruppen, Benutzer, Projekte und sonstige Aufgaben verwaltet.

Anlegen eines DLRG Accounts

Downloadfehler in DEHSt-VPSMail. Workaround zum Umgang mit einem Downloadfehler

ÖKB Steiermark Schulungsunterlagen

Software Engineering. Bibliographisches Institut & F. A. Brockhaus AG, Mannheim; Spektrum Akademischer Verlag GmbH, Heidelberg, 2003

Datenbanksysteme SS 2007

Backup der Progress Datenbank

OECD Programme for International Student Assessment PISA Lösungen der Beispielaufgaben aus dem Mathematiktest. Deutschland

Bilder zum Upload verkleinern

Installation von Druckern auf dem ZOVAS-Notebook. 1. Der Drucker ist direkt mit dem Notebook verbunden

Einführung in die Java- Programmierung

Java Kurs für Anfänger Einheit 5 Methoden

Albert HAYR Linux, IT and Open Source Expert and Solution Architect. Open Source professionell einsetzen

BBCode v2.0. Einleitung...2 Installation... 3 Bugfixliste Inhaltsverzeichnis. Überarbeiteter BBCode + neuem Interface.

lohmeyer White Paper Use Cases II UX+Prozessanalyse

DOKUMENTATION ios APP «FRI APP»

Informatik 12 Datenbanken SQL-Einführung

Subpostfächer und Vertretungen für Unternehmen

Transkript:

Domain Driven Design in Ruby on Rails Created by Angelo Maron

Wer bin ich? Angelo Maron Sofware-Entwickler seit ca. 7 Jahren (Ruby on Rails) bei AKRA seit 2,5 Jahren Xing: https://www.xing.com/profile/angelo_maron Twitter: @MrRaffnix

Aga 1. MVC & Rails 2. Domain Driven Design 3. Domain Driven Design in Rails 4. Zusammenfassung

MVC (Model View Controller) Wikipedia: Der englischsprachige Begriff "model view controller" (MVC) ist ein Muster zur Strukturierung von Software-Entwicklung in die drei Einheiten Datenmodell (engl. model), Präsentation (engl. view) und Programmsteuerung (engl. controller).

Ruby on Rails Ruby on Rails ist ein in der Programmiersprache Ruby geschriebenes und quelloffenes Web Application Framework. wird dieses Jahr 10 Jahre alt. basiert auf dem MVC-Pattern Prinzipien: Don't repeat yourself (DRY) Convention over Configuration

!Convention!

MVC in Ruby on Rails M odel: V iew: ActiveRecord ActionView C ontroller: ActionController

Fat Model, Skinny Con- troller (1) "Im Zusammenspiel von Controller und Model, versuche im Controller nur das Objekt zu instanzieren und einen Methodenaufruf durchzuführen. Der Rest wird im Model definiert."

Fat Model, Skinny Con- troller (2) def index @published_posts = Post.all.where('published_at <=?', Time.now) @unpublished_posts = Post.all.where('published_at IS NULL or published_at >?', Time.now) def index @published_posts = Post.all_published @unpublished_posts = Post.all_unpublished

Problematik Mit zunehmen Anforderungen werden können die folgen Problematiken auftreten: Die Model-Dateien werden immer größer (500+ Zeilen) Die Actions der Controller werden immer größer (30+ Zeilen) Dies führt zur Verschlechterung der Testbarkeit, Wartbarkeit und Verständnis des Codes. Daher habe ich versucht nach den folgen Regeln zu arbeiten. (nach Sandy Matz) --> Domain Driven Design Eine Klasse hat maximal 100 Zeilen. Eine Methode hat maximal 5 Zeilen.

Domain Driven Design Domain-Driven Design (DDD) ist eine Herangehensweise an die Modellierung komplexer objektorientierter Software. Die Modellierung der Software wird dabei maßgeblich von den umzusetzen Fachlichkeiten der Anwungsdomäne beeinflusst.

Warum DDD? 1. Fachliche Begrifflichkeiten und Codestruktur angleichen. 2. kleinere Dateien (bessere Wartbarkeit) 3. höhere Codeunabhängigkeit (bessere Wartbarkeit) 4. Bessere Testbarkeit (durch kleinere Klassen)

Domain-Driven Design in Rails Rails Helpers Concerns Service Objects Presenter Objects Strukturierte Namensräume Decorator Pattern

Rails Helpers Interne Struktur von Rails um Funktionen für views zur Verfügung zu stellen. Funktionen um komplexen Code aus der View zu halten. Sich wiederhole Funktionen wieder zu verwen. Persönlich: (erinnert mich an funktionale Programmierung)

Beispiel Rails Helper (1) <div> <%- if @user.image.present? %> <%= image_tag(@user.image.path) %> <%- else %> <%= image_tag(asset_path('default_profile.png')) %> <%- %> </div>

Beispiel Rails Helper (2) module UserHelper def user_picture_path(user) if user.image.present? user.image.path else asset_path('default_profile.png') <div> <%= image_tag(user_picture_path(@user)) %> </div>

Domain-Driven Design in Rails Rails Helpers Concerns Service Objects Presenter Objects Strukturierte Namensräume Decorator Pattern

Rails Concerns Rails Concerns ist eine Möglichkeit Code in Module auszulagern, die man über ein include in ein beliebiges Model inkludieren kann. Dieses hat folge Anwungsmöglichkeiten: 1. Aufteilen des Codes eines Models in mehrere Dateien 2. Auslagerung von Mechanismen/Pattern zur Wiederverwung Rails bietet hier ein hauseigenes Konzept: ActiveSupport::Concern

Beispiel Rails Concerns (1) class Article < ActiveRecord::Base belongs_to :create_user, class_name: 'User' belongs_to :update_user, class_name: 'User' class Job < ActiveRecord::Base belongs_to :create_user, class_name: 'User' belongs_to :update_user, class_name: 'User'

Beispiel Rails Concerns (2) module Trackable ext ActiveSupport::Concern included do belongs_to :create_user, class_name: 'User' belongs_to :update_user, class_name: 'User' class Article < ActiveRecord::Base include Trackable class Job < ActiveRecord::Base include Trackable

Domain-Driven Design in Rails Rails Helpers Concerns Service Objects Presenter Objects Strukturierte Namensräume Decorator Pattern

Service Objects Verlagerung bestimmter Funktionen eines Anwungsfall in ein eigenes Objekt, dass genau diese Funktionen zur Verfügung stellt. zum Beispiel: SearchService (Suchkomponente) InvoiceService (Rechnungserstellung) RegistrationService (RegistrierungsValidierung)

Beispiel Service Object (1) class Article < ActiveRecord::Base def search(term, options = {}) # execute search def admin_search(term, options = {}) # execute search from admin perspective def Job < ActiveRecord::Base def search(term, options = {}) # execute search def admin_search(term, options = {}) # execute search from admin perspective

Beispiel Service Object (2) class SearchService def self.article_search(term, options = {}) # execute search here def self.job_search(term, options = {}) # execute search here class AdminSearchService def self.article_search(term, options = {}) # execute search here def self.job_search(term, options = {}) # execute search here

Domain-Driven Design in Rails Rails Helpers Concerns Service Objects Presenter Objects Strukturierte Namensräume Decorator Pattern

Presenter Objects Oft haben Get-Operationen komplexe Analyse von Parametern, um die genau angeforderten Objekte anzuzeigen. Hier gibt es eine gute Möglichkeit, diese in eigene Objekte auszulagern.

Beispiel Presenter Object (1) class JobController < ApplicationController::Base def index @jobs = Job.active.preload(:items) if params[:state] @jobs = @jobs.by_state(params[:state]) if params[:order] order_string = "#{params[:order]} #{params[:dir].presence 'asc'}" @jobs = @jobs.order(order_string) @jobs = @jobs.page(params[:page].presence 1).per(params[:per].presence 10)

Beispiel Presenter Object (2) class JobController < ApplicationController::Base def index @jobs = JobPresenter.get_all(params) class JobPresenter def self.get_all(params) self.new(params).get_all def new(params) @params = params def get_all jobs = Job.active.preload(:items) if @params[:state] jobs = jobs.by_state(@params[:state])

Domain-Driven Design in Rails Rails Helpers Concerns Service Objects Presenter Objects Strukturierte Namensräume Decorator Pattern

Strukturierte Namen- sräume Strukturierung aller Objekte (Models, Services, Presenters, Decorators, Controllers usw.) in Domain-basierte Namespaces. Dies hat folge Vorteile: Code-Unabhängigkeit kleinere Dateien bessere Abbildung der Businessdomäne im Code.

Beispiel Namensräume (1) class Job < ActiveRecord::Base def self.all_for_admins #execute query here def self.all_for_moderators # execute query here def self.all_for_visitors #execute query here

Beispiel Namensräume (2) module Admins class Job def self.all #execute query here module Moderators class Job def self.all #execute query here module Visitors class Job def self.all #execute query here

Domain-Driven Design in Rails Rails Helpers Concerns Service Objects Presenter Objects Strukturierte Namensräume Decorator Pattern

Decorators in Rails (1)

Decorators in Rails (2)

Beispiel Decorator (1) class UserController < ApplicationController::Base def show @user = User.find(params[:id]) <div> <p>erstellt am: <%= @user.registered_at.strftime('%y%m%d')</p> <p>name: <%= @user.first_name + @user.last_name %></p> <%- if @user.image.present? %> <%= image_tag(@user.image.path) %> <%- else %> <%= image_tag(asset_path('default_profile.png')) %> <%- %> </div>

Beispiel Decorator (2) class UserDecorator < SimpleDelegator def registered_at @object.registered_at.strftime('%y%m%d') def name "#{@object.first_name} #{@object.last_name}" def image_path # return image.path or default class UserController < ApplicationController::Base def show @user_decorator = UserDecorator.new(User.find(params[:id])) <div> <p>erstellt am: <%= @user_decorator.registered_at</p>

Und was nun?

Die alles entscheidene Frage Welches Pattern benutzt man wann? Ab wann benutzen wir überhaupt diese Pattern?

Neuprogrammierung Abwägung der Komplexität gegen den entstehen Aufwand. Wichtig: Komplexe Business-Logik lässt sich nur durch komplexen Code abbilden.

Refactoring Oft ist schon ein gewisser Fortschritt da, bevor man merkt, dass die Komplexität der Domaine sich direkt im Code wiederspiegelt. Nicht gleich alles komplett refactorn, sondern Step by Step.

Beispiel: