SORU
12 Mart 2012, PAZARTESİ


Uygulama standart yazılım tasarım desenleri (MVC odaklanmak) R

Şu anda, Tasarım, Design Patterns vs Yazılım Mühendisliği Yazılım hakkında çok şey okuyorum. Doğru teknik terminolojinin bazı yönlerini tanımlamak için kullanmıyorum diye bana yeni ilginç şeyler, bu yüzden lütfen beni mazur görün, bu tamamen farklı bir arka plan, gelen ;-)

Nesne yönelim yaptığım şeyler için doğru seçim gibi görünüyor çünkü Reference Classes (R OOP) çoğu zaman kullandım.

Şimdi, Eğer iyi bir nasihat veya uygulanmasıyla ilgili biraz tecrübesi var mı diye merak ediyordumMVC(Model Görünümü Denetleyicisi; de bilinirMVP: Görünüm Sunan Model) R, tercihen kullanarak Başvuru Sınıflar desen.

Ayrıca bilgi diğer "" observer, blackboard vb. gibi tasarım desenleri standart ile ilgili olarak çok merak ediyorum ama bu soru çok geniş bir tanımlama yapmak istemiyorum. Havalı şey biraz az örnek kod, ama herhangi bir işaretçi görmek olurdu sanırım, "", diyagram veya herhangi bir diğer fikir de büyük takdir! edilecek şeması

Bu benzer şeyler ilgilenen, gerçekten şu kitapları tavsiye edebilirim:

  1. The Pragmatic Programmer
  2. Design Patterns

2012-03-12 GÜNCELLEŞTİRİN

Sonunda MVC benim yorumuma küçük bir örnek ile karşılaştım tamamen doğru olmayabilir (; -)).

Paket Bağımlılıkları

require("digest")

Sınıf Tanımı Gözlemci

setRefClass(
    "Observer",
    fields=list(
        .X="environment"
    ),
    methods=list(
        notify=function(uid, ...) {
            message(paste("Notifying subscribers of model uid: ", uid, sep=""))
            temp <- get(uid, .self$.X)
            if (length(temp$subscribers)) {
                # Call method updateView() for each subscriber reference
                sapply(temp$subscribers, function(x) {
                    x$updateView()        
                })
            }    
            return(TRUE)
        }
    )
)

Sınıf Tanımı Model

setRefClass(
    "Model",
    fields=list(
        .X="data.frame",
        state="character",
        uid="character",
        observer="Observer"
    ),
    methods=list(
        initialize=function(...) {
            # Make sure all inputs are used ('...')
            .self <- callSuper(...)
            # Ensure uid
            .self$uid <- digest(c(.self, Sys.time()))
            # Ensure hash key of initial state
            .self$state <- digest(.self$.X)
            # Register uid in observer
            assign(.self$uid, list(state=.self$state), .self$observer$.X)
            .self
        },
        multiply=function(x, ...) {
            .self$.X <- .X * x 
            # Handle state change
            statechangeDetect()
            return(TRUE)
        },
        publish=function(...) {
            message(paste("Publishing state change for model uid: ", 
                .self$uid, sep=""))
            # Publish current state to observer
            if (!exists(.self$uid, .self$observer$.X)) {
                assign(.self$uid, list(state=.self$state), .self$observer$.X)
            } else {
                temp <- get(.self$uid, envir=.self$observer$.X)
                temp$state <- .self$state
                assign(.self$uid, temp, .self$observer$.X)    
            }
            # Make observer notify all subscribers
            .self$observer$notify(uid=.self$uid)
            return(TRUE)
        },
        statechangeDetect=function(...) {
            out <- TRUE
            # Hash key of current state
            state <- digest(.self$.X)
            if (length(.self$state)) {
                out <- .self$state != state
                if (out) {
                # Update state if it has changed
                    .self$state <- state
                }
            }    
            if (out) {
                message(paste("State change detected for model uid: ", 
                   .self$uid, sep=""))
                # Publish state change to observer
                .self$publish()
            }    
            return(out)
        }
    )
)

Sınıf Tanımı ve Görünümleri Denetleyicisi

setRefClass(
    "Controller",
    fields=list(
        model="Model",
        views="list"
    ),
    methods=list(
        multiply=function(x, ...) {
            # Call respective method of model
            .self$model$multiply(x) 
        },
        subscribe=function(...) {
            uid     <- .self$model$uid
            envir   <- .self$model$observer$.X 
            temp <- get(uid, envir)
            # Add itself to subscribers of underlying model
            temp$subscribers <- c(temp$subscribers, .self)
            assign(uid, temp, envir)    
        },
        updateView=function(...) {
            # Call display method of each registered view
            sapply(.self$views, function(x) {
                x$display(.self$model)    
            })
            return(TRUE)
        }
    )
)
setRefClass(
    "View1",
    methods=list(
        display=function(model, x=1, y=2, ...) {
            plot(x=model$.X[,x], y=model$.X[,y])
        }
    )
)
setRefClass(
    "View2",
    methods=list(
        display=function(model, ...) {
            print(model$.X)
        }
    )
)

