Ruby & Ruby on Rails for arkitekter Kim Harding Christensen khc@kimharding.com
Aga Intro & problemstilling Introduktion til Ruby DSL er Introduktion til Ruby on Rails Begreber (MVC & REST) Demo
Intro
Kim er ikke glad!
Software udvikling er for svært og tager al for lang tid
Problemområde [Distribuerede informationssystemer].net 3.0
Infosets + Objects + Tuples = #&$?!
hvilket fører til
When I work in Java, I wouldn't say I feel joy. I don't feel like I'm riding a fast stallion through beautiful wooded hills, the wind in my long, flowing hair. I feel more like I'm struggling to convince a workhorse to pull a plow. Bill Venners
Java is the blunt scissors of programming. It s what we give to children to program Dave Thomas
Problemområde Sprog Platform
Introduktion til Ruby (på 10 slides) I have a lot of trouble writing about Ruby, because I find there's nothing to say. It's why I almost never post to the O'Reilly Ruby blog. Ruby seems so self-explanatory to me. It makes it almost boring; you try to focus on Ruby and you wind up talking about some problem domain instead of the language. I think that's the goal of all programming languages, but so far Ruby's one of the few to succeed at it so well. Steve Yegge
Ruby Pure Object-Oriented Language Dynamisk type system Simpel nedarvning + mixins Block, closures, continuations Read-eval-print Meta-programmering, metaklasser, introspection, eval Simpel & konsistent syntaks Regulære udtryk Cross-platform
class MyClass @instance_var @@class_var def instance_method(arg)... def self.class_method(arg)... def foo() # getter @foo def foo=(value) # setter @foo = value def state_changing_method!()... def query_method?...
class LinkedList class Node def initialize(element) @element = element def element() @element def next() @next def next=(node) @next = node def add(element)...
class LinkedList class Node def initialize(element) @element = element def element() @element class Node attr_reader :element attr_accessor :next def initialize(element) @element = element def next() @next def next=(node) @next = node def add(element)...
class LinkedList class Node... def add(element) node = Node.new(element) if (@first == nil) @first = node if (@last!= nil) @last.next = node @last = node
class LinkedList class Node... def add(element) node = Node.new(element) if (@first == nil) @first = node if (@last!= nil) @last.next = node @last = node class LinkedList class Node... def add(element) node = Node.new(element) @first = node unless @first @last.next = node if @last @last = node
Block & Closures a = 7 [1,2,3].each { element puts(element + a)}
Block & Closures a = 7 [1,2,3].each { element puts(element + a)} def twice() yield yield twice() { puts Hello }
class LinkedList def add(element)... def each() if block_given? node = @first while node do yield node.element node = node.next self > l = LinkedList.new > [1,2,3,4,5].each { e l.add e} > l.each { e puts e} 1 2 3 4 5 >
Nedarvning class Collection def size() count = 0 self.each { e count += 1} count class LinkedList < Collection def add(element)... def each()...
Moduler & Mixins module Enumeration def select() result = Array.new this.each { e result << yield(e)} result def detect()... def reject()... def collect()......
class Collection include Enumeration def size() count = 0 self.each { e count += 1} count class LinkedList < Collection def add(element)... alias :<< :add def each()...
Metode lookup class Object include Kernel class A include M module Kernel module M class B < A b = B.new b.foo
Domain Specific Languages
DSL Ekstern DSL Intern DSL http://martinfowler.com/articles/languageworkbench.html
Rake - Ruby Make Rakefiler er skrevet i standard Ruby - ingen behov for XML filer Tasks med afhængigheder Rule patterns Rake består af en fil: 400-500 linier Ruby kode http://rake.rubyforge.org http://www.martinfowler.com/articles/rake.html
file 'main.o' => ["main.c", "greet.h"] do sh "cc -c -o main.o main.c" file 'greet.o' => ['greet.c'] do sh "cc -c -o greet.o greet.c" file "hello" => ["main.o", "greet.o"] do sh "cc -o hello main.o greet.o" > rake hello
require 'rake/clean' CLEAN.include('*.o') CLOBBER.include('hello') task :default => ["hello"] SRC = FileList['*.c'] OBJ = SRC.ext('o') rule '.o' => '.c' do t sh "cc -c -o #{t.name} #{t.source}" file "hello" => OBJ do sh "cc -o hello #{OBJ}" # File depencies go here... file 'main.o' => ['main.c', 'greet.h'] file 'greet.o' => ['greet.c']
Ruby On Rails
Rails Full stack web framework MVC baseret Opinionated Convention over configuration Open Source
Model - View - Controller 1 Controller 3 2 4 View Model DB
Rails MVC Routing Controller View Model DB
Rails MVC http://kimharding.com/kursus/index.html Routing Controller View Model DB
Rails MVC http://kimharding.com/kursus/index.html Routing KursusController.index() Controller View Model DB
Rails MVC http://kimharding.com/kursus/index.html Routing KursusController.index() Controller @kurser = Kursus.find(:all) View Model DB
Rails MVC http://kimharding.com/kursus/index.html Routing KursusController.index() Controller index.rhtml @kurser = Kursus.find(:all) View Model DB
Rails MVC http://kimharding.com/kursus/index.html Routing KursusController.index() Controller index.rhtml @kurser = Kursus.find(:all) View <h1>kurser</h1> <% @kurser.each do kursus %> <h2><%= @kursus.titel() %></h2> <%= @kursus.beskrivelse() %> <% %> Model DB
ActiveRecord The essence of an Active Record is a Domain Model in which the classes match very closely the record structure of an underlying database. Each Active Record is responsible for saving and loading to the database and also for any domain logic that acts on the data... The data structure of the Active Record should exactly match that of the database: one field in the class for each column in the table... Patterns of Enterprise Application Architecture Martin Fowler
Analyse model Brand title description logo_url 1 * ProductType title description image_url * Product title price * * Category title children parent
DB Design BRANDS id title description logo_url int varchar(80) varchar(512) varchar(256) PRODUCT_TYPES id title description image_url brand_id int varchar(80) varchar(512) varchar(256) int PRODUCTS id title price product_type_id int varchar(80) number(8,2) int CATEGORIES_PRODUCT_TYPES product_types_id category_id int int CATEGORIES id title parent_id int varchar(80) int
BRANDS id title description logo_url int varchar(80) varchar(512) varchar(256) PRODUCT_TYPES id title description image_url brand_id int varchar(80) varchar(512) varchar(256) int PRODUCTS id title price product_type_id int varchar(80) number(8,2) int class CreateBrands < ActiveRecord::Migration def self.up create_table CATEGORIES_PRODUCT_TYPES :brands do t t.column :title, product_types_id :string, int :null => false t.column :description, category_id int :text t.column :logo_url, :string def self.down drop_table :brands CATEGORIES id title parent_id int varchar(80) int
Brand title description logo_url 1 * ProductType title description image_url class Brand < ActiveRecord::Base has_many :product_types class ProductType < ActiveRecord::Base belongs_to :brand * Product title price * * Category title children parent
Brand title description logo_url 1 class ProductType < ActiveRecord::Base belongs_to :brand has_many :products, :depent => true * ProductType title description image_url * Product title price * * Category title children class Product < ActiveRecord::Base belongs_to :product_type parent
Brand title description logo_url 1 class ProductType < ActiveRecord::Base belongs_to :brand has_many :products has_and_belongs_to_many :categories * ProductType title description image_url * Product title price * * Category title children class Category < ActiveRecord::Base has_and_belongs_to_many :product_types parent
Brand title description logo_url 1 * ProductType title description image_url * Product title price * * Category title parent children class Category < ActiveRecord::Base has_and_belongs_to_many :product_types acts_as_tree :order => "title"
REST
Hvad er REST? Representational State Transfer is inted to evoke an image of how a well-designed Web application behaves: a network of web pages (a virtual state-machine), where the user progresses through an application by selecting links (state transitions), resulting in the next page (representing the next state of the application) being transferred to the user and rered for their use. Dr. Roy Fielding Architectural Styles and the Design of Network-based Software Architectures
Principper Applikationstilstand og funktionalitet realiseres vha. ressourcer Enhver ressource kan adresseres vha. en URI Alle ressourcer benytter samme uniforme interface til at flytte tilstand mellem klient og ressource Veldefineret sæt af operationer Veldefineret sæt af content-typer En protokol som er Client/Server, Stateless & Cacheable
REST & HTTP HTTP benyttes ofte som fundament for REST Client/Server, Stateless & Cacheable Ressourcer identificeres af URLs Operationer er GET, PUT, POST, DELETE (TRACE, OPTIONS, HEAD) GET: hent ressource repræsentation PUT: opdater ressource POST: opret ny ressource DELETE: slet ressource
Eksempel Customer Order OrderLine Product
Eksempel Customer Order OrderLine Product /customers GET: list all customers POST: add new customers /customers/{id} GET: get customer details PUT: update customer DELETE: delete customer
Eksempel Customer Order /customers GET: list all customers POST: add new customers OrderLine Product /customers/{id} GET: get customer details PUT: update customer DELETE: delete customer /orders GET: list all orders POST: add new order /customers/{id}/orders GET: get order list /orders/{id} GET: get order details PUT: update order DELETE: cancel order
Rails Demo Blog app Baseret på REST RSS feed AJAX til kommentarer
Rails Demo Posting * Comment
Rails Demo Posting * Comment /postings GET: list all postings {HTML & RSS} POST: add new posting
Rails Demo Posting * Comment /postings GET: list all postings {HTML & RSS} POST: add new posting /postings/{id} GET: get post details PUT: update posting DELETE: remove posting
Rails Demo Posting * Comment /postings GET: list all postings {HTML & RSS} POST: add new posting /postings/{id}/comments GET: list all comments POST: add new comment /postings/{id} GET: get post details PUT: update posting DELETE: remove posting
Rails Demo Posting * Comment /postings GET: list all postings {HTML & RSS} POST: add new posting /postings/{id}/comments GET: list all comments POST: add new comment /postings/{id} GET: get post details PUT: update posting DELETE: remove posting /postings/{id}/comments/{id} GET: get comment details PUT: update comment DELETE: remove comment
From what I have seen so far, Rails is a hyper-productive agile environment that EVERYONE should be taking very seriously. It seems to me that a Rails team could leave a Java or.net team in the dust by a factor of five or so. I know the rebuttal to that will be the dreaded "E" word. My response to that is: "It's OK with me if you want to go slow, just get out of the way while the rest of us get stuff done." Bob Martin
Ruby & RoR
Kim Harding Design Aps Kurser i.net, Java, Ruby, Modellering, Arkitektur Mentoring & Reviews Kontakt: khc@kimharding.com Tlf: 20929761