抽象函数/避免函数重复

时间:2011-01-06 04:25:35

标签: refactoring functional-programming scheme racket

我需要一些关于抽象findcheck-callback函数的建议。代码工作正常,但似乎有很多不必要的重复。是否有更优雅的方式重写它们?

;; Model
(define-struct contact (name phone))
(define phonebook (list (make-contact 'adam 5551212)
                        (make-contact 'brian 5552323)
                        (make-contact 'chris 5558888)))

;; find: (string->symbol, string->number) item (listof items) -> symbol/number/false
(define (find type item pb)
  (cond
    [(empty? pb) false]
    [(equal? (string->symbol item) (contact-name (first pb))) (contact-phone (first pb))]
    [(equal? (string->number item) (contact-phone (first pb))) (contact-name (first pb))]
    [else (find type item (rest pb))]))

;; Controller
(define (check-callback b)
  (cond
    [(number? (find string->symbol (text-contents a-text-field) phonebook))
     (draw-message a-msg (number->string (find string->symbol (text-contents a-text-field) phonebook)))]
    [(symbol? (find string->number (text-contents a-text-field) phonebook))
     (draw-message a-msg (symbol->string (find string->number (text-contents a-text-field) phonebook)))]
    [else (draw-message a-msg "Not found")]))


;; View
(define a-text-field
  (make-text "Enter a name or phone number"))

(define a-msg
  (make-message ""))

(define a-button
  (make-button "Search" check-callback))

(create-window
 (list (list a-text-field)
       (list a-button)
       (list a-msg)))

1 个答案:

答案 0 :(得分:1)

由于未使用type变量,我从代码中省略了它并进行了一些重构:

;; find
(define (find item pb)
  (let* ((first-pb (first pb))
         (name (contact-name first-pb))
         (phone (contact-phone first-pb)))
    (cond
      [(empty? pb) #f]
      [(equal? (string->symbol item) name) phone]
      [(equal? (string->number item) phone) name]
      [else (find item (rest pb))])))

;; Controller
(define (check-callback pb)
  (let ((res (find (text-contents a-text-field) pb)))
    (draw-message a-msg
                  (cond
                    [(number? res) (number->string res)]
                    [(symbol? res) (symbol->string res)]
                    [else "Not found"]))))

或者您可以立即将姓名和手机转换为字符串:

;; find
(define (find item pb)
  (let* ((first-pb (first pb))
         (name (contact-name first-pb))
         (phone (contact-phone first-pb)))
    (cond
      [(empty? pb) #f]
      [(equal? (string->symbol item) name) (number->string phone)]
      [(equal? (string->number item) phone) (symbol->string name)]
      [else (find item (rest pb))])))

;; Controller
(define (check-callback pb)
  (let ((res (find (text-contents a-text-field) pb)))
    (draw-message a-msg
                  (if (res)
                    res
                    "Not found"))))