Kukla Veri Temsil Eden Bir Sınıf Tanımı

setRefClass(
    "MyData",
    fields=list(
        .X="data.frame"
    ),
    methods=list(
        modelMake=function(...){
            new("Model", .X=.self$.X)
        }
    )
)

Örnekler Oluşturur

x <- new("MyData", .X=data.frame(a=1:3, b=10:12))

Model özellikleri ve gözlemci devlet araştırın

mod <- x$modelMake()
mod$.X

> mod$uid
[1] "fdf47649f4c25d99efe5d061b1655193"
# Field value automatically set when initializing object.
# See 'initialize()' method of class 'Model'.

> mod$state
[1] "6d95a520d4e3416bac93fbae88dfe02f"
# Field value automatically set when initializing object.
# See 'initialize()' method of class 'Model'.

> ls(mod$observer$.X)
[1] "fdf47649f4c25d99efe5d061b1655193"

> get(mod$uid, mod$observer$.X)
$state
[1] "6d95a520d4e3416bac93fbae88dfe02f"

Nesnenin uid otomatik olarak başlatma sırasında gözlemci olarak kaydedildiğini unutmayın. Bu şekilde, denetleyici/görüş bildirimleri için abone olun ve 1:n bir ilişki var.

Görüş ve denetleyicisi başlatılamadı

view1 <- new("View1")
view2 <- new("View2")
cont  <- new("Controller", model=mod, views=list(view1, view2))

Abone olun

Denetleyicisi temel model bildirimleri için abone olur

cont$subscribe()

Abonelik gözlemci olarak günlüğe not edin

get(mod$uid, mod$observer$.X)

Kayıtlı Görüşlerini Görüntüleyin

> cont$updateView()
  a  b
1 1 10
2 2 11
3 3 12
[1] TRUE

Ayrıca açılan arsa bir pencere var.

Model Değiştir

> cont$model$multiply(x=10)
State change detected for model uid: fdf47649f4c25d99efe5d061b1655193
Publishing state change for model uid: fdf47649f4c25d99efe5d061b1655193
Notifying subscribers of model uid: fdf47649f4c25d99efe5d061b1655193
   a   b
1 10 100
2 20 110
3 30 120
[1] TRUE

Hem kayıtlı görünümleri temel modeli sırayla tüm aboneleri haberdar olan gözlemci, (yani, denetleyici) için devlet değiştirmek yayınlanan otomatik olarak güncellenir unutmayın.

Soru Açık

Henüz tam olarak anlamış değilim gibi hissediyorum:

  1. Bu MVC deseni biraz doğru bir uygulama mı? Ben yanlış ne yaptım?
  2. "" Yöntemleri (örneğin, veri toplama, alt vb.) işlenmesi gerekir model "," model veya denetleyici sınıf . ait olduğun için Şimdiye kadar, ben her zaman belirli bir nesne "bu yöntemleri olarak" nesne çok. yaptığı herşeyi tanımlanan
  3. Gereken denetleyicisi olarak bir tür "proxy" kontrol her etkileşimini model ve görünümleri (bir nevi "iki yönlü"), yoksa sadece sorumlu yayılıyor kullanıcı giriş modeli (bir çeşit "tek yol" mu?

CEVAP
27 Temmuz 2012, Cuma


  1. Oldukça iyi görünüyor, ama bir Gözlemci Genellikle Denetleyici bir Gözlemci diğer derslerin (belki bana söyleyebilirsin) ek neden o kadar emin değilim. R Java bunu öğrendiğim zaman bunu anlamak çok kolay (Java iyi parçaları bazı gizler) değildi, çünkü bunu yapmak için gerçekten iyi bir fikirdir

  2. Evet ve Hayır. Bu desen farklı yorumlar var. Nesne yöntem olması gibi, modele ait olduğunu söyleyebilirim. Basit bir örnek, bir GUI içinde çözme adımları gösteren bir sudoku çözücü olacaktır. Bırak paylaşalım içine bazı parçalar olabilir ayrılmış M, V ve C: ham veri (2D dizi belki), sudoku fonksiyonları (calc sonraki adım, ...), GUI, birisi söyler GUI yeni bir adım olduğu belirlenmiştir Bunu şöyle ifade ederdim: M: ham veri sudoku fonksiyonları, C: GUI girişi, V hakkında model / değişiklikler hakkında GUI söyleyen: herhangi bir mantık olmadan GUI Diğerleri kumandaya sudoku görev koymak, aynı zamanda doğru ve daha bazı sorunlar için işe yarayabilir

  3. Olası bir "tek yolu onu aramak ve Görüntülemek model bir Gözlemci gibi" kumanda var Aynı zamanda Denetleyici her şey ve Modeli yapalım ve birbirimizi Görünümü (Model View Sunan bir bak, o bu konuda bir şey bilmiyorum

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Caramthros

    Caramthros

    10 AĞUSTOS 2007
  • Gigawipf

    Gigawipf

    18 ŞUBAT 2010
  • o0oCyrusViruso0o

    o0oCyrusViru

    11 Mart 2008