├── .gitignore ├── .idea ├── artifacts │ └── Scala_jar.xml ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── inspectionProfiles │ └── Project_Default.xml ├── jsLibraryMappings.xml ├── kotlinc.xml ├── misc.xml ├── modules.xml ├── runConfigurations │ ├── PatternClojure.xml │ ├── PatternJava.xml │ ├── PatternScala.xml │ ├── TinyWebClojure.xml │ ├── TinyWebJava.xml │ └── TinyWebScala.xml ├── scala_settings.xml └── vcs.xml ├── Clojure ├── Clojure.iml └── src │ └── com │ └── yourtion │ ├── Pattern01 │ ├── person_example.clj │ └── person_example_ex.clj │ ├── Pattern02 │ └── person_example_cc.clj │ ├── Pattern03 │ └── cash_register.clj │ ├── Pattern04 │ └── person.clj │ ├── Pattern05 │ ├── higher_order_functions.clj │ └── lambda_bar_and_grille.clj │ ├── Pattern06 │ └── grade_reporter.clj │ ├── Pattern07 │ └── people_collector_example.clj │ ├── Pattern08 │ └── person_example.clj │ ├── Pattern09 │ └── calculator_example.clj │ ├── Pattern10 │ └── visitor_example.clj │ ├── Pattern11 │ └── services.clj │ ├── Pattern12 │ └── names.clj │ ├── Pattern13 │ └── mutual_recursion_example.clj │ ├── Pattern14 │ └── discount_example.clj │ ├── Pattern15 │ └── chain_example.clj │ ├── Pattern16 │ ├── composition_examples.clj │ ├── discount_builder.clj │ ├── function_builder_example.clj │ ├── partial_examples.clj │ └── selector_example.clj │ ├── Pattern17 │ └── memoization_example.clj │ ├── Pattern18 │ └── lazy_sequence_example.clj │ ├── Pattern19 │ └── focused_mutation_example.clj │ ├── Pattern20 │ └── flow_control_example.clj │ ├── Pattern21 │ └── dsl_example.clj │ ├── PatternDemo │ └── example.clj │ └── TinyWeb │ ├── ControllerException.java │ ├── RenderingException.java │ ├── core.clj │ └── example.clj ├── Java ├── .gitignore ├── Java.iml └── src │ └── com │ └── yourtion │ ├── Pattern01 │ ├── Person.java │ ├── PersonExample.java │ ├── PersonExampleEx.java │ └── PersonExpanded.java │ ├── Pattern02 │ ├── ComposedComparator.java │ └── PersonExampleCC.java │ ├── Pattern03 │ ├── CashRegister.java │ ├── Command.java │ ├── Purchase.java │ ├── PurchaseInvoker.java │ └── RegisterClient.java │ ├── Pattern04 │ ├── ImmutablePerson.java │ └── PersonHarness.java │ ├── Pattern05 │ ├── HigherOrderFunctions.java │ └── TheLambdaBarAndGrille.java │ ├── Pattern06 │ ├── FullGradeReporter.java │ ├── GradeReporterTemplate.java │ └── PlusMinusGradeReporter.java │ ├── Pattern07 │ ├── FirstNameValidator.java │ ├── FullNameValidator.java │ ├── Person.java │ ├── PersonCollector.java │ ├── PersonCollectorExample.java │ └── PersonValidator.java │ ├── Pattern08 │ ├── NullPerson.java │ ├── Person.java │ ├── PersonExample.java │ └── RealPerson.java │ ├── Pattern09 │ ├── Calculator.java │ ├── CalculatorExample.java │ ├── CalculatorImpl.java │ └── LoggingCalculator.java │ ├── Pattern10 │ └── Empty │ ├── Pattern11 │ ├── MovieService.java │ └── ex1 │ │ ├── DecoratedMovie.java │ │ ├── FavoriteVideosService.java │ │ ├── FavoritesService.java │ │ ├── Movie.java │ │ ├── MovieDao.java │ │ ├── MovieService.java │ │ └── VideoService.java │ ├── Pattern12 │ └── SumExample.java │ ├── Pattern13 │ └── Empty │ ├── Pattern14 │ └── Empty │ ├── Pattern15 │ ├── ChainExample.java │ ├── ImmutablePerson.java │ └── Person.java │ ├── Pattern16 │ └── Empty │ ├── Pattern17 │ └── Empty │ ├── Pattern18 │ └── Empty │ ├── Pattern19 │ └── Empty │ ├── Pattern20 │ └── Empty │ ├── Pattern21 │ └── Empty │ ├── PatternDemo │ └── Example.java │ └── TinyWeb │ ├── Controller.java │ ├── ControllerException.java │ ├── Example │ ├── ExampleHarness.java │ ├── GreetingController.java │ ├── GreetingRenderingStrategy.java │ └── LoggingFilter.java │ ├── Filter.java │ ├── HttpRequest.java │ ├── HttpResponse.java │ ├── RenderingException.java │ ├── RenderingStrategy.java │ ├── StrategyView.java │ ├── TemplateController.java │ ├── TinyWeb.java │ └── View.java ├── LICENSE ├── README.md ├── Scala ├── Scala.iml └── src │ ├── META-INF │ └── MANIFEST.MF │ └── com │ └── yourtion │ ├── Pattern01 │ ├── PersonExample.scala │ └── PersonExampleEx.scala │ ├── Pattern02 │ └── PersonExampleCC.scala │ ├── Pattern03 │ ├── Register.scala │ └── RegisterClient.scala │ ├── Pattern04 │ └── Person.scala │ ├── Pattern05 │ ├── HigherOrderFunctions.scala │ └── TheLambdaBarAndGrille.scala │ ├── Pattern06 │ └── GradeReporter.scala │ ├── Pattern07 │ └── PersonCollectorExample.scala │ ├── Pattern08 │ └── PersonExamples.scala │ ├── Pattern09 │ └── CalculatorExample.scala │ ├── Pattern10 │ └── VisitorExample.scala │ ├── Pattern11 │ └── Services.scala │ ├── Pattern12 │ └── Names.scala │ ├── Pattern13 │ └── MutualRecursionExample.scala │ ├── Pattern14 │ └── DiscountExample.scala │ ├── Pattern15 │ └── ChainExample.scala │ ├── Pattern16 │ ├── CompositionExamples.scala │ ├── DiscountBuilder.scala │ ├── FunctionBuilderExample.scala │ ├── PartialExamples.scala │ └── SelectorExample.scala │ ├── Pattern17 │ └── MemoizationExample.scala │ ├── Pattern18 │ └── LazySequenceExample.scala │ ├── Pattern19 │ └── FocusedMutationExample.scala │ ├── Pattern20 │ └── FlowControlExample.scala │ ├── Pattern21 │ └── DSLExample.scala │ ├── PatternDemo │ └── Example.scala │ └── TinyWeb │ ├── Controller.scala │ ├── ControllerException.java │ ├── Example.scala │ ├── Filter.java │ ├── HttpData.scala │ ├── RenderingException.java │ ├── TinyWeb.scala │ └── View.scala └── ScreenShot.png /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Java template 3 | *.class 4 | 5 | # Mobile Tools for Java (J2ME) 6 | .mtj.tmp/ 7 | 8 | # Package Files # 9 | *.jar 10 | *.war 11 | *.ear 12 | 13 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 14 | hs_err_pid* 15 | 16 | /local.properties 17 | /.idea/workspace.xml 18 | /.idea/libraries 19 | .DS_Store 20 | /build 21 | /captures 22 | 23 | out 24 | -------------------------------------------------------------------------------- /.idea/artifacts/Scala_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | $PROJECT_DIR$/out/artifacts/Scala_jar 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/jsLibraryMappings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/kotlinc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/runConfigurations/PatternClojure.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.idea/runConfigurations/PatternJava.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | -------------------------------------------------------------------------------- /.idea/runConfigurations/PatternScala.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | -------------------------------------------------------------------------------- /.idea/runConfigurations/TinyWebClojure.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.idea/runConfigurations/TinyWebJava.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | -------------------------------------------------------------------------------- /.idea/runConfigurations/TinyWebScala.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | -------------------------------------------------------------------------------- /.idea/scala_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Clojure/Clojure.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Clojure/src/com/yourtion/Pattern01/person_example.clj: -------------------------------------------------------------------------------- 1 | (ns com.yourtion.Pattern01.person-example) 2 | 3 | (def p1 {:first-name "Michael" :last-name "Bevilacqua"}) 4 | (def p2 {:first-name "Pedro" :last-name "Vasquez"}) 5 | (def p3 {:first-name "Robert" :last-name "Aarons"}) 6 | 7 | (def people [p1 p2 p3]) 8 | 9 | 10 | (def sorted_people (sort (fn [p1 p2] (compare (p1 :last-name) (p2 :last-name))) people)) 11 | 12 | ;(sort (fn [p1 p2] (compare (p1 :first-name) (p2 :first-name))) people) 13 | 14 | (defn run [] (doseq [col sorted_people :when (not= col nil)] 15 | (println (col :first-name) (col :last-name)))) 16 | -------------------------------------------------------------------------------- /Clojure/src/com/yourtion/Pattern01/person_example_ex.clj: -------------------------------------------------------------------------------- 1 | (ns com.yourtion.Pattern01.person-example-ex) 2 | 3 | (def p1 {:first-name "Aaron" :middle-name "Jeffrey" :last-name "Smith"}) 4 | (def p2 {:first-name "Aaron" :middle-name "Bailey" :last-name "Zanthar"}) 5 | (def p3 {:first-name "Brian" :middle-name "Adams" :last-name "Smith"}) 6 | (def people [p1 p2 p3]) 7 | (defn complicated-sort [p1 p2] 8 | (let [first-name-compare (compare (p1 :first-name) (p2 :first-name)) 9 | middle-name-compare (compare (p1 :middle-name) (p2 :middle-name)) 10 | last-name-compare (compare (p1 :last-name) (p2 :last-name))] 11 | (cond 12 | (not (= 0 first-name-compare)) first-name-compare 13 | (not (= 0 last-name-compare)) last-name-compare 14 | :else middle-name-compare))) 15 | 16 | (def sorted_people (sort complicated-sort people)) 17 | 18 | (defn run [] (doseq [col sorted_people :when (not= col nil)] 19 | (println (col :first-name) (col :middle-name) (col :last-name)))) 20 | -------------------------------------------------------------------------------- /Clojure/src/com/yourtion/Pattern02/person_example_cc.clj: -------------------------------------------------------------------------------- 1 | (ns com.yourtion.Pattern02.person-example-cc) 2 | 3 | (defn make-composed-comparison [& comparisons] 4 | (fn [p1 p2] 5 | (let [results (for [comparison comparisons] (comparison p1 p2)) 6 | first-non-zero-result 7 | (some (fn [result] (if (not (= 0 result)) result nil)) results)] 8 | (if (nil? first-non-zero-result) 9 | 0 10 | first-non-zero-result)))) 11 | 12 | (defn first-name-comparison [p1, p2] 13 | (compare (:first-name p1) (:first-name p2))) 14 | 15 | (defn last-name-comparison [p1 p2] 16 | (compare (:last-name p1) (:last-name p2))) 17 | 18 | (def first-and-last-name-comparison 19 | (make-composed-comparison 20 | first-name-comparison last-name-comparison)) 21 | 22 | (def p1 {:first-name "John" :middle-name "" :last-name "Adams"}) 23 | (def p2 {:first-name "John" :middle-name "Quincy" :last-name "Adams"}) 24 | 25 | (defn run [] (println (first-and-last-name-comparison p1 p2) )) 26 | -------------------------------------------------------------------------------- /Clojure/src/com/yourtion/Pattern03/cash_register.clj: -------------------------------------------------------------------------------- 1 | (ns com.yourtion.Pattern03.cash-register) 2 | 3 | (defn make-cash-register [] 4 | (let [register (atom 0)] 5 | (set-validator! register (fn [new-total] (>= new-total 0))) 6 | register)) 7 | 8 | (defn add-cash [register to-add] 9 | (swap! register + to-add)) 10 | 11 | (defn reset [register] 12 | (swap! register (fn [oldval] 0))) 13 | 14 | (defn make-purchase [register amount] 15 | (fn [] 16 | (println (str "-> Purchase in amount: " amount)) 17 | (add-cash register amount))) 18 | 19 | (def purchases (atom [])) 20 | (defn execute-purchase [purchase] 21 | (swap! purchases conj purchase) 22 | (purchase)) 23 | 24 | (def register (make-cash-register)) 25 | (def purchase-1 (make-purchase register 100)) 26 | (def purchase-2 (make-purchase register 50)) 27 | 28 | (defn run [] 29 | (execute-purchase purchase-1) 30 | (execute-purchase purchase-2) 31 | (println "After purchases: " @register) 32 | 33 | (println "Register reset to 0") 34 | (reset register) 35 | 36 | (doseq [purchase @purchases] (purchase)) 37 | (println "After replay: " @register)) 38 | -------------------------------------------------------------------------------- /Clojure/src/com/yourtion/Pattern04/person.clj: -------------------------------------------------------------------------------- 1 | (ns com.yourtion.Pattern04.person) 2 | 3 | (def p 4 | {:first-name "John" 5 | :middle-name "Quincy" 6 | :last-name "Adams"}) 7 | 8 | (defrecord Cat [color name]) 9 | 10 | (defrecord Dog [color name]) 11 | 12 | (defprotocol NoiseMaker 13 | (make-noise [this])) 14 | 15 | (defrecord NoisyCat [color name] 16 | NoiseMaker 17 | (make-noise [this] (str (:name this) " meows!"))) 18 | 19 | (defrecord NoisyDog [color name] 20 | NoiseMaker 21 | (make-noise [this] (str (:name this) " barks!"))) 22 | 23 | (def cat1 (Cat. "Calico" "Fuzzy McBootings")) 24 | (def dog1 (Dog. "Brown" "Brown Dog")) 25 | 26 | (def noisy-cat (NoisyCat. "Calico" "Fuzzy McBootings")) 27 | (def noisy-dog (NoisyDog. "Brown" "Brown Dog")) 28 | 29 | (defn run [] 30 | (println "# use map") 31 | (println (p :first-name) (p :middle-name) (p :last-name)) 32 | (println "Upper: " (into {} (for [[k, v] p] [k (.toUpperCase v)]))) 33 | (println) 34 | 35 | (println "# use record") 36 | (println "cat: " (:name cat1)) 37 | (println "dog: " (:name dog1)) 38 | 39 | (println "noisy-cat: " (:name noisy-cat)) 40 | (println "noisy-dog: " (:name noisy-dog)) 41 | (println (make-noise noisy-cat)) 42 | (println (make-noise noisy-dog)) 43 | ) 44 | -------------------------------------------------------------------------------- /Clojure/src/com/yourtion/Pattern05/higher_order_functions.clj: -------------------------------------------------------------------------------- 1 | (ns com.yourtion.Pattern05.higher-order-functions) 2 | 3 | (defn sum-sequence [s] 4 | {:pre [(not (empty? s))]} 5 | (reduce + s)) 6 | 7 | (defn prepend-hello [names] 8 | (map (fn [name] (str "Hello, " name)) names)) 9 | 10 | (def vowel? #{\a \e \i \o \u}) 11 | (defn vowels-in-word [word] 12 | (set (filter vowel? word))) 13 | 14 | (def name-list ["Yourtion", "Sophia"]) 15 | 16 | (defn run [] 17 | (println "vowelsInWord: " (vowels-in-word "Yourtion")) 18 | (println) 19 | (println "person: " name-list) 20 | (println "prependHello: " (prepend-hello name-list)) 21 | (println) 22 | (println "sumSequence: " (sum-sequence [1 2 3 4 5]))) 23 | -------------------------------------------------------------------------------- /Clojure/src/com/yourtion/Pattern05/lambda_bar_and_grille.clj: -------------------------------------------------------------------------------- 1 | (ns com.yourtion.Pattern05.lambda-bar-and-grille) 2 | 3 | (def close-zip? #{19123 19103}) 4 | 5 | (defn generate-greetings [people] 6 | (for [{:keys [name address]} people :when (close-zip? (address :zip-code))] 7 | (str "Hello, " name ", and welcome to the Lambda Bar And Grille!"))) 8 | 9 | (defn print-greetings [people] 10 | (doseq [{:keys [name address]} people :when (close-zip? (address :zip-code))] 11 | (println (str "Hello, " name ", and welcome to the Lambda Bar And Grille!")))) 12 | 13 | (def p1 {:name "Yourtion1", :address {:zip-code 19123}}) 14 | (def p2 {:name "Yourtion2", :address {:zip-code 19103}}) 15 | (def p3 {:name "Yourtion3", :address {:zip-code 19129}}) 16 | (def p4 {:name "Yourtion4", :address {:zip-code 19103}}) 17 | (def p5 {:name "Yourtion5", :address {:zip-code 19111}}) 18 | (def people [p1 p2 p3 p4 p5]) 19 | 20 | (defn run [] 21 | (println "All person: " people) 22 | (println generate-greetings people) 23 | (println "-------------") 24 | (print-greetings people)) 25 | -------------------------------------------------------------------------------- /Clojure/src/com/yourtion/Pattern06/grade_reporter.clj: -------------------------------------------------------------------------------- 1 | (ns com.yourtion.Pattern06.grade-reporter) 2 | 3 | (defn make-grade-reporter [num-to-letter print-grade-report] 4 | (fn [grades] 5 | (print-grade-report (map num-to-letter grades)))) 6 | 7 | (defn full-grade-converter [grade] 8 | (cond 9 | (and (<= grade 5.0) (> grade 4.0)) "A" 10 | (and (<= grade 4.0) (> grade 3.0)) "B" 11 | (and (<= grade 3.0) (> grade 2.0)) "C" 12 | (and (<= grade 2.0) (> grade 0)) "D" 13 | (= grade 0) "F" 14 | :else "N/A")) 15 | 16 | (defn print-histogram [grades] 17 | (let [grouped (group-by identity grades) 18 | counts (sort (map 19 | (fn [[grade grades]] [grade (count grades)]) 20 | grouped))] 21 | (doseq [[grade num] counts] 22 | (println (str grade ":" (apply str (repeat num "*"))))))) 23 | 24 | (defn plus-minus-grade-converter [grade] 25 | (cond 26 | (and (<= grade 5.0) (> grade 4.7)) "A" 27 | (and (<= grade 4.7) (> grade 4.3)) "A-" 28 | (and (<= grade 4.3) (> grade 4.0)) "B+" 29 | (and (<= grade 4.0) (> grade 3.7)) "B" 30 | (and (<= grade 3.7) (> grade 3.3)) "B-" 31 | (and (<= grade 3.3) (> grade 3.0)) "C+" 32 | (and (<= grade 3.0) (> grade 2.7)) "C" 33 | (and (<= grade 2.7) (> grade 2.3)) "C" 34 | (and (<= grade 2.3) (> grade 0)) "D" 35 | (= grade 0) "F" 36 | :else "N/A")) 37 | 38 | (defn print-all-grades [grades] 39 | (doseq [grade grades] 40 | (println "Grade is:" grade))) 41 | 42 | (def sample-grades [5.0 4.0 4.4 2.2 3.3 3.5]) 43 | 44 | (def plus-minus-grade-reporter 45 | (make-grade-reporter plus-minus-grade-converter print-all-grades)) 46 | 47 | (def full-grade-reporter (make-grade-reporter full-grade-converter print-histogram)) 48 | 49 | (defn run [] 50 | (println "FullGradeReporter : ") 51 | (plus-minus-grade-reporter sample-grades) 52 | (println) 53 | (println "PlusMinusGradeReporter :") 54 | (full-grade-reporter sample-grades)) 55 | -------------------------------------------------------------------------------- /Clojure/src/com/yourtion/Pattern07/people_collector_example.clj: -------------------------------------------------------------------------------- 1 | (ns com.yourtion.Pattern07.people-collector-example) 2 | 3 | (defn first-name-valid? [person] 4 | (not (nil? (:first-name person)))) 5 | 6 | (defn full-name-valid? [person] 7 | (and 8 | (not (nil? (:first-name person))) 9 | (not (nil? (:middle-name person))) 10 | (not (nil? (:last-name person))))) 11 | 12 | (defn person-collector [valid?] 13 | (let [valid-people (atom [])] 14 | (fn [person] 15 | (if (valid? person) 16 | (swap! valid-people conj person)) 17 | @valid-people))) 18 | 19 | 20 | (def p1 {:first-name "Yourtion" :middle-name nil :last-name "Guo"}) 21 | (def p2 {:first-name "John" :middle-name "Quincy" :last-name "Adams"}) 22 | (def p3 {:first-name nil :middle-name "John" :last-name "Adams"}) 23 | (def p4 {:first-name nil :middle-name nil :last-name nil}) 24 | 25 | (def c1 (person-collector first-name-valid?)) 26 | (def c2 (person-collector full-name-valid?)) 27 | (c1 p1) 28 | (c1 p2) 29 | (c1 p3) 30 | (def res1 (c1 p4)) 31 | (c2 p1) 32 | (c2 p2) 33 | (c2 p3) 34 | (def res2 (c2 p4)) 35 | 36 | (defn run [] 37 | (println "FirstNameValidator Collector list ") 38 | (println res1) 39 | (println "") 40 | (println "FullNameValidator Collector list ") 41 | (println res2)) 42 | -------------------------------------------------------------------------------- /Clojure/src/com/yourtion/Pattern08/person_example.clj: -------------------------------------------------------------------------------- 1 | (ns com.yourtion.Pattern08.person-example 2 | (:require [clojure.string :as string])) 3 | 4 | (def null-person {:first-name "John" :last-name "Doe"}) 5 | (defn fetch-person [people id] 6 | (get id people null-person)) 7 | 8 | (defn person-greeting [person] 9 | (if person 10 | (->> (:first-name person) 11 | string/capitalize 12 | (str "Hello, ")) 13 | "Hello, John")) 14 | 15 | (defn build-person [first-name last-name] 16 | (if (and first-name last-name) 17 | {:first-name first-name :last-name last-name} 18 | {:first-name "John" :last-name "Doe"})) 19 | 20 | (defn run [] 21 | (println "BuildPerson : ") 22 | (println "Not null: " (build-person "Yourtion" "Guo")) 23 | (println "Null first name: " (build-person nil "Guo")) 24 | (println "Null last name: " (build-person "Yourtion" nil)) 25 | (println "") 26 | (println "FetchPerson : ") 27 | (def people {1 {:first-name "Yourtion" :last-name "Guo"}}) 28 | (println "Not null: " (fetch-person 1 people)) 29 | (println "Null: " (fetch-person 2 people))) 30 | -------------------------------------------------------------------------------- /Clojure/src/com/yourtion/Pattern09/calculator_example.clj: -------------------------------------------------------------------------------- 1 | (ns com.yourtion.Pattern09.calculator-example) 2 | 3 | (defn add [a b] (+ a b)) 4 | (defn subtract [a b] (- a b)) 5 | (defn multiply [a b] (* a b)) 6 | (defn divide [a b] (/ a b)) 7 | 8 | (defn make-logger [calc-fn] 9 | (fn [a b] 10 | (let [result (calc-fn a b)] 11 | (println (str "Result is: " result)) 12 | result))) 13 | 14 | (def logging-add (make-logger add)) 15 | (def logging-subtract (make-logger subtract)) 16 | (def logging-multiply (make-logger multiply)) 17 | (def logging-divide (make-logger divide)) 18 | 19 | (defn run [] 20 | (println "Without Logging : ") 21 | (println (add 1 2)) 22 | (println (subtract 4 3)) 23 | (println (divide 6 2)) 24 | (println (multiply 2 3)) 25 | 26 | (println "") 27 | (println "Logging : ") 28 | 29 | (println (logging-add 1 2)) 30 | (println (logging-subtract 4 3)) 31 | (println (logging-divide 6 2)) 32 | (println (logging-multiply 2 3))) 33 | -------------------------------------------------------------------------------- /Clojure/src/com/yourtion/Pattern10/visitor_example.clj: -------------------------------------------------------------------------------- 1 | (ns com.yourtion.Pattern10.visitor-example) 2 | 3 | (defprotocol NameExtractor 4 | (extract-name [this] "Extracts a name from a person.")) 5 | 6 | (defrecord SimplePerson [first-name last-name house-num street]) 7 | 8 | (extend-type SimplePerson 9 | NameExtractor 10 | (extract-name [this] 11 | (str (:first-name this) " " (:last-name this)))) 12 | 13 | (defrecord ComplexPerson [name address] 14 | NameExtractor 15 | (extract-name [this] 16 | (str (-> this :name :first) " " (-> this :name :last)))) 17 | 18 | (defprotocol 19 | AddressExtractor 20 | (extract-address [this] "Extracts and address from a person.")) 21 | 22 | (extend-type SimplePerson 23 | AddressExtractor 24 | (extract-address [this] 25 | (str (:house-num this) " " (:street this)))) 26 | 27 | (extend-type ComplexPerson 28 | AddressExtractor 29 | (extract-address [this] 30 | (str (-> this :address :house-num) 31 | " " 32 | (-> this :address :street)))) 33 | 34 | (defmulti test-multimethod (fn [keyword] keyword)) 35 | 36 | (defmethod test-multimethod :foo [a-map] 37 | "foo-method was called") 38 | 39 | (defmethod test-multimethod :bar [a-map] 40 | "bar-method was called") 41 | 42 | (defmulti perimeter (fn [shape] (:shape-name shape))) 43 | (defmethod perimeter :circle [circle] 44 | (* 2 Math/PI (:radius circle))) 45 | (defmethod perimeter :rectangle [rectangle] 46 | (+ (* 2 (:width rectangle)) (* 2 (:height rectangle)))) 47 | 48 | (def some-shapes [{:shape-name :circle :radius 4} 49 | {:shape-name :rectangle :width 2 :height 2}]) 50 | 51 | (defmulti area (fn [shape] (:shape-name shape))) 52 | (defmethod area :circle [circle] 53 | (* Math/PI (:radius circle) (:radius circle))) 54 | (defmethod area :rectangle [rectangle] 55 | (* (:width rectangle) (:height rectangle))) 56 | 57 | (defmethod perimeter :square [square] 58 | (* 4 (:side square))) 59 | (defmethod area :square [square] 60 | (* (:side square) (:side square))) 61 | 62 | (def more-shapes (conj some-shapes 63 | {:shape-name :square :side 4})) 64 | 65 | (defn run [] 66 | (println "SimplePerson : ") 67 | (def simple-person (->SimplePerson "Yourtion" "Guo" 123 "Fake. St.")) 68 | (println (:first-name simple-person)) 69 | (println (extract-name simple-person)) 70 | (println (extract-address simple-person)) 71 | (println "") 72 | 73 | (println "ComplexPerson : ") 74 | (def complex-person (->ComplexPerson {:first "yourtion" :last "guo"} {:house-num 456 :street "Fake2. St."})) 75 | (println (extract-name complex-person)) 76 | (println (extract-address complex-person)) 77 | (println "") 78 | 79 | (println "TestMultimethod : ") 80 | (println (test-multimethod :foo)) 81 | (println (test-multimethod :bar)) 82 | (println "") 83 | 84 | (println "SecondShapeExample :") 85 | (println (for [shape some-shapes] (perimeter shape))) 86 | (println (for [shape some-shapes] (area shape))) 87 | (println "") 88 | 89 | (println "ThirdShapeExample :") 90 | (println (for [shape more-shapes] (perimeter shape))) 91 | (println (for [shape more-shapes] (area shape))) 92 | 93 | ) 94 | -------------------------------------------------------------------------------- /Clojure/src/com/yourtion/Pattern11/services.clj: -------------------------------------------------------------------------------- 1 | (ns com.yourtion.Pattern11.services) 2 | 3 | (defn get-movie [movie-id] 4 | {:id "42" :title "A Movie"}) 5 | 6 | (defn get-favorite-videos [user-id] 7 | [{:id "1"}]) 8 | 9 | (defn get-favorite-decorated-videos [user-id get-movie get-favorite-videos] 10 | (for [video (get-favorite-videos user-id)] 11 | {:movie (get-movie (:id video)) 12 | :video video})) 13 | 14 | (defn get-test-movie [movie-id] 15 | {:id "43" :title "A Test Movie"}) 16 | 17 | (defn get-test-favorite-videos [user-id] 18 | [{:id "2"}]) 19 | 20 | (defn get-favorite-decorated-videos-2 [user-id] 21 | (for [video (get-favorite-videos user-id)] 22 | {:movie (get-movie (:id video)) 23 | :video video})) 24 | 25 | (with-redefs 26 | [get-favorite-videos get-test-favorite-videos 27 | get-movie get-test-movie] 28 | (doall (get-favorite-decorated-videos-2 "2"))) 29 | 30 | (defn dep [] "dep") 31 | 32 | (defn test-dep [] "test-dep") 33 | 34 | (defn outer-1 [] 35 | (conj (for [foo (range 0 1)] (dep)) (dep))) 36 | 37 | (defn outer-2 [] 38 | (for [foo (range 0 1)] (dep))) 39 | 40 | (defn run [] 41 | (println "Moke : ") 42 | (println (get-favorite-decorated-videos "2" get-test-movie get-favorite-videos)) 43 | (println (get-favorite-decorated-videos-2 "1")) 44 | (println "")) 45 | -------------------------------------------------------------------------------- /Clojure/src/com/yourtion/Pattern12/names.clj: -------------------------------------------------------------------------------- 1 | (ns com.yourtion.Pattern12.names) 2 | 3 | (defn make-people [first-names last-names] 4 | (loop [first-names first-names last-names last-names people []] 5 | (if (seq first-names) 6 | (recur 7 | (rest first-names) 8 | (rest last-names) 9 | (conj 10 | people 11 | {:first (first first-names) :last (first last-names)})) 12 | people))) 13 | 14 | (defn shorter-make-people [first-names last-names] 15 | (for [[first last] (partition 2 (interleave first-names last-names))] 16 | {:first first :last last})) 17 | 18 | (defn run [] 19 | (println "Moke : ") 20 | (println (make-people ["Yourtion1", "Yourtion2"] ["Guo1", "Guo2"])) 21 | (println (shorter-make-people ["Yourtion1", "Yourtion2"] ["Guo1", "Guo2"])) 22 | (println "")) 23 | -------------------------------------------------------------------------------- /Clojure/src/com/yourtion/Pattern13/mutual_recursion_example.clj: -------------------------------------------------------------------------------- 1 | (ns com.yourtion.Pattern13.mutual-recursion-example) 2 | 3 | (declare plasma vapor liquid solid) 4 | 5 | (defn plasma [[transition & rest-transitions]] 6 | #(case transition 7 | nil true 8 | :deionization (vapor rest-transitions) 9 | :false)) 10 | 11 | (defn vapor [[transition & rest-transitions]] 12 | #(case transition 13 | nil true 14 | :condensation (liquid rest-transitions) 15 | :deposition (solid rest-transitions) 16 | :ionization (plasma rest-transitions) 17 | false)) 18 | 19 | (defn liquid [[transition & rest-transitions]] 20 | #(case transition 21 | nil true 22 | :vaporization (vapor rest-transitions) 23 | :freezing (solid rest-transitions) 24 | false)) 25 | 26 | (defn solid [[transition & rest-transitions]] 27 | #(case transition 28 | nil true 29 | :melting (liquid rest-transitions) 30 | :sublimation (vapor rest-transitions) 31 | false)) 32 | 33 | 34 | (defn run [] 35 | (println "Phases : ") 36 | (def valid-sequence [:melting :vaporization :ionization :deionization]) 37 | (println "solid:" (trampoline solid valid-sequence)) 38 | (def invalid-sequence [:vaporization :freezing]) 39 | (println "liquid" (trampoline liquid invalid-sequence)) 40 | (println "")) 41 | -------------------------------------------------------------------------------- /Clojure/src/com/yourtion/Pattern14/discount_example.clj: -------------------------------------------------------------------------------- 1 | (ns com.yourtion.Pattern14.discount-example) 2 | 3 | (defn calculate-discount [prices] 4 | (reduce + 5 | (map (fn [price] (* price 0.10)) 6 | (filter (fn [price] (>= price 20.0)) prices)))) 7 | 8 | (defn calculate-discount-namedfn [prices] 9 | (letfn [(twenty-or-greater? [price] (>= price 20.0)) 10 | (ten-percent [price] (* price 0.10))] 11 | (reduce + 0.0 (map ten-percent (filter twenty-or-greater? prices))))) 12 | 13 | (def bill [20.0 4.5 50.0 15.75 30.0 3.50]) 14 | 15 | (defn run [] 16 | (println "Discount : ") 17 | (println "calculate-discount : " (calculate-discount bill)) 18 | (println "calculate-discount-namedfn : " (calculate-discount-namedfn bill)) 19 | (println "")) 20 | -------------------------------------------------------------------------------- /Clojure/src/com/yourtion/Pattern15/chain_example.clj: -------------------------------------------------------------------------------- 1 | (ns com.yourtion.Pattern15.chain-example 2 | (:require [clojure.string :as string])) 3 | 4 | (def my-name "michael bevilacqua linn") 5 | (defn get-intitals [] 6 | (apply str (map first (string/split my-name #" ")))) 7 | 8 | (def v1 9 | {:title "Pianocat Plays Carnegie Hall" 10 | :type :cat 11 | :length 300}) 12 | 13 | (def v2 14 | {:title "Paint Drying" 15 | :type :home-improvement 16 | :length 600}) 17 | 18 | (def v3 19 | {:title "Fuzzy McMittens Live At The Apollo" 20 | :type :cat 21 | :length 200}) 22 | 23 | (def videos [v1 v2 v3]) 24 | 25 | (defn cat-time [videos] 26 | (apply + 27 | (map :length 28 | (filter (fn [video] (= :cat (:type video))) videos)))) 29 | (defn more-cat-time [videos] 30 | (->> videos 31 | (filter (fn [video] (= :cat (:type video)))) 32 | (map :length) 33 | (apply +))) 34 | 35 | (defn run [] 36 | (println "get-intitals") 37 | (def my-name "michael bevilacqua linn") 38 | (defn get-intitals [] 39 | (apply str (map first (string/split my-name #" ")))) 40 | (println (get-intitals) ) 41 | (println "") 42 | (println "cat-time:" (cat-time videos)) 43 | (println "") 44 | (println (-> 4 (- 2) (- 2))) 45 | (println (->> 4 (- 2) (- 2))) 46 | (println "") 47 | (println "more-cat-time:" (more-cat-time videos)) 48 | (println "")) 49 | -------------------------------------------------------------------------------- /Clojure/src/com/yourtion/Pattern16/composition_examples.clj: -------------------------------------------------------------------------------- 1 | (ns com.yourtion.Pattern16.composition-examples) 2 | 3 | (defn append-a [s] (str s "a")) 4 | (defn append-b [s] (str s "b")) 5 | (defn append-c [s] (str s "c")) 6 | 7 | (def request 8 | {:headers 9 | {"Authorization" "auth" 10 | "X-RequestFingerprint" "fingerprint"} 11 | :body "body"}) 12 | 13 | (defn check-authorization [request] 14 | (let [auth-header (get-in request [:headers "Authorization"])] 15 | (assoc 16 | request 17 | :principal 18 | (if-not (nil? auth-header) 19 | "AUser")))) 20 | 21 | (defn log-fingerprint [request] 22 | (let [fingerprint (get-in request [:headers "X-RequestFingerprint"])] 23 | (println (str "FINGERPRINT=" fingerprint)) 24 | request)) 25 | 26 | (defn compose-filters [filters] 27 | (reduce 28 | (fn [all-filters, current-filter] (comp all-filters current-filter)) 29 | filters)) 30 | 31 | (defn run [] 32 | (println "CompositionExamples: ") 33 | (def append-cba (comp append-a append-b append-c)) 34 | (println (append-cba "z")) 35 | (println "") 36 | 37 | (def request {:headers 38 | {"Authorization" "auth" 39 | "X-RequestFingerprint" "fingerprint"} 40 | :body "Body"}) 41 | (def filter-chain (compose-filters [check-authorization log-fingerprint])) 42 | (println (filter-chain request)) 43 | (println "")) 44 | -------------------------------------------------------------------------------- /Clojure/src/com/yourtion/Pattern16/discount_builder.clj: -------------------------------------------------------------------------------- 1 | (ns com.yourtion.Pattern16.discount-builder) 2 | 3 | (defn discount [percentage] 4 | {:pre [(and (>= percentage 0) (<= percentage 100))]} 5 | (fn [price] (- price (* price percentage 0.01)))) 6 | 7 | (defn run [] 8 | (println "DiscountBuilder") 9 | (println "200 50% discount -> " ((discount 50) 200)) 10 | (println "200 0% discount -> " ((discount 0) 200)) 11 | (println "200 100% discount -> " ((discount 100) 200)) 12 | (def twenty-five-percent-off (discount 25)) 13 | (println "Multi1 : " (apply + (map twenty-five-percent-off [100.0 25.0 50.0 25.0]))) 14 | (println "Multi2 : " (apply + (map twenty-five-percent-off [75.0 25.0]))) 15 | (println "")) 16 | -------------------------------------------------------------------------------- /Clojure/src/com/yourtion/Pattern16/function_builder_example.clj: -------------------------------------------------------------------------------- 1 | (ns com.yourtion.Pattern16.function-builder-example 2 | (:require [com.yourtion.Pattern16.discount-builder :as discount-builder]) 3 | (:require [com.yourtion.Pattern16.selector-example :as selector-example]) 4 | (:require [com.yourtion.Pattern16.composition-examples :as composition-examples]) 5 | (:require [com.yourtion.Pattern16.partial-examples :as partial-examples])) 6 | 7 | (defn run [] 8 | (discount-builder/run) 9 | (println "") 10 | (selector-example/run) 11 | (println "") 12 | (composition-examples/run) 13 | (println "") 14 | (partial-examples/run) 15 | (println "")) 16 | -------------------------------------------------------------------------------- /Clojure/src/com/yourtion/Pattern16/partial_examples.clj: -------------------------------------------------------------------------------- 1 | (ns com.yourtion.Pattern16.partial-examples) 2 | 3 | (defn add-two-ints [int-one int-two] (+ int-one int-two)) 4 | 5 | (defn tax-for-state [state amount] 6 | (cond 7 | (= :ny state) (* amount 0.0645) 8 | (= :pa state) (* amount 0.045))) 9 | 10 | (defn run [] 11 | (println "PartialExamples :") 12 | (def add-fourty-two (partial add-two-ints 42)) 13 | (println "100 addFortyTwo: " (add-fourty-two 100)) 14 | (def ny-tax (partial tax-for-state :ny)) 15 | (println "nyTax 100 : " (ny-tax 100)) 16 | (def pa-tax (partial tax-for-state :pa)) 17 | (println "paTax 100 : " (pa-tax 100)) 18 | (println "")) 19 | -------------------------------------------------------------------------------- /Clojure/src/com/yourtion/Pattern16/selector_example.clj: -------------------------------------------------------------------------------- 1 | (ns com.yourtion.Pattern16.selector-example) 2 | 3 | (defn selector [& path] 4 | {:pre [(not (empty? path))]} 5 | (fn [ds] (get-in ds path))) 6 | 7 | (defn run [] 8 | (println "SelectorExample : ") 9 | (def simple-person {:name "Yourtion Guo"}) 10 | (def name (selector :name)) 11 | (println "name from simplePerson: " (name simple-person)) 12 | (def more-complex-person {:name {:first "Yourtion" :last "Guo"}}) 13 | (def first-name (selector :name :first)) 14 | (println "firstName from moreComplexPerson: " (first-name more-complex-person)) 15 | (def middle-name (selector :name :middle)) 16 | (println "middleName from moreComplexPerson: " (middle-name more-complex-person)) 17 | (println "")) 18 | 19 | -------------------------------------------------------------------------------- /Clojure/src/com/yourtion/Pattern17/memoization_example.clj: -------------------------------------------------------------------------------- 1 | (ns com.yourtion.Pattern17.memoization-example) 2 | 3 | (defn expensive-lookup [id] 4 | (Thread/sleep 1000) 5 | (println (str "Lookup for " id)) 6 | ({42 "foo" 12 "bar" 1 "baz"} id)) 7 | 8 | (def memoized-expensive-lookup 9 | (memoize expensive-lookup)) 10 | 11 | (def slow-fib 12 | (fn [n] 13 | (cond 14 | (<= n 0) 0 15 | (< n 2) 1 16 | :else (+ (slow-fib (- n 1)) (slow-fib (- n 2)))))) 17 | 18 | (def mem-fib 19 | (memoize 20 | (fn [n] 21 | (cond 22 | (<= n 0) 0 23 | (< n 2) 1 24 | :else (+ (mem-fib (- n 1)) (mem-fib (- n 2))))))) 25 | 26 | (defn run [] 27 | (println "Expensive lookup :") 28 | (println (expensive-lookup 42)) 29 | (println (expensive-lookup 42)) 30 | 31 | (println "memoized lookup :") 32 | (println (memoized-expensive-lookup 42)) 33 | (println (memoized-expensive-lookup 42)) 34 | 35 | (println "memoized fib :") 36 | (println "One: " (time (mem-fib 40))) 37 | (println "Two: " (time (mem-fib 40))) 38 | 39 | (println "")) 40 | -------------------------------------------------------------------------------- /Clojure/src/com/yourtion/Pattern18/lazy_sequence_example.clj: -------------------------------------------------------------------------------- 1 | (ns com.yourtion.Pattern18.lazy-sequence-example) 2 | 3 | (def integers (range Integer/MAX_VALUE)) 4 | 5 | (def randoms (repeatedly (fn [] (rand-int Integer/MAX_VALUE)))) 6 | 7 | (defn get-page [page-num] 8 | (cond 9 | (= page-num 1) "Page1" 10 | (= page-num 2) "Page2" 11 | (= page-num 3) "Page3" 12 | :default nil)) 13 | 14 | (defn paged-sequence [page-num] 15 | (let [page (get-page page-num)] 16 | (when page 17 | (cons page (lazy-seq (paged-sequence (inc page-num))))))) 18 | 19 | (defn paged-sequence-print [page-num] 20 | (let [page (get-page page-num)] 21 | (when page 22 | (println (str "Realizing " page)) 23 | (cons page (lazy-seq (paged-sequence (inc page-num))))))) 24 | 25 | (defn print-num [num] (print (str num " "))) 26 | 27 | (def print-hellos (repeatedly (fn [] (println "hello, world")))) 28 | 29 | (defn run [] 30 | (println "Some Ints :") 31 | (println (take 5 integers)) 32 | (println "") 33 | 34 | (println "aFewRabdom :") 35 | (println (take 5 randoms)) 36 | (println "") 37 | 38 | (println "aFewMoreRabdom :") 39 | (println (take 6 randoms)) 40 | (println "") 41 | 42 | (println "print Hello :") 43 | (println (take 5 print-hellos)) 44 | (println "") 45 | 46 | (println "pages :") 47 | (println (paged-sequence 1)) 48 | (println (take 2 (paged-sequence 1))) 49 | 50 | (println "")) 51 | -------------------------------------------------------------------------------- /Clojure/src/com/yourtion/Pattern19/focused_mutation_example.clj: -------------------------------------------------------------------------------- 1 | (ns com.yourtion.Pattern19.focused-mutation-example) 2 | 3 | (def one-million 1000000) 4 | (def five-hundred-thousand 500000) 5 | 6 | (defmacro time-runs [fn count] 7 | `(dotimes [_# ~count] 8 | (time ~fn))) 9 | 10 | (defn test-mutable [count] 11 | (loop [i 0 s (transient [])] 12 | (if (< i count) 13 | (recur (inc i) (conj! s i)) 14 | (persistent! s)))) 15 | 16 | (defn test-immutable [count] 17 | (loop [i 0 s []] 18 | (if (< i count) 19 | (recur (inc i) (conj s i)) 20 | s))) 21 | 22 | (defn make-test-purchase [] 23 | {:store-number (rand-int 100) 24 | :customer-number (rand-int 100) 25 | :item-number (rand-int 500)}) 26 | (defn infinite-test-purchases [] 27 | (repeatedly make-test-purchase)) 28 | 29 | (defn immutable-sequence-event-processing [count] 30 | (let [test-purchases (take count (infinite-test-purchases))] 31 | (reduce 32 | (fn [map-of-purchases {:keys [store-number] :as current-purchase}] 33 | (let [purchases-for-store (get map-of-purchases store-number '())] 34 | (assoc map-of-purchases store-number 35 | (conj purchases-for-store current-purchase)))) 36 | {} 37 | test-purchases))) 38 | 39 | (defn mutable-sequence-event-processing [count] 40 | (let [test-purchases (take count (infinite-test-purchases))] 41 | (persistent! (reduce 42 | (fn [map-of-purchases {:keys [store-number] :as current-purchase}] 43 | (let [purchases-for-store (get map-of-purchases store-number '())] 44 | (assoc! map-of-purchases store-number 45 | (conj purchases-for-store current-purchase)))) 46 | (transient {}) 47 | test-purchases)))) 48 | (defn run [] 49 | (println "Immutable :") 50 | (time-runs (test-immutable one-million) 5) 51 | (println "") 52 | 53 | (println "Mutable :") 54 | (time-runs (test-mutable one-million) 5) 55 | (println "") 56 | 57 | (println "fiveTestPurchases :") 58 | (println "Immutable :") 59 | (time-runs (immutable-sequence-event-processing five-hundred-thousand) 5) 60 | (println "Mutable :") 61 | (time-runs (mutable-sequence-event-processing five-hundred-thousand) 5) 62 | 63 | (println "")) 64 | -------------------------------------------------------------------------------- /Clojure/src/com/yourtion/Pattern20/flow_control_example.clj: -------------------------------------------------------------------------------- 1 | (ns com.yourtion.Pattern20.flow-control-example) 2 | 3 | (defmacro make-logger [name form] 4 | `(defn ~name [] 5 | (println (str "Calling " ~name)) 6 | ~form)) 7 | 8 | (defn choose [num first second third] 9 | (cond 10 | (= 1 num) (first) 11 | (= 2 num) (second) 12 | (= 3 num) (third))) 13 | 14 | (defmacro simpler-choose [num first second third] 15 | `(cond 16 | (= 1 ~num) ~first 17 | (= 2 ~num) ~second 18 | (= 3 ~num) ~third)) 19 | 20 | (defn time-run [to-time] 21 | (let [start (System/currentTimeMillis)] 22 | (to-time) 23 | (- (System/currentTimeMillis) start))) 24 | 25 | (defmacro avg-time [times to-time] 26 | `(let [total-time# 27 | (apply + (for [_# (range ~times)] (time-run (fn [] ~to-time))))] 28 | (float (/ total-time# ~times)))) 29 | 30 | (defn avg-time-fn [times to-time] 31 | (let [total-time 32 | (apply + (for [_ (range times)] (time-run to-time)))] 33 | (float (/ total-time times)))) 34 | 35 | (let 36 | [total-time 37 | (apply + (for [_ (range 5)] (time-run (fn [] (Thread/sleep 100)))))] 38 | (float (/ total-time 5))) 39 | 40 | (defn run [] 41 | (println "choose :") 42 | (choose 2 43 | (fn [] (println "hello, world")) 44 | (fn [] (println "goodbye, cruel world")) 45 | (fn [] (println "meh, indifferent world"))) 46 | (println "") 47 | 48 | (println "simpler-choose :") 49 | (simpler-choose 2 50 | (println "hello, world") 51 | (println "goodbye, cruel world") 52 | (println "meh, indifferent world")) 53 | (println "") 54 | 55 | (println "avg-time :") 56 | (println (avg-time 5 (Thread/sleep 1000))) 57 | 58 | (println "")) 59 | -------------------------------------------------------------------------------- /Clojure/src/com/yourtion/Pattern21/dsl_example.clj: -------------------------------------------------------------------------------- 1 | (ns com.yourtion.Pattern21.dsl-example 2 | (:require [clojure.string :as str] 3 | [clojure.java.shell :as shell])) 4 | 5 | (defn- print-output [output] 6 | (println (str "Exit Code: " (:exit output))) 7 | (if-not (str/blank? (:out output)) (println (:out output))) 8 | (if-not (str/blank? (:err output)) (println (:err output))) 9 | output) 10 | 11 | (defn command [command-str] 12 | (let [command-parts (str/split command-str #"\s+")] 13 | (fn [] 14 | (print-output (apply shell/sh command-parts))))) 15 | 16 | (defn command [command-str] 17 | (let [command-parts (str/split command-str #"\s+")] 18 | (fn 19 | ([] (print-output (apply shell/sh command-parts))) 20 | ([{old-out :out}] 21 | (print-output (apply shell/sh (concat command-parts [:in old-out]))))))) 22 | 23 | (defn pipe [commands] 24 | (apply comp (reverse commands))) 25 | 26 | (defmacro def-command [name command-str] 27 | `(def ~name ~(command command-str))) 28 | 29 | (defmacro def-pipe [name & command-strs] 30 | (let [commands (map command command-strs) 31 | pipe (pipe commands)] 32 | `(def ~name ~pipe))) 33 | 34 | (defn run [] 35 | (println "Command ls :") 36 | (print-output (shell/sh "ls" "-a")) 37 | 38 | (println "")) 39 | -------------------------------------------------------------------------------- /Clojure/src/com/yourtion/PatternDemo/example.clj: -------------------------------------------------------------------------------- 1 | (ns com.yourtion.PatternDemo.example 2 | (:require [com.yourtion.Pattern01.person-example-ex :as p011]) 3 | (:require [com.yourtion.Pattern01.person-example-ex :as p012]) 4 | (:require [com.yourtion.Pattern02.person-example-cc :as p02]) 5 | (:require [com.yourtion.Pattern03.cash-register :as p03]) 6 | (:require [com.yourtion.Pattern04.person :as p04]) 7 | (:require [com.yourtion.Pattern05.higher-order-functions :as p051]) 8 | (:require [com.yourtion.Pattern05.lambda-bar-and-grille :as p052]) 9 | (:require [com.yourtion.Pattern06.grade-reporter :as p06]) 10 | (:require [com.yourtion.Pattern07.people-collector-example :as p07]) 11 | (:require [com.yourtion.Pattern08.person-example :as p08]) 12 | (:require [com.yourtion.Pattern09.calculator-example :as p09]) 13 | (:require [com.yourtion.Pattern10.visitor-example :as p10]) 14 | (:require [com.yourtion.Pattern11.services :as p11]) 15 | (:require [com.yourtion.Pattern12.names :as p12]) 16 | (:require [com.yourtion.Pattern13.mutual-recursion-example :as p13]) 17 | (:require [com.yourtion.Pattern14.discount-example :as p14]) 18 | (:require [com.yourtion.Pattern15.chain-example :as p15]) 19 | (:require [com.yourtion.Pattern16.composition-examples :as p16]) 20 | (:require [com.yourtion.Pattern17.memoization-example :as p17]) 21 | (:require [com.yourtion.Pattern18.lazy-sequence-example :as p18]) 22 | (:require [com.yourtion.Pattern19.focused-mutation-example :as p19]) 23 | (:require [com.yourtion.Pattern20.flow-control-example :as p20]) 24 | (:require [com.yourtion.Pattern21.dsl-example :as p21])) 25 | 26 | 27 | (println) 28 | (println "Pattern01 Example: ") 29 | (println) 30 | (p011/run) 31 | (p012/run) 32 | (println "------------------------------------") 33 | 34 | (println) 35 | (println "Pattern02 Example: ") 36 | (println) 37 | (p02/run) 38 | (println "------------------------------------") 39 | 40 | (println) 41 | (println "Pattern03 Example: ") 42 | (println) 43 | (p03/run) 44 | (println "------------------------------------") 45 | 46 | (println) 47 | (println "Pattern04 Example: ") 48 | (println) 49 | (p04/run) 50 | (println "------------------------------------") 51 | 52 | (println) 53 | (println "Pattern05 Example: ") 54 | (println) 55 | (p051/run) 56 | (p052/run) 57 | (println "------------------------------------") 58 | 59 | (println) 60 | (println "Pattern06 Example: ") 61 | (println) 62 | (p06/run) 63 | (println "------------------------------------") 64 | 65 | (println) 66 | (println "Pattern07 Example: ") 67 | (println) 68 | (p07/run) 69 | (println "------------------------------------") 70 | 71 | (println) 72 | (println "Pattern08 Example: ") 73 | (println) 74 | (p08/run) 75 | (println "------------------------------------") 76 | 77 | (println) 78 | (println "Pattern09 Example: ") 79 | (println) 80 | (p09/run) 81 | (println "------------------------------------") 82 | 83 | (println) 84 | (println "Pattern10 Example: ") 85 | (println) 86 | (p10/run) 87 | (println "------------------------------------") 88 | 89 | (println) 90 | (println "Pattern11 Example: ") 91 | (println) 92 | (p11/run) 93 | (println "------------------------------------") 94 | 95 | (println) 96 | (println "Pattern12 Example: ") 97 | (println) 98 | (p12/run) 99 | (println "------------------------------------") 100 | 101 | (println) 102 | (println "Pattern13 Example: ") 103 | (println) 104 | (p13/run) 105 | (println "------------------------------------") 106 | 107 | (println) 108 | (println "Pattern14 Example: ") 109 | (println) 110 | (p14/run) 111 | (println "------------------------------------") 112 | 113 | (println) 114 | (println "Pattern15 Example: ") 115 | (println) 116 | (p15/run) 117 | (println "------------------------------------") 118 | 119 | (println) 120 | (println "Pattern16 Example: ") 121 | (println) 122 | (p16/run) 123 | (println "------------------------------------") 124 | 125 | (println) 126 | (println "Pattern17 Example: ") 127 | (println) 128 | (p17/run) 129 | (println "------------------------------------") 130 | 131 | (println) 132 | (println "Pattern18 Example: ") 133 | (println) 134 | (p18/run) 135 | (println "------------------------------------") 136 | 137 | (println) 138 | (println "Pattern19 Example: ") 139 | (println) 140 | (p19/run) 141 | (println "------------------------------------") 142 | 143 | (println) 144 | (println "Pattern20 Example: ") 145 | (println) 146 | (p20/run) 147 | (println "------------------------------------") 148 | 149 | (println) 150 | (println "Pattern01 Example: ") 151 | (println) 152 | (p21/run) 153 | (println "------------------------------------") 154 | 155 | -------------------------------------------------------------------------------- /Clojure/src/com/yourtion/TinyWeb/ControllerException.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.TinyWeb; 2 | 3 | /** 4 | * Created by Yourtion on 9/5/16. 5 | */ 6 | public class ControllerException extends RuntimeException { 7 | private Integer statusCode; 8 | 9 | public ControllerException(Integer statusCode) { 10 | this.statusCode = statusCode; 11 | } 12 | 13 | public Integer getStatusCode() { 14 | return statusCode; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Clojure/src/com/yourtion/TinyWeb/RenderingException.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.TinyWeb; 2 | 3 | /** 4 | * Created by Yourtion on 9/5/16. 5 | */ 6 | public class RenderingException extends RuntimeException { 7 | 8 | public RenderingException(Exception e) { 9 | super(e); 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /Clojure/src/com/yourtion/TinyWeb/core.clj: -------------------------------------------------------------------------------- 1 | (ns com.yourtion.TinyWeb.core 2 | (:require [clojure.string :as str]) 3 | (:import (com.yourtion.TinyWeb RenderingException ControllerException))) 4 | (defn- render [view model] 5 | (try 6 | (view model) 7 | (catch Exception e (throw (RenderingException. e))))) 8 | (defn- execute-request [http-request handler] 9 | (let [controller (handler :controller) 10 | view (handler :view)] 11 | (try 12 | {:status-code 200 13 | :body 14 | (render 15 | view 16 | (controller http-request))} 17 | (catch ControllerException e {:status-code (.getStatusCode e) :body ""}) 18 | (catch RenderingException e {:status-code 500 19 | :body "Exception while rendering"}) 20 | (catch Exception e (.printStackTrace e) {:status-code 500 :body ""})))) 21 | (defn- apply-filters [filters http-request] 22 | (let [composed-filter (reduce comp (reverse filters))] 23 | (composed-filter http-request))) 24 | (defn tinyweb [request-handlers filters] 25 | (fn [http-request] 26 | (let [filtered-request (apply-filters filters http-request) 27 | path (http-request :path) 28 | handler (request-handlers path)] 29 | (execute-request filtered-request handler)))) 30 | -------------------------------------------------------------------------------- /Clojure/src/com/yourtion/TinyWeb/example.clj: -------------------------------------------------------------------------------- 1 | (ns com.yourtion.TinyWeb.example 2 | (:use [com.yourtion.TinyWeb.core]) 3 | (:require [clojure.string :as str])) 4 | 5 | (defn render-greeting [greeting] 6 | (str "

"greeting"

")) 7 | 8 | (defn greeting-view [model] 9 | (let [rendered-greetings (str/join " " (map render-greeting (:greetings model)))] 10 | (str "

Friendly Greetings

" rendered-greetings))) 11 | 12 | (defn logging-filter [http-request] 13 | (println (str "In Logging Filter - request for path: " (:path http-request))) 14 | http-request) 15 | 16 | (defn make-greeting [name] 17 | (let [greetings ["Hello" "Greetings" "Salutations" "Hola"] 18 | greeting-count (count greetings)] 19 | (str (greetings (rand-int greeting-count)) ", " name))) 20 | 21 | (defn handle-greeting [http-request] 22 | {:greetings (map make-greeting (str/split (:body http-request) #","))}) 23 | 24 | (def request-handlers 25 | {"/greeting" {:controller handle-greeting :view greeting-view}}) 26 | (def filters [logging-filter]) 27 | (def tinyweb-instance (tinyweb request-handlers filters)) 28 | 29 | (def request {:path "/greeting" :body "Mike,Joe,John,Steve"}) 30 | (def testResponse (tinyweb-instance request)) 31 | (println "responseCode: ", (testResponse :status-code)) 32 | (println "responseBody: ") 33 | (println (testResponse :body)) 34 | -------------------------------------------------------------------------------- /Java/.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Java template 3 | *.class 4 | 5 | # Mobile Tools for Java (J2ME) 6 | .mtj.tmp/ 7 | 8 | # Package Files # 9 | *.jar 10 | *.war 11 | *.ear 12 | 13 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 14 | hs_err_pid* 15 | 16 | -------------------------------------------------------------------------------- /Java/Java.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern01/Person.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern01; 2 | 3 | /** 4 | * Created by Yourtion on 9/7/16. 5 | */ 6 | 7 | public class Person implements Comparable { 8 | private String firstName; 9 | private String lastName; 10 | 11 | public Person(String firstName, String lastName) { 12 | this.firstName = firstName; 13 | this.lastName = lastName; 14 | } 15 | 16 | public String getFirstName() { 17 | return firstName; 18 | } 19 | 20 | public void setFirstName(String firstName) { 21 | this.firstName = firstName; 22 | } 23 | 24 | public String getLastName() { 25 | return lastName; 26 | } 27 | 28 | public void setLastName(String lastName) { 29 | this.lastName = lastName; 30 | } 31 | 32 | @Override 33 | // Implements the Comparable interface. 34 | public int compareTo(Person otherPerson) { 35 | return this.lastName.compareTo(otherPerson.lastName); 36 | } 37 | 38 | @Override 39 | public String toString() { 40 | return firstName + " " + lastName; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern01/PersonExample.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern01; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.Comparator; 6 | import java.util.List; 7 | 8 | /** 9 | * Created by Yourtion on 9/7/16. 10 | */ 11 | public class PersonExample { 12 | public void run() { 13 | Person p1 = new Person("Mike", "Bevilacqua"); 14 | Person p2 = new Person("Pedro", "Vasquez"); 15 | Person p3 = new Person("Robert", "Aarons"); 16 | 17 | List people = new ArrayList(); 18 | people.add(p1); 19 | people.add(p2); 20 | people.add(p3); 21 | 22 | Collections.sort(people, new Comparator() { 23 | public int compare(Person p1, Person p2) { 24 | return p1.getFirstName().compareTo(p2.getFirstName()); 25 | } 26 | }); 27 | 28 | for (Person person : people) { 29 | System.out.println(person); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern01/PersonExampleEx.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern01; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.Comparator; 6 | import java.util.List; 7 | 8 | /** 9 | * Created by Yourtion on 9/7/16. 10 | */ 11 | public class PersonExampleEx { 12 | public void run() { 13 | List people = new ArrayList(); 14 | people.add(new PersonExpanded("Aaron", "Jeffrey", "Smith")); 15 | people.add(new PersonExpanded("Aaron", "Bailey", "Zanthar")); 16 | people.add(new PersonExpanded("Brian", "Adams", "Smith")); 17 | 18 | Collections.sort(people, new ComplicatedNameComparator()); 19 | 20 | for (PersonExpanded person : people) { 21 | System.out.println(person); 22 | } 23 | } 24 | } 25 | 26 | class ComplicatedNameComparator implements Comparator { 27 | public int compare(PersonExpanded p1, PersonExpanded p2) { 28 | 29 | int firstNameCompare = 30 | p1.getFirstName().compareTo(p2.getFirstName()); 31 | int lastNameCompare = p1.getLastName().compareTo(p2.getLastName()); 32 | int middleNameCompare = p1.getMidName().compareTo(p2.getMidName()); 33 | 34 | if (0 != firstNameCompare) 35 | return firstNameCompare; 36 | else if (0 != lastNameCompare) 37 | return lastNameCompare; 38 | else 39 | return middleNameCompare; 40 | } 41 | } -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern01/PersonExpanded.java: -------------------------------------------------------------------------------- 1 | /*** 2 | * Excerpted from "Functional Programming Patterns", 3 | * published by The Pragmatic Bookshelf. 4 | * Copyrights apply to this code. It may not be used to create training material, 5 | * courses, books, articles, and the like. Contact us if you are in doubt. 6 | * We make no guarantees that this code is fit for any purpose. 7 | * Visit http://www.pragmaticprogrammer.com/titles/mbfpp for more book information. 8 | ***/ 9 | package com.yourtion.Pattern01; 10 | 11 | public class PersonExpanded implements Comparable { 12 | private String firstName; 13 | private String lastName; 14 | private String midName; 15 | 16 | public PersonExpanded(String firstName, String midName, String lastName) { 17 | this.firstName = firstName; 18 | this.lastName = lastName; 19 | this.midName = midName; 20 | } 21 | 22 | public String getFirstName() { 23 | return firstName; 24 | } 25 | 26 | public void setFirstName(String firstName) { 27 | this.firstName = firstName; 28 | } 29 | 30 | public String getLastName() { 31 | return lastName; 32 | } 33 | 34 | public void setLastName(String lastName) { 35 | this.lastName = lastName; 36 | } 37 | 38 | public String getMidName() { 39 | return midName; 40 | } 41 | 42 | public void setMidName(String middleName) { 43 | this.midName = middleName; 44 | } 45 | 46 | @Override 47 | public int compareTo(PersonExpanded otherPerson) { 48 | return this.lastName.compareTo(otherPerson.lastName); 49 | } 50 | 51 | @Override 52 | public String toString() { 53 | return firstName + " " + midName + " " + lastName; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern02/ComposedComparator.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern02; 2 | 3 | import java.util.Comparator; 4 | 5 | /** 6 | * Created by Yourtion on 9/8/16. 7 | */ 8 | public class ComposedComparator implements Comparator { 9 | 10 | private Comparator[] comparators; 11 | 12 | public ComposedComparator(Comparator... comparators) { 13 | this.comparators = comparators; 14 | } 15 | 16 | @Override 17 | public int compare(T o1, T o2) { 18 | for (Comparator comparator : comparators) { 19 | int result = comparator.compare(o1, o2); 20 | if (result != 0) 21 | return result; 22 | } 23 | return 0; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern02/PersonExampleCC.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern02; 2 | 3 | import com.yourtion.Pattern01.PersonExpanded; 4 | 5 | import java.util.Comparator; 6 | 7 | /** 8 | * Created by Yourtion on 9/8/16. 9 | */ 10 | public class PersonExampleCC { 11 | public void run() { 12 | Comparator firstAndLastNameComparator = 13 | new ComposedComparator( 14 | new FirstNameComparator(), 15 | new LastNameComparator()); 16 | 17 | PersonExpanded personOne = new PersonExpanded("John", "", "Adams"); 18 | PersonExpanded personTwo = new PersonExpanded("John", "Quincy", "Adams"); 19 | 20 | System.out 21 | .println(firstAndLastNameComparator.compare(personOne, personTwo)); 22 | } 23 | } 24 | 25 | class FirstNameComparator implements Comparator { 26 | @Override 27 | public int compare(PersonExpanded personOne, PersonExpanded personTwo) { 28 | return personOne.getFirstName().compareTo(personTwo.getFirstName()); 29 | } 30 | } 31 | 32 | class LastNameComparator implements Comparator { 33 | @Override 34 | public int compare(PersonExpanded personOne, PersonExpanded personTwo) { 35 | return personOne.getLastName().compareTo(personTwo.getLastName()); 36 | } 37 | } -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern03/CashRegister.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern03; 2 | 3 | /** 4 | * Created by Yourtion on 10/10/2016. 5 | */ 6 | public class CashRegister { 7 | private Integer total; 8 | 9 | public CashRegister(Integer startingTotal) { 10 | total = startingTotal; 11 | } 12 | 13 | public void addCash(Integer toAdd) { 14 | total += toAdd; 15 | } 16 | 17 | public Integer getTotal() { 18 | return total; 19 | } 20 | 21 | public void reset() { 22 | total = 0; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern03/Command.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern03; 2 | 3 | /** 4 | * Created by Yourtion on 10/10/2016. 5 | */ 6 | public interface Command { 7 | public void execute(); 8 | } 9 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern03/Purchase.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern03; 2 | 3 | /** 4 | * Created by Yourtion on 10/10/2016. 5 | */ 6 | public class Purchase implements Command { 7 | private CashRegister cashRegister; 8 | private Integer amount; 9 | 10 | public Purchase(CashRegister cashRegister, Integer amount) { 11 | this.cashRegister = cashRegister; 12 | this.amount = amount; 13 | } 14 | 15 | @Override 16 | public void execute() { 17 | System.out.println("-> Purchase in amount: " + amount); 18 | cashRegister.addCash(amount); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern03/PurchaseInvoker.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern03; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * Created by Yourtion on 10/10/2016. 8 | */ 9 | public class PurchaseInvoker { 10 | private List executedPurchases = new ArrayList(); 11 | 12 | public void executePurchase(Command purchase) { 13 | purchase.execute(); 14 | executedPurchases.add(purchase); 15 | } 16 | 17 | public List getPurchaseHistory() { 18 | return executedPurchases; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern03/RegisterClient.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern03; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * Created by Yourtion on 10/10/2016. 7 | */ 8 | public class RegisterClient { 9 | private static CashRegister cashRegister = new CashRegister(0); 10 | private static PurchaseInvoker purchaseInvoker = new PurchaseInvoker(); 11 | 12 | public void run() { 13 | Command purchase1 = new Purchase(cashRegister, 100); 14 | Command purchase2 = new Purchase(cashRegister, 50); 15 | 16 | // Invoke commands, check register total. 17 | purchaseInvoker.executePurchase(purchase1); 18 | purchaseInvoker.executePurchase(purchase2); 19 | System.out.println("After purchases: " + cashRegister.getTotal()); 20 | 21 | // Replay purchases 22 | cashRegister.reset(); 23 | System.out.println("Register reset to 0"); 24 | List purchases = purchaseInvoker.getPurchaseHistory(); 25 | for (Command purchase : purchases) { 26 | purchase.execute(); 27 | } 28 | System.out.println("After replay: " + cashRegister.getTotal()); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern04/ImmutablePerson.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern04; 2 | 3 | /** 4 | * Created by Yourtion on 10/10/2016. 5 | */ 6 | public class ImmutablePerson { 7 | private final String firstName; 8 | private final String lastName; 9 | 10 | public String getFirstName() { 11 | return firstName; 12 | } 13 | 14 | public String getLastName() { 15 | return lastName; 16 | } 17 | 18 | @Override 19 | public String toString() { 20 | return firstName + " " + lastName; 21 | } 22 | 23 | private ImmutablePerson(Builder builder){ 24 | firstName = builder.firstName; 25 | lastName = builder.lastName; 26 | } 27 | 28 | public static class Builder { 29 | private String firstName; 30 | private String lastName; 31 | 32 | public Builder firstName(String firstName) { 33 | this.firstName = firstName; 34 | return this; 35 | } 36 | 37 | public Builder lastName(String lastName) { 38 | this.lastName = lastName; 39 | return this; 40 | } 41 | 42 | public ImmutablePerson build() { 43 | return new ImmutablePerson(this); 44 | } 45 | } 46 | 47 | public static Builder newBuilder() { 48 | return new Builder(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern04/PersonHarness.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern04; 2 | 3 | /** 4 | * Created by Yourtion on 10/10/2016. 5 | */ 6 | public class PersonHarness { 7 | 8 | public void run() { 9 | ImmutablePerson.Builder b = ImmutablePerson.newBuilder(); 10 | ImmutablePerson p = b.firstName("Yourtion").lastName("Guo").build(); 11 | System.out.println("Person is: " + p.toString()); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern05/HigherOrderFunctions.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern05; 2 | 3 | import java.util.*; 4 | 5 | /** 6 | * Created by Yourtion on 11/10/2016. 7 | */ 8 | public class HigherOrderFunctions { 9 | 10 | public static Integer sumSequence(List sequence) { 11 | Integer sum = 0; 12 | for (Integer num : sequence) { 13 | sum += num; 14 | } 15 | return sum; 16 | } 17 | 18 | 19 | public static List prependHello(List names) { 20 | List prepended = new ArrayList(); 21 | for (String name : names) { 22 | prepended.add("Hello " + name); 23 | } 24 | return prepended; 25 | } 26 | 27 | 28 | public static Set vowelsInWord(String word) { 29 | 30 | Set vowelsInWord = new HashSet(); 31 | 32 | for (Character character : word.toLowerCase().toCharArray()) { 33 | if (isVowel(character)) { 34 | vowelsInWord.add(character); 35 | } 36 | } 37 | 38 | return vowelsInWord; 39 | } 40 | 41 | private static Boolean isVowel(Character c){ 42 | Set vowels = new HashSet(); 43 | vowels.add('a'); 44 | vowels.add('e'); 45 | vowels.add('i'); 46 | vowels.add('o'); 47 | vowels.add('u'); 48 | return vowels.contains(c); 49 | } 50 | 51 | public void run() { 52 | System.out.println("vowelsInWord: " + vowelsInWord("Yourtion")); 53 | System.out.println(); 54 | 55 | List nameList = Arrays.asList("Yourtion", "Sophia"); 56 | System.out.println("person: " + nameList); 57 | System.out.println("prependHello: " + prependHello(nameList)); 58 | System.out.println(); 59 | 60 | List sequence = Arrays.asList(1, 2, 3, 4, 5); 61 | System.out.println("sumSequence: " + sumSequence(sequence)); 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern05/TheLambdaBarAndGrille.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern05; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | /** 9 | * Created by Yourtion on 11/10/2016. 10 | */ 11 | 12 | class Address { 13 | 14 | private Integer zipCode; 15 | 16 | // Other fields elided for the sake of brevity. 17 | 18 | public Integer getZipCode() { 19 | return zipCode; 20 | } 21 | 22 | public void setZipCode(Integer zipCode) { 23 | this.zipCode = zipCode; 24 | } 25 | } 26 | 27 | class Person { 28 | 29 | private String name; 30 | private Address address; 31 | 32 | public String getName() { 33 | return name; 34 | } 35 | 36 | public void setName(String name) { 37 | this.name = name; 38 | } 39 | 40 | public Address getAddress() { 41 | return address; 42 | } 43 | 44 | public void setAddress(Address address) { 45 | this.address = address; 46 | } 47 | 48 | public static Person creatPerson(String name, Integer zipCode) { 49 | Address a = new Address(); 50 | a.setZipCode(zipCode); 51 | 52 | Person p = new Person(); 53 | p.name = name; 54 | p.address = a; 55 | 56 | return p; 57 | } 58 | 59 | @Override 60 | public String toString() { 61 | return String.format("%s - %d", this.name, this.address.getZipCode()); 62 | } 63 | } 64 | 65 | 66 | public class TheLambdaBarAndGrille { 67 | 68 | public Map> peopleByZip(List people) { 69 | Map> closePeople = 70 | new HashMap>(); 71 | 72 | for (Person person : people) { 73 | Integer zipCode = person.getAddress().getZipCode(); 74 | if (isCloseZip(zipCode)){ 75 | List peopleForZip = 76 | closePeople.get(zipCode); 77 | closePeople.put(zipCode, 78 | addPerson(peopleForZip, person)); 79 | } 80 | } 81 | 82 | return closePeople; 83 | } 84 | 85 | private List addPerson(List people, Person person) { 86 | if (null == people) 87 | people = new ArrayList(); 88 | people.add(person.getName()); 89 | return people; 90 | } 91 | private Boolean isCloseZip(Integer zipCode) { 92 | return zipCode == 19123 || zipCode == 19103; 93 | } 94 | 95 | public void run() { 96 | ArrayList persons = new ArrayList(); 97 | persons.add( Person.creatPerson("Yourtion1", 19123) ); 98 | persons.add( Person.creatPerson("Yourtion2", 19103) ); 99 | persons.add( Person.creatPerson("Yourtion3", 19129) ); 100 | persons.add( Person.creatPerson("Yourtion4", 19103) ); 101 | persons.add( Person.creatPerson("Yourtion5", 19111) ); 102 | 103 | System.out.println("All person: " + persons); 104 | System.out.println("closePeople: " + peopleByZip(persons)); 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern06/FullGradeReporter.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern06; 2 | 3 | import java.util.*; 4 | 5 | /** 6 | * Created by Yourtion on 12/10/2016. 7 | */ 8 | public class FullGradeReporter extends GradeReporterTemplate { 9 | @Override 10 | public String numToLetter(Double grade) { 11 | if (grade <= 5.0 && grade > 4.0) 12 | return "A"; 13 | else if (grade <= 4.0 && grade > 3.0) 14 | return "B"; 15 | else if (grade <= 3.0 && grade > 2.0) 16 | return "C"; 17 | else if (grade <= 2.0 && grade > 0.0) 18 | return "D"; 19 | else if (grade == 0.0) 20 | return "F"; 21 | else 22 | return "N/A"; 23 | } 24 | 25 | @Override 26 | protected void printGradeReport(List grades) { 27 | SortedMap gradeCounts = new TreeMap(); 28 | 29 | for (String grade : grades) { 30 | Integer currentGradeCount = gradeCounts.get(grade); 31 | if (null == currentGradeCount) 32 | gradeCounts.put(grade, 1); 33 | else 34 | gradeCounts.put(grade, currentGradeCount + 1); 35 | } 36 | 37 | for (Map.Entry gradeCount : gradeCounts.entrySet()) { 38 | StringBuffer bar = new StringBuffer(); 39 | for (int i = 0; i < gradeCount.getValue(); i++) 40 | bar.append("*"); 41 | System.out.printf("%s: %s\n", gradeCount.getKey(), bar); 42 | } 43 | } 44 | 45 | public void run() { 46 | GradeReporterTemplate gradeReporter = new FullGradeReporter(); 47 | List grades = Arrays.asList( 5.0, 4.0, 4.4, 2.2, 3.3, 3.5 ); 48 | gradeReporter.reportGrades(grades); 49 | } 50 | } -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern06/GradeReporterTemplate.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern06; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * Created by Yourtion on 12/10/2016. 8 | */ 9 | public abstract class GradeReporterTemplate { 10 | 11 | public void reportGrades(List grades) { 12 | List convertedGrades = new ArrayList(); 13 | for (Double grade : grades) { 14 | convertedGrades.add(numToLetter(grade)); 15 | } 16 | printGradeReport(convertedGrades); 17 | } 18 | 19 | protected abstract String numToLetter(Double grade); 20 | 21 | protected abstract void printGradeReport(List grades); 22 | } 23 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern06/PlusMinusGradeReporter.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern06; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | 6 | /** 7 | * Created by Yourtion on 12/10/2016. 8 | */ 9 | public class PlusMinusGradeReporter extends GradeReporterTemplate { 10 | @Override 11 | protected String numToLetter(Double grade) { 12 | if (grade <= 5.0 && grade > 4.7) 13 | return "A"; 14 | else if (grade <= 4.7 && grade > 4.3) 15 | return "A-"; 16 | else if (grade <= 4.3 && grade > 4.0) 17 | return "B+"; 18 | else if (grade <= 4.0 && grade > 3.7) 19 | return "B"; 20 | else if (grade <= 3.7 && grade > 3.3) 21 | return "B-"; 22 | else if (grade <= 3.3 && grade > 3.0) 23 | return "C+"; 24 | else if (grade <= 3.0 && grade > 2.7) 25 | return "C"; 26 | else if (grade <= 2.7 && grade > 2.3) 27 | return "C-"; 28 | else if (grade <= 2.3 && grade > 0.0) 29 | return "D"; 30 | else if (grade == 0.0) 31 | return "F"; 32 | else 33 | return "N/A"; 34 | } 35 | 36 | @Override 37 | protected void printGradeReport(List grades) { 38 | for (String grade : grades) { 39 | System.out.println("Grade is: " + grade); 40 | } 41 | } 42 | 43 | public void run() { 44 | GradeReporterTemplate gradeReporter = new PlusMinusGradeReporter(); 45 | List grades = Arrays.asList(5.0, 4.0, 4.4, 2.2, 3.3, 3.5); 46 | gradeReporter.reportGrades(grades); 47 | } 48 | } -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern07/FirstNameValidator.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern07; 2 | 3 | /** 4 | * Created by Yourtion on 20/10/2016. 5 | */ 6 | public class FirstNameValidator implements PersonValidator { 7 | @Override 8 | public boolean validate(Person person) { 9 | return person.getFirstName() != null; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern07/FullNameValidator.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern07; 2 | 3 | /** 4 | * Created by Yourtion on 20/10/2016. 5 | */ 6 | public class FullNameValidator implements PersonValidator { 7 | @Override 8 | public boolean validate(Person person) { 9 | return person.getFirstName() != null 10 | && person.getMiddleName() != null 11 | && person.getLastName() != null; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern07/Person.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern07; 2 | 3 | /** 4 | * Created by Yourtion on 20/10/2016. 5 | */ 6 | public class Person { 7 | private String firstName; 8 | private String lastName; 9 | private String middleName; 10 | 11 | public Person(String firstName, String middleName, String lastName) { 12 | this.firstName = firstName; 13 | this.lastName = lastName; 14 | this.middleName = middleName; 15 | } 16 | 17 | public String getFirstName() { 18 | return firstName; 19 | } 20 | 21 | public void setFirstName(String firstName) { 22 | this.firstName = firstName; 23 | } 24 | 25 | public String getLastName() { 26 | return lastName; 27 | } 28 | 29 | public void setLastName(String lastName) { 30 | this.lastName = lastName; 31 | } 32 | 33 | public String getMiddleName() { 34 | return middleName; 35 | } 36 | 37 | public void setMiddleName(String middleName) { 38 | this.middleName = middleName; 39 | } 40 | 41 | @Override 42 | public String toString() { 43 | return firstName + " " + middleName + " " + lastName; 44 | } 45 | 46 | 47 | } 48 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern07/PersonCollector.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern07; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * Created by Yourtion on 20/10/2016. 8 | */ 9 | public class PersonCollector { 10 | private PersonValidator personValidator; 11 | private List validPeople; 12 | 13 | public PersonCollector(PersonValidator personValidator) { 14 | this.personValidator = personValidator; 15 | this.validPeople = new ArrayList(); 16 | } 17 | 18 | public void addPerson(Person person) { 19 | if (personValidator.validate(person)) 20 | validPeople.add(person); 21 | } 22 | 23 | public List getValidPeople() { 24 | return validPeople; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern07/PersonCollectorExample.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern07; 2 | 3 | /** 4 | * Created by Yourtion on 20/10/2016. 5 | */ 6 | public class PersonCollectorExample { 7 | 8 | public void run() { 9 | Person person1 = new Person("Yourtion", null, "Guo"); 10 | Person person2 = new Person("John", "Quincy", "Adams"); 11 | Person person3 = new Person(null, "John", "Adams"); 12 | Person person4 = new Person(null, null, null); 13 | 14 | System.out.println("FirstNameValidator"); 15 | 16 | PersonValidator firstNameValidator = new FirstNameValidator(); 17 | PersonCollector personCollector1 = new PersonCollector(firstNameValidator); 18 | personCollector1.addPerson(person1); 19 | personCollector1.addPerson(person2); 20 | personCollector1.addPerson(person3); 21 | personCollector1.addPerson(person4); 22 | System.out.println("FirstNameValidator Collector list : " + personCollector1.getValidPeople()); 23 | 24 | System.out.println(""); 25 | 26 | System.out.println("FullNameValidator"); 27 | 28 | PersonValidator fullNameValidator = new FullNameValidator(); 29 | PersonCollector personCollector2 = new PersonCollector(fullNameValidator); 30 | personCollector2.addPerson(person1); 31 | personCollector2.addPerson(person2); 32 | personCollector2.addPerson(person3); 33 | personCollector2.addPerson(person4); 34 | System.out.println("FullNameValidator Collector list : " + personCollector2.getValidPeople()); 35 | 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern07/PersonValidator.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern07; 2 | 3 | /** 4 | * Created by Yourtion on 20/10/2016. 5 | */ 6 | public interface PersonValidator { 7 | public boolean validate(Person person); 8 | } 9 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern08/NullPerson.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern08; 2 | 3 | /** 4 | * Created by Yourtion on 23/11/2016. 5 | */ 6 | public class NullPerson implements Person { 7 | 8 | public String getFirstName() { 9 | return "John"; 10 | } 11 | 12 | public void setFirstName(String firstName) { 13 | } 14 | 15 | public String getLastName() { 16 | return "Doe"; 17 | } 18 | 19 | public void setLastName(String lastName) { 20 | } 21 | 22 | @Override 23 | public String toString() { 24 | return getFirstName() + " " + getLastName(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern08/Person.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern08; 2 | 3 | /** 4 | * Created by Yourtion on 23/11/2016. 5 | */ 6 | public interface Person { 7 | public String getFirstName(); 8 | 9 | public void setFirstName(String firstName); 10 | 11 | public String getLastName(); 12 | 13 | public void setLastName(String lastName); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern08/PersonExample.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern08; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * Created by Yourtion on 23/11/2016. 8 | */ 9 | public class PersonExample { 10 | 11 | private Map people; 12 | 13 | public PersonExample() { 14 | people = new HashMap(); 15 | } 16 | 17 | public Person fetchPerson(Integer id) { 18 | Person person = people.get(id); 19 | if (null != person) 20 | return person; 21 | else 22 | return new NullPerson(); 23 | } 24 | // Code to add/remove people 25 | 26 | public Person buildPerson(String firstName, String lastName) { 27 | if (null != firstName && null != lastName) 28 | return new RealPerson(firstName, lastName); 29 | else 30 | return new NullPerson(); 31 | } 32 | 33 | public void run() { 34 | System.out.println("BuildPerson :"); 35 | 36 | PersonExample example = new PersonExample(); 37 | 38 | System.out.println("Not null: " + example.buildPerson("Yourtion", "Guo")); 39 | System.out.println("Null first name: " + example.buildPerson(null, "Guo")); 40 | System.out.println("Null last name: " + example.buildPerson("Yourtion", null)); 41 | 42 | System.out.println(""); 43 | System.out.println("FetchPerson :"); 44 | 45 | example.people.put(0, example.buildPerson("Yourtion", "Guo")); 46 | 47 | System.out.println("Not null: " + example.fetchPerson(0)); 48 | System.out.println("Null: " + example.fetchPerson(1)); 49 | 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern08/RealPerson.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern08; 2 | 3 | /** 4 | * Created by Yourtion on 23/11/2016. 5 | */ 6 | public class RealPerson implements Person { 7 | 8 | private String firstName; 9 | private String lastName; 10 | 11 | public RealPerson(String firstName, String lastName) { 12 | this.firstName = firstName; 13 | this.lastName = lastName; 14 | } 15 | 16 | public String getFirstName() { 17 | return firstName; 18 | } 19 | 20 | public void setFirstName(String firstName) { 21 | this.firstName = firstName; 22 | } 23 | 24 | public String getLastName() { 25 | return lastName; 26 | } 27 | 28 | public void setLastName(String lastName) { 29 | this.lastName = lastName; 30 | } 31 | 32 | @Override 33 | public String toString() { 34 | return firstName + " " + lastName; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern09/Calculator.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern09; 2 | 3 | /** 4 | * Created by Yourtion on 28/11/2016. 5 | */ 6 | public interface Calculator { 7 | 8 | public int Add(int a, int b); 9 | 10 | public int Subtract(int a, int b); 11 | 12 | public int Divide(int a, int b); 13 | 14 | public int Multiply(int a, int b); 15 | } 16 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern09/CalculatorExample.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern09; 2 | 3 | /** 4 | * Created by Yourtion on 28/11/2016. 5 | */ 6 | public class CalculatorExample { 7 | 8 | public void run() { 9 | System.out.println("Without Logging :"); 10 | 11 | CalculatorImpl cal1 = new CalculatorImpl(); 12 | System.out.println(cal1.Add(1, 2)); 13 | System.out.println(cal1.Subtract(4,3)); 14 | System.out.println(cal1.Divide(6,2)); 15 | System.out.println(cal1.Multiply(2,3)); 16 | 17 | System.out.println(""); 18 | System.out.println("Logging :"); 19 | 20 | CalculatorImpl cal2 = new LoggingCalculator(); 21 | System.out.println(cal2.Add(1,2)); 22 | System.out.println(cal2.Subtract(4,3)); 23 | System.out.println(cal2.Divide(6,2)); 24 | System.out.println(cal2.Multiply(2,3)); 25 | 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern09/CalculatorImpl.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern09; 2 | 3 | /** 4 | * Created by Yourtion on 28/11/2016. 5 | */ 6 | public class CalculatorImpl implements Calculator { 7 | 8 | public int Add(int a, int b) { 9 | return a + b; 10 | } 11 | 12 | public int Subtract(int a, int b) { 13 | return a - b; 14 | } 15 | 16 | public int Divide(int a, int b) { 17 | return a / b; 18 | } 19 | 20 | public int Multiply(int a, int b) { 21 | return a * b; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern09/LoggingCalculator.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern09; 2 | 3 | /** 4 | * Created by Yourtion on 28/11/2016. 5 | */ 6 | public class LoggingCalculator extends CalculatorImpl { 7 | 8 | @Override 9 | public int Add(int a, int b) { 10 | int result = super.Add(a, b); 11 | System.out.println("Result is: " + result); 12 | return result; 13 | } 14 | 15 | @Override 16 | public int Subtract(int a, int b) { 17 | int result = super.Subtract(a, b); 18 | System.out.println("Result is: " + result); 19 | return result; 20 | } 21 | 22 | @Override 23 | public int Divide(int a, int b) { 24 | int result = super.Divide(a, b); 25 | System.out.println("Result is: " + result); 26 | return result; 27 | } 28 | 29 | @Override 30 | public int Multiply(int a, int b) { 31 | int result = super.Multiply(a, b); 32 | System.out.println("Result is: " + result); 33 | return result; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern10/Empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yourtion/LearningFunctionalProgramming/0ccfffe61b8e46ebdc5fdf485b328cee32ac7aac/Java/src/com/yourtion/Pattern10/Empty -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern11/MovieService.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern11; 2 | 3 | import com.yourtion.Pattern11.ex1.FavoritesService; 4 | import com.yourtion.Pattern11.ex1.MovieDao; 5 | 6 | /** 7 | * Created by Yourtion on 30/03/2017. 8 | */ 9 | public class MovieService { 10 | 11 | private MovieDao movieDao; 12 | private FavoritesService favoritesService; 13 | public MovieService(MovieDao movieDao, FavoritesService favoritesService){ 14 | this.movieDao = movieDao; 15 | this.favoritesService = favoritesService; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern11/ex1/DecoratedMovie.java: -------------------------------------------------------------------------------- 1 | /*** 2 | * Excerpted from "Functional Programming Patterns", 3 | * published by The Pragmatic Bookshelf. 4 | * Copyrights apply to this code. It may not be used to create training material, 5 | * courses, books, articles, and the like. Contact us if you are in doubt. 6 | * We make no guarantees that this code is fit for any purpose. 7 | * Visit http://www.pragmaticprogrammer.com/titles/mbfpp for more book information. 8 | ***/ 9 | package com.yourtion.Pattern11.ex1; 10 | 11 | public class DecoratedMovie { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern11/ex1/FavoriteVideosService.java: -------------------------------------------------------------------------------- 1 | /*** 2 | * Excerpted from "Functional Programming Patterns", 3 | * published by The Pragmatic Bookshelf. 4 | * Copyrights apply to this code. It may not be used to create training material, 5 | * courses, books, articles, and the like. Contact us if you are in doubt. 6 | * We make no guarantees that this code is fit for any purpose. 7 | * Visit http://www.pragmaticprogrammer.com/titles/mbfpp for more book information. 8 | ***/ 9 | package com.yourtion.Pattern11.ex1; 10 | 11 | public class FavoriteVideosService { 12 | 13 | private VideoService videoService; 14 | private FavoritesService favoritesService; 15 | 16 | private FavoriteVideosService(VideoService videoService, 17 | FavoritesService favoritesService){ 18 | this.videoService = videoService; 19 | this.favoritesService = favoritesService; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern11/ex1/FavoritesService.java: -------------------------------------------------------------------------------- 1 | /*** 2 | * Excerpted from "Functional Programming Patterns", 3 | * published by The Pragmatic Bookshelf. 4 | * Copyrights apply to this code. It may not be used to create training material, 5 | * courses, books, articles, and the like. Contact us if you are in doubt. 6 | * We make no guarantees that this code is fit for any purpose. 7 | * Visit http://www.pragmaticprogrammer.com/titles/mbfpp for more book information. 8 | ***/ 9 | package com.yourtion.Pattern11.ex1; 10 | 11 | public class FavoritesService { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern11/ex1/Movie.java: -------------------------------------------------------------------------------- 1 | /*** 2 | * Excerpted from "Functional Programming Patterns", 3 | * published by The Pragmatic Bookshelf. 4 | * Copyrights apply to this code. It may not be used to create training material, 5 | * courses, books, articles, and the like. Contact us if you are in doubt. 6 | * We make no guarantees that this code is fit for any purpose. 7 | * Visit http://www.pragmaticprogrammer.com/titles/mbfpp for more book information. 8 | ***/ 9 | package com.yourtion.Pattern11.ex1; 10 | 11 | public class Movie { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern11/ex1/MovieDao.java: -------------------------------------------------------------------------------- 1 | /*** 2 | * Excerpted from "Functional Programming Patterns", 3 | * published by The Pragmatic Bookshelf. 4 | * Copyrights apply to this code. It may not be used to create training material, 5 | * courses, books, articles, and the like. Contact us if you are in doubt. 6 | * We make no guarantees that this code is fit for any purpose. 7 | * Visit http://www.pragmaticprogrammer.com/titles/mbfpp for more book information. 8 | ***/ 9 | package com.yourtion.Pattern11.ex1; 10 | 11 | public class MovieDao { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern11/ex1/MovieService.java: -------------------------------------------------------------------------------- 1 | /*** 2 | * Excerpted from "Functional Programming Patterns", 3 | * published by The Pragmatic Bookshelf. 4 | * Copyrights apply to this code. It may not be used to create training material, 5 | * courses, books, articles, and the like. Contact us if you are in doubt. 6 | * We make no guarantees that this code is fit for any purpose. 7 | * Visit http://www.pragmaticprogrammer.com/titles/mbfpp for more book information. 8 | ***/ 9 | package com.yourtion.Pattern11.ex1; 10 | 11 | import java.util.List; 12 | 13 | public abstract class MovieService { 14 | 15 | private FavoriteVideosService favoriteVideosService; 16 | private MovieDao movieDao; 17 | 18 | public MovieService(FavoriteVideosService favoriteVideosService, 19 | MovieDao movieDao) { 20 | this.favoriteVideosService = favoriteVideosService; 21 | this.movieDao = movieDao; 22 | } 23 | 24 | public abstract List getFavoritesMovies(); 25 | public abstract Movie getMovie(); 26 | 27 | } 28 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern11/ex1/VideoService.java: -------------------------------------------------------------------------------- 1 | /*** 2 | * Excerpted from "Functional Programming Patterns", 3 | * published by The Pragmatic Bookshelf. 4 | * Copyrights apply to this code. It may not be used to create training material, 5 | * courses, books, articles, and the like. Contact us if you are in doubt. 6 | * We make no guarantees that this code is fit for any purpose. 7 | * Visit http://www.pragmaticprogrammer.com/titles/mbfpp for more book information. 8 | ***/ 9 | package com.yourtion.Pattern11.ex1; 10 | 11 | public class VideoService { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern12/SumExample.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern12; 2 | 3 | /** 4 | * Created by Yourtion on 31/03/2017. 5 | */ 6 | public class SumExample { 7 | 8 | public static int sum(int upTo) { 9 | int sum = 0; 10 | for (int i = 0; i <= upTo; i++) 11 | sum += i; 12 | return sum; 13 | } 14 | 15 | 16 | public static int sumRecursive(int upTo) { 17 | if (upTo == 0) 18 | return 0; 19 | else 20 | return upTo + sumRecursive(upTo - 1); 21 | } 22 | 23 | 24 | public static int sumTailRecursive(int upTo, int currentSum) { 25 | if (upTo == 0) 26 | return currentSum; 27 | else 28 | return sumTailRecursive(upTo - 1, currentSum + upTo); 29 | } 30 | 31 | public void run() { 32 | System.out.println("sum: " + sum(10)); 33 | System.out.println("sumRecursive: " + sumRecursive(10)); 34 | System.out.println("sumTailRecursive: " + sumTailRecursive(10, 0)); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern13/Empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yourtion/LearningFunctionalProgramming/0ccfffe61b8e46ebdc5fdf485b328cee32ac7aac/Java/src/com/yourtion/Pattern13/Empty -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern14/Empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yourtion/LearningFunctionalProgramming/0ccfffe61b8e46ebdc5fdf485b328cee32ac7aac/Java/src/com/yourtion/Pattern14/Empty -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern15/ChainExample.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern15; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * Created by Yourtion on 01/04/2017. 8 | */ 9 | public class ChainExample { 10 | public void run() { 11 | 12 | System.out.println("PersonExample"); 13 | ImmutablePerson.Builder b = ImmutablePerson.newBuilder(); 14 | ImmutablePerson p = b.firstName("Peter").lastName("Jones").build(); 15 | System.out.println(p.toString()); 16 | 17 | System.out.println(""); 18 | 19 | System.out.println("ListExample"); 20 | List names = new ArrayList(); 21 | names.add("Michael Bevilacqua Linn"); 22 | System.out.println(names); 23 | System.out.println(names.get(0).toUpperCase()); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern15/ImmutablePerson.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern15; 2 | 3 | /** 4 | * Created by Yourtion on 01/04/2017. 5 | */ 6 | public class ImmutablePerson { 7 | 8 | private final String firstName; 9 | private final String lastName; 10 | 11 | public String getFirstName() { 12 | return firstName; 13 | } 14 | 15 | public String getLastName() { 16 | return lastName; 17 | } 18 | 19 | private ImmutablePerson(Builder builder){ 20 | firstName = builder.firstName; 21 | lastName = builder.lastName; 22 | } 23 | 24 | public static class Builder { 25 | private String firstName; 26 | private String lastName; 27 | 28 | public Builder firstName(String firstName) { 29 | this.firstName = firstName; 30 | return this; 31 | } 32 | 33 | public Builder lastName(String lastName) { 34 | this.lastName = lastName; 35 | return this; 36 | } 37 | 38 | public ImmutablePerson build() { 39 | return new ImmutablePerson(this); 40 | } 41 | } 42 | 43 | public static Builder newBuilder() { 44 | return new Builder(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern15/Person.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern15; 2 | 3 | /** 4 | * Created by Yourtion on 01/04/2017. 5 | */ 6 | public class Person { 7 | 8 | private String firstName; 9 | private String lastName; 10 | 11 | public String getFirstName() { 12 | return firstName; 13 | } 14 | 15 | public void setFirstName(String firstName) { 16 | this.firstName = firstName; 17 | } 18 | 19 | public String getLastName() { 20 | return lastName; 21 | } 22 | 23 | public void setLastName(String lastName) { 24 | this.lastName = lastName; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern16/Empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yourtion/LearningFunctionalProgramming/0ccfffe61b8e46ebdc5fdf485b328cee32ac7aac/Java/src/com/yourtion/Pattern16/Empty -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern17/Empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yourtion/LearningFunctionalProgramming/0ccfffe61b8e46ebdc5fdf485b328cee32ac7aac/Java/src/com/yourtion/Pattern17/Empty -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern18/Empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yourtion/LearningFunctionalProgramming/0ccfffe61b8e46ebdc5fdf485b328cee32ac7aac/Java/src/com/yourtion/Pattern18/Empty -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern19/Empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yourtion/LearningFunctionalProgramming/0ccfffe61b8e46ebdc5fdf485b328cee32ac7aac/Java/src/com/yourtion/Pattern19/Empty -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern20/Empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yourtion/LearningFunctionalProgramming/0ccfffe61b8e46ebdc5fdf485b328cee32ac7aac/Java/src/com/yourtion/Pattern20/Empty -------------------------------------------------------------------------------- /Java/src/com/yourtion/Pattern21/Empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yourtion/LearningFunctionalProgramming/0ccfffe61b8e46ebdc5fdf485b328cee32ac7aac/Java/src/com/yourtion/Pattern21/Empty -------------------------------------------------------------------------------- /Java/src/com/yourtion/PatternDemo/Example.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.PatternDemo; 2 | 3 | /** 4 | * Created by Yourtion on 9/7/16. 5 | */ 6 | public class Example { 7 | 8 | public static void main(String[] args){ 9 | System.out.println("\nPattern01 Example : \n"); 10 | new com.yourtion.Pattern01.PersonExample().run(); 11 | System.out.println("------------------------------------"); 12 | 13 | System.out.println("\nPattern02 Example : \n"); 14 | new com.yourtion.Pattern02.PersonExampleCC().run(); 15 | System.out.println("------------------------------------"); 16 | 17 | System.out.println("\nPattern03 Example : \n"); 18 | new com.yourtion.Pattern03.RegisterClient().run(); 19 | System.out.println("------------------------------------"); 20 | 21 | System.out.println("\nPattern04 Example : \n"); 22 | new com.yourtion.Pattern04.PersonHarness().run(); 23 | System.out.println("------------------------------------"); 24 | 25 | System.out.println("\nPattern05 Example : \n"); 26 | new com.yourtion.Pattern05.HigherOrderFunctions().run(); 27 | new com.yourtion.Pattern05.TheLambdaBarAndGrille().run(); 28 | System.out.println("------------------------------------"); 29 | 30 | System.out.println("\nPattern06 Example : \n"); 31 | new com.yourtion.Pattern06.FullGradeReporter().run(); 32 | System.out.println("------------------------------------"); 33 | 34 | System.out.println("\nPattern07 Example : \n"); 35 | new com.yourtion.Pattern07.PersonCollectorExample().run(); 36 | System.out.println("------------------------------------"); 37 | 38 | System.out.println("\nPattern08 Example : \n"); 39 | new com.yourtion.Pattern08.PersonExample().run(); 40 | System.out.println("------------------------------------"); 41 | 42 | System.out.println("\nPattern09 Example : \n"); 43 | new com.yourtion.Pattern09.CalculatorExample().run(); 44 | System.out.println("------------------------------------"); 45 | 46 | System.out.println("\nPattern12 Example : \n"); 47 | new com.yourtion.Pattern12.SumExample().run(); 48 | System.out.println("------------------------------------"); 49 | 50 | System.out.println("\nPattern15 Example : \n"); 51 | new com.yourtion.Pattern15.ChainExample().run(); 52 | System.out.println("------------------------------------"); 53 | 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/TinyWeb/Controller.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.TinyWeb; 2 | 3 | /** 4 | * Created by Yourtion on 9/5/16. 5 | */ 6 | public interface Controller { 7 | 8 | public HttpResponse handleRequest(HttpRequest httpRequest); 9 | 10 | } 11 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/TinyWeb/ControllerException.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.TinyWeb; 2 | 3 | /** 4 | * Created by Yourtion on 9/5/16. 5 | */ 6 | public class ControllerException extends RuntimeException { 7 | private Integer statusCode; 8 | 9 | public ControllerException(Integer statusCode) { 10 | this.statusCode = statusCode; 11 | } 12 | 13 | public Integer getStatusCode() { 14 | return statusCode; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/TinyWeb/Example/ExampleHarness.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.TinyWeb.Example; 2 | 3 | import com.yourtion.TinyWeb.*; 4 | 5 | import java.util.*; 6 | 7 | /** 8 | * Created by Yourtion on 9/5/16. 9 | */ 10 | public class ExampleHarness { 11 | 12 | public static void main(String[] args){ 13 | 14 | TinyWeb tinyWeb = new TinyWeb(makeRoutes(), makeFilters()); 15 | 16 | HttpRequest testRequest = HttpRequest.Builder.newBuilder() 17 | .path("greeting/") 18 | .body("Mike,Joe,John,Steve") 19 | .addHeader("X-Example", "exampleHeader") 20 | .build(); 21 | 22 | HttpResponse testResponse = tinyWeb.handleRequest(testRequest); 23 | 24 | System.out.println("responseCode: " + testResponse.getResponseCode()); 25 | System.out.println("responseBody: "); 26 | System.out.println(testResponse.getBody()); 27 | } 28 | 29 | private static Map makeRoutes(){ 30 | GreetingRenderingStrategy viewRenderer = new GreetingRenderingStrategy(); 31 | StrategyView greetingView = new StrategyView(viewRenderer); 32 | GreetingController greetingController = new GreetingController(greetingView); 33 | 34 | Map controllers = new HashMap(); 35 | controllers.put("greeting/", greetingController); 36 | return Collections.unmodifiableMap(controllers); 37 | } 38 | 39 | private static List makeFilters(){ 40 | List filters = new ArrayList(); 41 | filters.add(new LoggingFilter()); 42 | return filters; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/TinyWeb/Example/GreetingController.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.TinyWeb.Example; 2 | 3 | import com.yourtion.TinyWeb.HttpRequest; 4 | import com.yourtion.TinyWeb.TemplateController; 5 | import com.yourtion.TinyWeb.View; 6 | 7 | import java.util.*; 8 | 9 | /** 10 | * Created by Yourtion on 9/5/16. 11 | */ 12 | public class GreetingController extends TemplateController { 13 | private Random random; 14 | public GreetingController(View view) { 15 | super(view); 16 | random = new Random(); 17 | } 18 | 19 | @Override 20 | public Map> doRequest(HttpRequest httpRequest) { 21 | Map> helloModel = 22 | new HashMap>(); 23 | helloModel.put("greetings", 24 | generateGreetings(httpRequest.getBody())); 25 | return helloModel; 26 | } 27 | 28 | private List generateGreetings(String namesCommaSeparated) { 29 | String[] names = namesCommaSeparated.split(","); 30 | List greetings = new ArrayList(); 31 | for (String name : names) { 32 | greetings.add(makeGreeting(name)); 33 | } 34 | return greetings; 35 | } 36 | 37 | private String makeGreeting(String name) { 38 | String[] greetings = 39 | { "Hello", "Greetings", "Salutations", "Hola" }; 40 | String greetingPrefix = greetings[random.nextInt(4)]; 41 | return String.format("%s, %s", greetingPrefix, name); 42 | } 43 | } 44 | 45 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/TinyWeb/Example/GreetingRenderingStrategy.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.TinyWeb.Example; 2 | 3 | import com.yourtion.TinyWeb.RenderingStrategy; 4 | 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | /** 9 | * Created by Yourtion on 9/5/16. 10 | */ 11 | public class GreetingRenderingStrategy implements RenderingStrategy { 12 | 13 | @Override 14 | public String renderView(Map> model) { 15 | List greetings = model.get("greetings"); 16 | StringBuffer responseBody = new StringBuffer(); 17 | responseBody.append("

Friendly Greetings:

\n"); 18 | for (String greeting : greetings) { 19 | responseBody.append( 20 | String.format("

%s

\n", greeting)); 21 | 22 | } 23 | return responseBody.toString(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/TinyWeb/Example/LoggingFilter.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.TinyWeb.Example; 2 | 3 | import com.yourtion.TinyWeb.Filter; 4 | import com.yourtion.TinyWeb.HttpRequest; 5 | 6 | /** 7 | * Created by Yourtion on 9/5/16. 8 | */ 9 | public class LoggingFilter implements Filter { 10 | 11 | @Override 12 | public HttpRequest doFilter(HttpRequest request) { 13 | System.out.println("In Logging Filter - request for path: " 14 | + request.getPath()); 15 | return request; 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /Java/src/com/yourtion/TinyWeb/Filter.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.TinyWeb; 2 | 3 | /** 4 | * Created by Yourtion on 9/5/16. 5 | */ 6 | public interface Filter { 7 | public HttpRequest doFilter(HttpRequest request); 8 | } 9 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/TinyWeb/HttpRequest.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.TinyWeb; 2 | 3 | import java.util.Collections; 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | 7 | /** 8 | * Created by Yourtion on 9/5/16. 9 | */ 10 | public class HttpRequest { 11 | private Map headers; 12 | private String body; 13 | private String path; 14 | 15 | public Map getHeaders() { 16 | return headers; 17 | } 18 | 19 | public String getBody() { 20 | return body; 21 | } 22 | 23 | public String getPath() { 24 | return path; 25 | } 26 | 27 | private HttpRequest(Builder builder) { 28 | this.headers = Collections.unmodifiableMap(builder.headers); 29 | this.body = builder.body; 30 | this.path = builder.path; 31 | } 32 | 33 | public static class Builder { 34 | private Map headers; 35 | private String body; 36 | private String path; 37 | 38 | private Builder() { 39 | headers = new HashMap(); 40 | } 41 | 42 | public Builder addHeader(String name, String value) { 43 | headers.put(name, value); 44 | return this; 45 | } 46 | 47 | public Builder body(String body) { 48 | this.body = body; 49 | return this; 50 | } 51 | 52 | public Builder path(String path) { 53 | this.path = path; 54 | return this; 55 | } 56 | 57 | public HttpRequest build() { 58 | return new HttpRequest(this); 59 | } 60 | 61 | public static Builder newBuilder() { 62 | return new Builder(); 63 | } 64 | 65 | public static Builder builderFrom(HttpRequest request) { 66 | Builder builder = new Builder(); 67 | builder.path(request.getPath()); 68 | builder.body(request.getBody()); 69 | 70 | Map headers = request.getHeaders(); 71 | for (String headerName : headers.keySet()) 72 | builder.addHeader(headerName, 73 | headers.get(headerName)); 74 | 75 | return builder; 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/TinyWeb/HttpResponse.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.TinyWeb; 2 | 3 | /** 4 | * Created by Yourtion on 9/5/16. 5 | */ 6 | public class HttpResponse { 7 | private final String body; 8 | private final Integer responseCode; 9 | 10 | public String getBody() { 11 | return body; 12 | } 13 | 14 | public Integer getResponseCode() { 15 | return responseCode; 16 | } 17 | 18 | private HttpResponse(Builder builder) { 19 | body = builder.body; 20 | responseCode = builder.responseCode; 21 | } 22 | 23 | public static class Builder { 24 | private String body; 25 | private Integer responseCode; 26 | 27 | public Builder body(String body) { 28 | this.body = body; 29 | return this; 30 | } 31 | 32 | public Builder responseCode(Integer responseCode) { 33 | this.responseCode = responseCode; 34 | return this; 35 | } 36 | 37 | public HttpResponse build() { 38 | return new HttpResponse(this); 39 | } 40 | 41 | public static Builder newBuilder() { 42 | return new Builder(); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/TinyWeb/RenderingException.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.TinyWeb; 2 | 3 | /** 4 | * Created by Yourtion on 9/5/16. 5 | */ 6 | public class RenderingException extends RuntimeException { 7 | 8 | public RenderingException(Exception e) { 9 | super(e); 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/TinyWeb/RenderingStrategy.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.TinyWeb; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | /** 7 | * Created by Yourtion on 9/5/16. 8 | */ 9 | public interface RenderingStrategy { 10 | 11 | public String renderView(Map> model); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/TinyWeb/StrategyView.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.TinyWeb; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | /** 7 | * Created by Yourtion on 9/5/16. 8 | */ 9 | public class StrategyView implements View { 10 | 11 | private RenderingStrategy viewRenderer; 12 | 13 | public StrategyView(RenderingStrategy viewRenderer) { 14 | this.viewRenderer = viewRenderer; 15 | } 16 | 17 | @Override 18 | public String render(Map> model) { 19 | try { 20 | return viewRenderer.renderView(model); 21 | } catch (Exception e) { 22 | throw new RenderingException(e); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/TinyWeb/TemplateController.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.TinyWeb; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | /** 7 | * Created by Yourtion on 9/5/16. 8 | */ 9 | public abstract class TemplateController implements Controller { 10 | private View view; 11 | public TemplateController(View view) { 12 | this.view = view; 13 | } 14 | 15 | public HttpResponse handleRequest(HttpRequest request) { 16 | Integer responseCode = 200; 17 | String responseBody = ""; 18 | 19 | try { 20 | Map> model = doRequest(request); 21 | responseBody = view.render(model); 22 | } catch (ControllerException e) { 23 | responseCode = e.getStatusCode(); 24 | } catch (RenderingException e) { 25 | responseCode = 500; 26 | responseBody = "Exception while rendering."; 27 | } catch (Exception e) { 28 | responseCode = 500; 29 | } 30 | 31 | return HttpResponse.Builder.newBuilder().body(responseBody) 32 | .responseCode(responseCode).build(); 33 | } 34 | protected abstract Map> doRequest(HttpRequest request); 35 | } 36 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/TinyWeb/TinyWeb.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.TinyWeb; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | /** 7 | * Created by Yourtion on 9/5/16. 8 | */ 9 | public class TinyWeb { 10 | private Map controllers; 11 | private List filters; 12 | 13 | public TinyWeb(Map controllers, List filters) { 14 | this.controllers = controllers; 15 | this.filters = filters; 16 | } 17 | 18 | public HttpResponse handleRequest(HttpRequest httpRequest) { 19 | 20 | HttpRequest currentRequest = httpRequest; 21 | for (Filter filter : filters) { 22 | currentRequest = filter.doFilter(currentRequest); 23 | } 24 | 25 | Controller controller = controllers.get(currentRequest.getPath()); 26 | 27 | if (null == controller) 28 | return null; 29 | 30 | return controller.handleRequest(currentRequest); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Java/src/com/yourtion/TinyWeb/View.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.TinyWeb; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | /** 7 | * Created by Yourtion on 9/5/16. 8 | */ 9 | public interface View { 10 | 11 | public String render(Map> model); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 郭宇翔 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Learning Functional Programming 2 | 3 | 《Scala与Clojure函数式编程模式:Java虚拟机高效编程》学习代码记录 4 | 5 | - 模式1 [替代函数式接口](https://github.com/yourtion/LearningFunctionalProgramming/releases/tag/Pattern01) 6 | - 模式2 [替代承载状态的函数式接口](https://github.com/yourtion/LearningFunctionalProgramming/releases/tag/Pattern02) 7 | - 模式3 [替代命令模式](https://github.com/yourtion/LearningFunctionalProgramming/releases/tag/Pattern03) 8 | - 模式4 [替代生成器模式来获得不可变对象](https://github.com/yourtion/LearningFunctionalProgramming/releases/tag/Pattern04) 9 | - 模式5 [替代迭代器模式](https://github.com/yourtion/LearningFunctionalProgramming/releases/tag/Pattern05) 10 | - 模式6 [替代模板方法模式](https://github.com/yourtion/LearningFunctionalProgramming/releases/tag/Pattern06) 11 | - 模式7 [替代策略模式](https://github.com/yourtion/LearningFunctionalProgramming/releases/tag/Pattern07) 12 | - 模式8 [替代空对象](https://github.com/yourtion/LearningFunctionalProgramming/releases/tag/Pattern08) 13 | - 模式9 [替代装饰器模式](https://github.com/yourtion/LearningFunctionalProgramming/releases/tag/Pattern09) 14 | - 模式10 [替代访问者模式](https://github.com/yourtion/LearningFunctionalProgramming/releases/tag/Pattern10) 15 | - 模式11 [替代依赖注入](https://github.com/yourtion/LearningFunctionalProgramming/releases/tag/Pattern11) 16 | - 模式12 [尾递归模式](https://github.com/yourtion/LearningFunctionalProgramming/releases/tag/Pattern12) 17 | - 模式13 [相互递归模式](https://github.com/yourtion/LearningFunctionalProgramming/releases/tag/Pattern13) 18 | - 模式14 [Filter-Map-Reduce模式](https://github.com/yourtion/LearningFunctionalProgramming/releases/tag/Pattern14) 19 | - 模式15 [操作链模式](https://github.com/yourtion/LearningFunctionalProgramming/releases/tag/Pattern15) 20 | - 模式16 [函数生成器模式](https://github.com/yourtion/LearningFunctionalProgramming/releases/tag/Pattern16) 21 | - 模式17 [记忆模式](https://github.com/yourtion/LearningFunctionalProgramming/releases/tag/Pattern17) 22 | - 模式18 [惰性序列模式](https://github.com/yourtion/LearningFunctionalProgramming/releases/tag/Pattern18) 23 | - 模式19 [集中的可变性](https://github.com/yourtion/LearningFunctionalProgramming/releases/tag/Pattern19) 24 | - 模式20 [自定义控制流](https://github.com/yourtion/LearningFunctionalProgramming/releases/tag/Pattern20) 25 | - 模式21 [领域特定语言](https://github.com/yourtion/LearningFunctionalProgramming/releases/tag/Pattern21) 26 | 27 | ## 运行与编译 28 | 29 | 基于 IntelliJ 环境,切换到对应的 [`tag`](https://github.com/yourtion/LearningFunctionalProgramming/releases/) 即可运行相关模式代码,不同代码通过上方运行环境切换。 30 | 31 | ![ScreenShot](ScreenShot.png) 32 | -------------------------------------------------------------------------------- /Scala/Scala.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Scala/src/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Main-Class: Example 3 | 4 | -------------------------------------------------------------------------------- /Scala/src/com/yourtion/Pattern01/PersonExample.scala: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern01 2 | 3 | /** 4 | * Created by Yourtion on 9/7/16. 5 | */ 6 | object PersonExample { 7 | (int1: Int, int2: Int) => int1 + int2 8 | 9 | case class Person(firstName: String, lastName: String) 10 | 11 | val p1 = Person("Michael", "Bevilacqua") 12 | val p2 = Person("Pedro", "Vasquez") 13 | val p3 = Person("Robert", "Aarons") 14 | 15 | val people = Vector(p3, p2, p1) 16 | 17 | val sorted_people = people.sortWith((p1, p2) => p1.firstName < p2.firstName) 18 | 19 | def run() = { 20 | sorted_people.foreach(p => println(p.firstName, p.lastName)) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Scala/src/com/yourtion/Pattern01/PersonExampleEx.scala: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern01 2 | 3 | /** 4 | * Created by Yourtion on 9/7/16. 5 | */ 6 | object PersonExampleEx { 7 | case class Person(firstName: String, middleName: String, lastName: String) 8 | val p1 = Person("Aaron", "Jeffrey", "Smith") 9 | val p2 = Person("Aaron", "Bailey", "Zanthar") 10 | val p3 = Person("Brian", "Adams", "Smith") 11 | val people = Vector(p3, p2, p1) 12 | 13 | def complicatedSort(p1: Person, p2: Person) = 14 | if (p1.firstName != p2.firstName) 15 | p1.firstName < p2.firstName 16 | else if (p1.lastName != p2.lastName) 17 | p1.lastName < p2.lastName 18 | else 19 | p1.middleName < p2.middleName 20 | 21 | def run() = { 22 | people.sortWith(complicatedSort).foreach(p => println(p.firstName, p.middleName, p.lastName)) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Scala/src/com/yourtion/Pattern02/PersonExampleCC.scala: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern02 2 | 3 | /** 4 | * Created by Yourtion on 9/8/16. 5 | */ 6 | object PersonExampleCC { 7 | 8 | case class Person(firstName: String, middleName: String, lastName: String) 9 | 10 | def makeComposedComparison(comparisons: ((Person, Person) => Int)*) = 11 | (p1: Person, p2: Person) => 12 | comparisons.map(cmp => cmp(p1, p2)).find(_ != 0).getOrElse(0) 13 | 14 | def firstNameComparison(p1: Person, p2: Person) = 15 | p1.firstName.compareTo(p2.firstName) 16 | 17 | def lastNameComparison(p1: Person, p2: Person) = 18 | p1.lastName.compareTo(p2.lastName) 19 | 20 | val firstAndLastNameComparison = makeComposedComparison( 21 | firstNameComparison, lastNameComparison 22 | ) 23 | 24 | val p1 = Person("John", "", "Adams") 25 | val p2 = Person("John", "Quincy", "Adams") 26 | 27 | def run() = { 28 | println(firstNameComparison(p1, p2)) 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /Scala/src/com/yourtion/Pattern03/Register.scala: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern03 2 | 3 | /** 4 | * Created by Yourtion on 10/10/2016. 5 | */ 6 | class CashRegister(var total: Int) { 7 | def addCash(toAdd: Int) { 8 | total += toAdd 9 | } 10 | } 11 | 12 | object Register { 13 | def makePurchase(register: CashRegister, amount: Int) = { 14 | () => { 15 | println("-> Purchase in amount: " + amount) 16 | register.addCash(amount) 17 | } 18 | } 19 | 20 | var purchases: Vector[() => Unit] = Vector() 21 | def executePurchase(purchase: () => Unit) = { 22 | purchases = purchases :+ purchase 23 | purchase() 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /Scala/src/com/yourtion/Pattern03/RegisterClient.scala: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern03 2 | 3 | import com.yourtion.Pattern03 4 | 5 | /** 6 | * Created by Yourtion on 10/10/2016. 7 | */ 8 | object RegisterClient { 9 | 10 | def run() = { 11 | val register = new CashRegister(0) 12 | 13 | val purchaseOne = Register.makePurchase(register, 100) 14 | val purchaseTwo = Register.makePurchase(register, 50) 15 | 16 | Register.executePurchase(purchaseOne) 17 | Register.executePurchase(purchaseTwo) 18 | 19 | println("After purchases: " + register.total) 20 | 21 | println("Register reset to 0") 22 | register.total = 0 23 | 24 | for (purchase <- Register.purchases) { 25 | purchase.apply() 26 | } 27 | 28 | println("After replay: " + register.total) 29 | 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Scala/src/com/yourtion/Pattern04/Person.scala: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern04 2 | 3 | /** 4 | * Created by Yourtion on 10/10/2016. 5 | */ 6 | class Person( 7 | val firstName: String, 8 | val middleName: String, 9 | val lastName: String) 10 | { 11 | override def toString: String = "%s %s %s".format(firstName, middleName, lastName) 12 | } 13 | 14 | class PersonWithDefault( 15 | val firstName: String, 16 | val middleName: String = "", 17 | val lastName: String) 18 | { 19 | override def toString: String = "%s %s %s".format(firstName, middleName, lastName) 20 | } 21 | 22 | case class PersonCaseClass( 23 | firstName: String, 24 | middleName: String = "", 25 | lastName: String = "") 26 | { 27 | override def toString: String = "%s %s %s".format(firstName, middleName, lastName) 28 | } 29 | 30 | object PersonHarness { 31 | def run(): Unit = { 32 | println("# simple class with val") 33 | val p1 = new Person("John", "Quincy", "Adams") 34 | println("Person1 is: " + p1.toString) 35 | val p2 = new Person(firstName = "John",middleName = "Quincy",lastName = "Adams") 36 | println("Person2 is: " + p2.toString) 37 | println("Person1 is equals Person2 : " + p1.equals(p2)) 38 | println() 39 | 40 | println("class with Default") 41 | val p3 = new PersonWithDefault(firstName = "Yourtion", lastName = "Guo") 42 | println("Person3 is: " + p3.toString) 43 | val p4 = new PersonWithDefault(firstName = "Yourtion", lastName = "Guo") 44 | println("Person4 is: " + p4.toString) 45 | println("Person3 is equals Person4 : " + p3.equals(p4)) 46 | println() 47 | 48 | println("# case class with Default") 49 | val p5 = PersonCaseClass(firstName = "Yourtion") 50 | println("Person5 is: " + p5.toString) 51 | val p6 = PersonCaseClass(firstName = "Yourtion") 52 | println("Person6 is: " + p6.toString) 53 | println("Person5 is equals Person6 : " + p5.equals(p6)) 54 | val p7 = PersonCaseClass(firstName = "Yourtion", lastName = "Guo") 55 | println("Person7 is: " + p7.toString) 56 | println("Person6 is equals Person7 : " + p6.equals(p7)) 57 | val p8 = p5.copy(lastName = "Guo") 58 | println("Person8 is: " + p7.toString) 59 | println("Person7 is equals Person8 : " + p8.equals(p8)) 60 | 61 | val p9 = p8 match { 62 | case PersonCaseClass(firstName, middleName, lastName) => { 63 | "First: %s - Middle: %s - Last: %s".format(firstName, middleName, lastName) 64 | } 65 | } 66 | println("Person9 is: " + p9.toString) 67 | println() 68 | 69 | println("# use tuple") 70 | def p = ("Yourtion", "Guo") 71 | println("Person is: " + p._1 + " " + p._2 ) 72 | 73 | p match { 74 | case (firstName, lastName) => { 75 | println("First name is: " + firstName) 76 | println("Last name is: " + lastName) 77 | } 78 | } 79 | 80 | 81 | 82 | 83 | } 84 | } -------------------------------------------------------------------------------- /Scala/src/com/yourtion/Pattern05/HigherOrderFunctions.scala: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern05 2 | 3 | /** 4 | * Created by Yourtion on 11/10/2016. 5 | */ 6 | object HigherOrderFunctions { 7 | 8 | def sumSequence(sequence : Seq[Int]) = 9 | if(sequence.isEmpty) 0 else sequence.reduce((acc, curr) => acc + curr) 10 | 11 | def prependHello(names : Seq[String]) = 12 | names.map((name) => "Hello " + name) 13 | 14 | val isVowel = Set('a', 'e', 'i', 'o', 'u') 15 | def vowelsInWord(word: String) = word.filter(isVowel).toSet 16 | 17 | def run(): Unit = { 18 | println("vowelsInWord: " + vowelsInWord("Yourtion")) 19 | println() 20 | 21 | val nameList = Vector("Yourtion", "Sophia") 22 | println("person: " + nameList) 23 | println("prependHello: " + prependHello(nameList)) 24 | println() 25 | 26 | val sequence = Vector(1, 2, 3, 4, 5) 27 | println("sumSequence: "+ sumSequence(sequence)) 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /Scala/src/com/yourtion/Pattern05/TheLambdaBarAndGrille.scala: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern05 2 | 3 | /** 4 | * Created by Yourtion on 11/10/2016. 5 | */ 6 | object TheLambdaBarAndGrille { 7 | 8 | case class Person(name: String, address: Address) 9 | case class Address(zip: Int) 10 | 11 | def generateGreetings(people: Seq[Person]) = 12 | for (Person(name, address) <- people if isCloseZip(address.zip)) 13 | yield "Hello, %s, and welcome to the Lambda Bar And Grille!".format(name) 14 | def isCloseZip(zipCode: Int) = zipCode == 19123 || zipCode == 19103 15 | 16 | def printGreetings(people: Seq[Person]) = 17 | for (Person(name, address) <- people if isCloseZip(address.zip)) 18 | println("Hello, %s, and welcome to the Lambda Bar And Grille!".format(name)) 19 | 20 | def run(): Unit = { 21 | var persons = Seq[Person](); 22 | persons = persons :+ Person("Yourtion1", Address(19123)) 23 | persons = persons :+ Person("Yourtion2", Address(19103)) 24 | persons = persons :+ Person("Yourtion3", Address(19129)) 25 | persons = persons :+ Person("Yourtion4", Address(19103)) 26 | persons = persons :+ Person("Yourtion5", Address(19111)) 27 | 28 | println("All person: " + persons) 29 | println(generateGreetings(persons)) 30 | println("-------------") 31 | printGreetings(persons) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Scala/src/com/yourtion/Pattern06/GradeReporter.scala: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern06 2 | 3 | /** 4 | * Created by Yourtion on 12/10/2016. 5 | */ 6 | object GradeReporter { 7 | 8 | def makeGradeReporter( 9 | numToLetter: (Double) => String, 10 | printGradeReport: (Seq[String]) => Unit) = (grades: Seq[Double]) => { 11 | printGradeReport(grades.map(numToLetter)) 12 | } 13 | 14 | def fullGradeConverter(grade: Double) = 15 | if(grade <= 5.0 && grade > 4.0) "A" 16 | else if(grade <= 4.0 && grade > 3.0) "B" 17 | else if(grade <= 3.0 && grade > 2.0) "C" 18 | else if(grade <= 2.0 && grade > 0.0) "D" 19 | else if(grade == 0.0) "F" 20 | else "N/A" 21 | 22 | def printHistogram(grades: Seq[String]) = { 23 | val grouped = grades.groupBy(identity) 24 | val counts = grouped.map((kv) => (kv._1, kv._2.size)).toSeq.sorted 25 | for(count <- counts) { 26 | val stars = "*" * count._2 27 | println("%s: %s".format(count._1, stars)) 28 | } 29 | } 30 | 31 | def plusMinusGradeConverter(grade: Double) = 32 | if(grade <= 5.0 && grade > 4.7) "A" 33 | else if(grade <= 4.7 && grade > 4.3) "A-" 34 | else if(grade <= 4.3 && grade > 4.0) "B+" 35 | else if(grade <= 4.0 && grade > 3.7) "B" 36 | else if(grade <= 3.7 && grade > 3.3) "B-" 37 | else if(grade <= 3.3 && grade > 3.0) "C+" 38 | else if(grade <= 3.0 && grade > 2.7) "C" 39 | else if(grade <= 2.7 && grade > 2.3) "C-" 40 | else if(grade <= 2.3 && grade > 0.0) "D" 41 | else if(grade == 0.0) "F" 42 | else "N/A" 43 | 44 | def printAllGrades(grades: Seq[String]) = 45 | for(grade <- grades) println("Grade is: " + grade) 46 | 47 | 48 | def run(): Unit = { 49 | val sampleGrades = Vector(5.0, 4.0, 4.4, 2.2, 3.3, 3.5) 50 | 51 | val fullGradeReporter = makeGradeReporter(fullGradeConverter, printHistogram) 52 | 53 | println("FullGradeReporter : ") 54 | fullGradeReporter(sampleGrades) 55 | println() 56 | 57 | val plusMinusGradeReporter = makeGradeReporter(plusMinusGradeConverter, printAllGrades) 58 | 59 | println("PlusMinusGradeReporter :") 60 | plusMinusGradeReporter(sampleGrades) 61 | println() 62 | 63 | } 64 | } -------------------------------------------------------------------------------- /Scala/src/com/yourtion/Pattern07/PersonCollectorExample.scala: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern07 2 | 3 | /** 4 | * Created by Yourtion on 20/10/2016. 5 | */ 6 | object PersonCollectorExample { 7 | case class Person( 8 | firstName: Option[String], 9 | middleName: Option[String], 10 | lastName: Option[String]) 11 | 12 | def isFirstNameValid(person: Person) = person.firstName.isDefined 13 | 14 | def isFullNameValid(person: Person) = person match { 15 | case Person(firstName, middleName, lastName) => 16 | firstName.isDefined && middleName.isDefined && lastName.isDefined 17 | } 18 | 19 | def personCollector(isValid: (Person) => Boolean) = { 20 | var validPeople = Vector[Person]() 21 | (person: Person) => { 22 | if(isValid(person)) validPeople = validPeople :+ person 23 | validPeople 24 | } 25 | } 26 | 27 | def run(): Unit = { 28 | val p1 = Person(Some("Yourtion"), None, Some("Guo")) 29 | val p2 = Person(Some("John"), Some("Quincy"), Some("Adams")) 30 | val p3 = Person(None, Some("John"), Some("Adams")) 31 | val p4 = Person(None, None, None) 32 | 33 | val personCollector1 = personCollector(isFirstNameValid) 34 | var result1 = personCollector1(p1) 35 | result1 = personCollector1(p2) 36 | result1 = personCollector1(p3) 37 | result1 = personCollector1(p4) 38 | println("FirstNameValidator Collector list :") 39 | println(result1) 40 | 41 | println() 42 | 43 | val personCollector2 = personCollector(isFullNameValid) 44 | var result2 = personCollector2(p1) 45 | result2 = personCollector2(p2) 46 | result2 = personCollector2(p3) 47 | result2 = personCollector2(p4) 48 | println("FullNameValidator Collector list :") 49 | println(result2) 50 | 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Scala/src/com/yourtion/Pattern08/PersonExamples.scala: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern08 2 | 3 | /** 4 | * Created by Yourtion on 23/11/2016. 5 | */ 6 | object PersonExamples { 7 | case class Person(firstName: String="John", lastName: String="Doe") 8 | val nullPerson = Person() 9 | 10 | def fetchPerson(people: Map[Int, Person], id: Int) = 11 | people.getOrElse(id, nullPerson) 12 | 13 | def buildPerson(firstNameOption: Option[String], lastNameOption: Option[String]) = 14 | (for( 15 | firstName <- firstNameOption; 16 | lastName <- lastNameOption) 17 | yield Person(firstName, lastName)).getOrElse(Person("John", "Doe")) 18 | 19 | 20 | def run(): Unit = { 21 | println("BuildPerson :") 22 | 23 | println("Not null: ", buildPerson(Option("Yourtion"),Option("Guo"))) 24 | println("Null firstlast name: ", buildPerson(None,Option("Guo"))) 25 | println("Null last name: ", buildPerson(Option("Yourtion"),None)) 26 | 27 | val yourtion = Person("Yourtion", "Guo") 28 | val somePeople = Map(1 -> yourtion) 29 | 30 | println() 31 | println("FetchPerson :") 32 | 33 | println("Not null: ", fetchPerson(somePeople,1)) 34 | println("Null: ", fetchPerson(somePeople,2)) 35 | 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Scala/src/com/yourtion/Pattern09/CalculatorExample.scala: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern09 2 | 3 | /** 4 | * Created by Yourtion on 28/11/2016. 5 | */ 6 | object CalculatorExample { 7 | 8 | def add(a: Int, b: Int) = a + b 9 | def subtract(a: Int, b: Int) = a - b 10 | def multiply(a: Int, b: Int) = a * b 11 | def divide(a: Int, b: Int) = a / b 12 | 13 | def makeLogger(calcFn: (Int, Int) => Int) = 14 | (a: Int, b: Int) => { 15 | val result = calcFn(a, b) 16 | println("Result is: " + result) 17 | result 18 | } 19 | 20 | val loggingAdd = makeLogger(add) 21 | val loggingSubtract = makeLogger(subtract) 22 | val loggingMultiply = makeLogger(multiply) 23 | val loggingDivide = makeLogger(divide) 24 | 25 | def run(): Unit = { 26 | println("Without Logging :") 27 | 28 | println(add(1,2)) 29 | println(subtract(4,3)) 30 | println(divide(6,2)) 31 | println(multiply(2,3)) 32 | 33 | println() 34 | println("Logging :") 35 | println(loggingAdd(1,2)) 36 | println(loggingSubtract(4,3)) 37 | println(loggingDivide(6,2)) 38 | println(loggingMultiply(2,3)) 39 | 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /Scala/src/com/yourtion/Pattern10/VisitorExample.scala: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern10 2 | 3 | /** 4 | * Created by Yourtion on 29/03/2017. 5 | */ 6 | object VisitorExample { 7 | 8 | trait Person { 9 | def fullName: String 10 | def firstName: String 11 | def lastName: String 12 | def houseNum: Int 13 | def street: String 14 | } 15 | 16 | class SimplePerson(val firstName: String, val lastName: String, 17 | val houseNum: Int, val street: String) extends Person { 18 | def fullName = firstName + " " + lastName 19 | } 20 | 21 | class ComplexPerson(name: Name, address: Address) extends Person { 22 | def fullName = name.firstName + " " + name.lastName 23 | 24 | def firstName = name.firstName 25 | def lastName = name.lastName 26 | def houseNum = address.houseNum 27 | def street = address.street 28 | } 29 | class Address(val houseNum: Int, val street: String) 30 | class Name(val firstName: String, val lastName: String) 31 | 32 | implicit class ExtendedPerson(person: Person) { 33 | def fullAddress = person.houseNum + " " + person.street 34 | } 35 | 36 | 37 | trait PerimeterShapes { 38 | trait Shape { 39 | def perimeter: Double 40 | } 41 | 42 | class Circle(radius: Double) extends Shape { 43 | def perimeter = 2 * Math.PI * radius 44 | } 45 | 46 | class Rectangle(width: Double, height: Double) extends Shape { 47 | def perimeter = 2 * width + 2 * height 48 | } 49 | } 50 | 51 | object FirstShapeExample extends PerimeterShapes { 52 | val aCircle = new Circle(4) 53 | val aRectangle = new Rectangle(2, 2) 54 | } 55 | 56 | trait AreaShapes extends PerimeterShapes { 57 | trait Shape extends super.Shape { 58 | def area: Double 59 | } 60 | 61 | class Circle(radius: Double) extends super.Circle(radius) with Shape { 62 | def area = Math.PI * radius * radius 63 | } 64 | 65 | class Rectangle(width: Double, height: Double) 66 | extends super.Rectangle(width, height) with Shape { 67 | def area = width * height 68 | } 69 | } 70 | 71 | object SecondShapeExample extends AreaShapes { 72 | val someShapes = Vector(new Circle(4), new Rectangle(2, 2)) 73 | } 74 | 75 | trait MorePerimeterShapes extends PerimeterShapes { 76 | class Square(side: Double) extends Shape { 77 | def perimeter = 4 * side 78 | } 79 | } 80 | 81 | trait MoreAreaShapes extends AreaShapes with MorePerimeterShapes { 82 | class Square(side: Double) extends super.Square(side) with Shape { 83 | def area = side * side 84 | } 85 | } 86 | 87 | object ThirdShapeExample extends MoreAreaShapes { 88 | val someMoreShapes = Vector(new Circle(4), new Rectangle(2, 2), new Square(4)) 89 | } 90 | 91 | def run(): Unit = { 92 | println("SimplePerson :") 93 | 94 | val simplePerson = new SimplePerson("Yourtion", "Guo", 123, "Fake. St.") 95 | println(simplePerson) 96 | println("FullName:" + simplePerson.fullName) 97 | println("FullAddress:" + simplePerson.fullAddress) 98 | println() 99 | 100 | println("ComplexPerson :") 101 | val name = new Name("yourtion", "guo") 102 | val address = new Address(456, "Fake2. St.") 103 | val complexPerson = new ComplexPerson(name, address) 104 | println("FullName:" + complexPerson.fullName) 105 | println("FullAddress:" + complexPerson.fullAddress) 106 | println() 107 | 108 | 109 | println("FirstShapeExample :") 110 | println(FirstShapeExample.aCircle.perimeter) 111 | println(FirstShapeExample.aRectangle.perimeter) 112 | println() 113 | 114 | println("SecondShapeExample :") 115 | println(for(shape <- SecondShapeExample.someShapes) yield shape.perimeter) 116 | println(for(shape <- SecondShapeExample.someShapes) yield shape.area) 117 | println() 118 | 119 | println("ThirdShapeExample :") 120 | println(for(shape <- ThirdShapeExample.someMoreShapes) yield shape.perimeter) 121 | println(for(shape <- ThirdShapeExample.someMoreShapes) yield shape.area) 122 | println() 123 | } 124 | 125 | } 126 | -------------------------------------------------------------------------------- /Scala/src/com/yourtion/Pattern11/Services.scala: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern11 2 | 3 | /** 4 | * Created by Yourtion on 30/03/2017. 5 | */ 6 | object Services { 7 | case class Movie(movieId: String, title: String) 8 | case class Video(movieId: String) 9 | case class DecoratedMovie(movie: Movie, video: Video) 10 | 11 | trait MovieDaoComponent { 12 | trait MovieDao { 13 | def getMovie(id: String): Movie 14 | } 15 | } 16 | 17 | trait FavoritesServiceComponent { 18 | trait FavoritesService { 19 | def getFavoriteVideos(id: String): Vector[Video] 20 | } 21 | } 22 | 23 | trait MovieDaoComponentImpl extends MovieDaoComponent { 24 | class MovieDaoImpl extends MovieDao { 25 | def getMovie(id: String): Movie = new Movie("42", "A Movie") 26 | } 27 | } 28 | 29 | trait FavoritesServiceComponentImpl extends FavoritesServiceComponent { 30 | class FavoritesServiceImpl extends FavoritesService { 31 | def getFavoriteVideos(id: String): Vector[Video] = Vector(new Video("1")) 32 | } 33 | } 34 | 35 | trait MovieServiceComponentImpl { 36 | this: MovieDaoComponent with FavoritesServiceComponent => 37 | 38 | val favoritesService: FavoritesService 39 | val movieDao: MovieDao 40 | 41 | class MovieServiceImpl { 42 | def getFavoriteDecoratedMovies(userId: String): Vector[DecoratedMovie] = 43 | for ( 44 | favoriteVideo <- favoritesService.getFavoriteVideos(userId); 45 | movie = movieDao.getMovie(favoriteVideo.movieId) 46 | ) yield DecoratedMovie(movie, favoriteVideo) 47 | } 48 | } 49 | 50 | object ComponentRegistry extends MovieServiceComponentImpl 51 | with FavoritesServiceComponentImpl with MovieDaoComponentImpl { 52 | val favoritesService = new FavoritesServiceImpl 53 | val movieDao = new MovieDaoImpl 54 | 55 | val movieService = new MovieServiceImpl 56 | } 57 | 58 | trait MovieDaoComponentTestImpl extends MovieDaoComponent { 59 | class MovieDaoTestImpl extends MovieDao { 60 | def getMovie(id: String): Movie = new Movie("43", "A Test Movie") 61 | } 62 | } 63 | 64 | trait FavoritesServiceComponentTestImpl extends FavoritesServiceComponent { 65 | class FavoritesServiceTestImpl extends FavoritesService { 66 | def getFavoriteVideos(id: String): Vector[Video] = Vector(new Video("2")) 67 | } 68 | } 69 | 70 | object TestComponentRegistery extends MovieServiceComponentImpl 71 | with FavoritesServiceComponentTestImpl with MovieDaoComponentTestImpl { 72 | val favoritesService = new FavoritesServiceTestImpl 73 | val movieDao = new MovieDaoTestImpl 74 | 75 | val movieService = new MovieServiceImpl 76 | } 77 | 78 | def run(): Unit = { 79 | println("Moke :") 80 | for(moive <- TestComponentRegistery.favoritesService.getFavoriteVideos("2")) yield println(moive) 81 | println(TestComponentRegistery.movieDao.getMovie("43")) 82 | println() 83 | 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /Scala/src/com/yourtion/Pattern12/Names.scala: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern12 2 | import scala.annotation.tailrec 3 | 4 | /** 5 | * Created by Yourtion on 31/03/2017. 6 | */ 7 | object Names { 8 | 9 | case class Person(firstNames: String, lastNames: String) 10 | 11 | /* 12 | val makePeople = (firstNames: Seq[String], lastNames: Seq[String]) => { 13 | @tailrec 14 | lazy val helper: (Seq[String], Seq[String], Vector[Person]) => Seq[Person] = 15 | (firstNames: Seq[String], lastNames: Seq[String], people: Vector[Person]) => { 16 | if (firstNames.isEmpty) 17 | people 18 | else { 19 | val newPerson = Person(firstNames.head, lastNames.head) 20 | helper(firstNames.tail, lastNames.tail, people :+ newPerson) 21 | } 22 | } 23 | 24 | helper(firstNames, lastNames, Vector[Person]()) 25 | }*/ 26 | 27 | def makePeople(firstNames: Seq[String], lastNames: Seq[String]) = { 28 | @tailrec 29 | def helper(firstNames: Seq[String], lastNames: Seq[String], 30 | people: Vector[Person]): Seq[Person] = 31 | if (firstNames.isEmpty) 32 | people 33 | else { 34 | val newPerson = Person(firstNames.head, lastNames.head) 35 | helper(firstNames.tail, lastNames.tail, people :+ newPerson) 36 | } 37 | helper(firstNames, lastNames, Vector[Person]()) 38 | } 39 | 40 | def run(): Unit = { 41 | println("MakePeople :") 42 | 43 | val people = makePeople(Seq("Yourtion1", "Yourtion2"), Seq("Guo1", "Guo2")) 44 | for(p <- people) yield println(p) 45 | 46 | println() 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Scala/src/com/yourtion/Pattern13/MutualRecursionExample.scala: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern13 2 | 3 | import com.yourtion.Pattern13.Phases._ 4 | 5 | import scala.util.control.TailCalls._ 6 | 7 | /** 8 | * Created by Yourtion on 01/04/2017. 9 | */ 10 | 11 | object EvenOdd { 12 | 13 | def isOdd(n: Long): Boolean = if (n == 0) false else isEven(n - 1) 14 | 15 | def isEven(n: Long): Boolean = if (n == 0) true else isOdd(n - 1) 16 | 17 | def isOddTrampoline(n: Long): TailRec[Boolean] = 18 | if (n == 0) done(false) else tailcall(isEvenTrampoline(n - 1)) 19 | 20 | def isEvenTrampoline(n: Long): TailRec[Boolean] = 21 | if (n == 0) done(true) else tailcall(isOddTrampoline(n - 1)) 22 | } 23 | 24 | object Phases { 25 | class Transition 26 | case object Ionization extends Transition 27 | case object Deionization extends Transition 28 | case object Vaporization extends Transition 29 | case object Condensation extends Transition 30 | case object Freezing extends Transition 31 | case object Melting extends Transition 32 | case object Sublimation extends Transition 33 | case object Deposition extends Transition 34 | 35 | def plasma(transitions: List[Transition]): TailRec[Boolean] = transitions match { 36 | case Nil => done(true) 37 | case Deionization :: restTransitions => tailcall(vapor(restTransitions)) 38 | case _ => done(false) 39 | } 40 | def vapor(transitions: List[Transition]): TailRec[Boolean] = transitions match { 41 | case Nil => done(true) 42 | case Condensation :: restTransitions => tailcall(liquid(restTransitions)) 43 | case Deposition :: restTransitions => tailcall(solid(restTransitions)) 44 | case Ionization :: restTransitions => tailcall(plasma(restTransitions)) 45 | case _ => done(false) 46 | } 47 | 48 | def liquid(transitions: List[Transition]): TailRec[Boolean] = transitions match { 49 | case Nil => done(true) 50 | case Vaporization :: restTransitions => tailcall(vapor(restTransitions)) 51 | case Freezing :: restTransitions => tailcall(solid(restTransitions)) 52 | case _ => done(false) 53 | } 54 | 55 | def solid(transitions: List[Transition]): TailRec[Boolean] = transitions match { 56 | case Nil => done(true) 57 | case Melting :: restTransitions => tailcall(liquid(restTransitions)) 58 | case Sublimation :: restTransitions => tailcall(vapor(restTransitions)) 59 | case _ => done(false) 60 | } 61 | 62 | } 63 | 64 | object MutualRecursionExample { 65 | def run(): Unit = { 66 | println("Odd or Even :") 67 | 68 | println(EvenOdd.isEvenTrampoline(0).result) 69 | println(EvenOdd.isOddTrampoline(0).result) 70 | println(EvenOdd.isOddTrampoline(1000).result) 71 | println() 72 | 73 | println("Phases :") 74 | val validSequence = List(Melting, Vaporization, Ionization, Deionization) 75 | println("solid: " + solid(validSequence).result) 76 | 77 | val invalidSequence = List(Vaporization, Freezing) 78 | println("liquid: " + liquid(invalidSequence).result) 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /Scala/src/com/yourtion/Pattern14/DiscountExample.scala: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern14 2 | 3 | /** 4 | * Created by Yourtion on 01/04/2017. 5 | */ 6 | object DiscountExample { 7 | def calculateDiscount(prices : Seq[Double]) : Double = { 8 | prices filter(price => price >= 20.0) map 9 | (price => price * 0.10) reduce 10 | ((total, price) => total + price) 11 | } 12 | 13 | def calculateDiscountNamedFn(prices : Seq[Double]) : Double = { 14 | def isGreaterThan20(price : Double) = price >= 20.0 15 | def tenPercent(price : Double) = price * 0.10 16 | def sumPrices(total: Double, price : Double) = total + price 17 | 18 | prices filter isGreaterThan20 map tenPercent reduce sumPrices 19 | } 20 | 21 | def run(): Unit = { 22 | println("Discount :") 23 | 24 | println("calculateDiscount : " + calculateDiscount(Vector(20.0, 4.5, 50.0, 15.75, 30.0, 3.5))) 25 | println("calculateDiscountNamedFn : " +calculateDiscountNamedFn(Vector(20.0, 4.5, 50.0, 15.75, 30.0, 3.5))) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Scala/src/com/yourtion/Pattern15/ChainExample.scala: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern15 2 | 3 | /** 4 | * Created by Yourtion on 01/04/2017. 5 | */ 6 | object ChainExample { 7 | 8 | val name = "michael bevilacqua linn" 9 | val initials = name.split(" ") map (_.toUpperCase) map (_.charAt(0)) mkString 10 | 11 | case class Video(title: String, video_type: String, length: Int) 12 | 13 | def catTime(videos: Vector[Video]) = 14 | videos. 15 | filter((video) => video.video_type == "cat"). 16 | map((video) => video.length). 17 | sum 18 | 19 | val vec1 = Vector(42) 20 | val vec2 = Vector(8) 21 | 22 | for { i1 <- vec1; i2 <- vec2 } yield(i1 + i2) 23 | 24 | val o1 = Some(42) 25 | val o2 = Some(8) 26 | 27 | for { v1 <- o1; v2 <- o2 } yield(v1 + v2) 28 | 29 | val o3: Option[Int] = None 30 | 31 | for { v1 <- o1; v3 <- o3 } yield(v1 + v3) 32 | 33 | case class User(name: String, id: String) 34 | case class Movie(name: String, id: String) 35 | 36 | def getUserById(id: String) = id match { 37 | case "1" => Some(User("Mike", "1")) 38 | case _ => None 39 | } 40 | 41 | def getFavoriteMovieForUser(user: User) = user match { 42 | case User(_, "1") => Some(Movie("Gigli", "101")) 43 | case _ => None 44 | } 45 | 46 | def getVideosForMovie(movie: Movie) = movie match { 47 | case Movie(_, "101") => 48 | Some(Vector( 49 | Video("Interview With Cast", "interview", 480), 50 | Video("Gigli", "feature", 7260))) 51 | case _ => None 52 | } 53 | 54 | def getFavoriteVideos(userId: String) = 55 | for { 56 | user <- getUserById(userId) 57 | favoriteMovie <- getFavoriteMovieForUser(user) 58 | favoriteVideos <- getVideosForMovie(favoriteMovie) 59 | } yield favoriteVideos 60 | 61 | def run(): Unit = { 62 | println("Videos :") 63 | val v1 = Video("Pianocat Plays Carnegie Hall", "cat", 300) 64 | val v2 = Video("Paint Drying", "home-improvement", 600) 65 | val v3 = Video("Fuzzy McMittens Live At The Apollo", "cat", 200) 66 | 67 | val videos = Vector(v1, v2, v3) 68 | println("catTime: " + catTime(videos)) 69 | println() 70 | 71 | println("getFavoriteVideos") 72 | println(getFavoriteVideos("1")) 73 | 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Scala/src/com/yourtion/Pattern16/CompositionExamples.scala: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern16 2 | 3 | /** 4 | * Created by Yourtion on 05/04/2017. 5 | */ 6 | object CompositionExamples { 7 | 8 | val appendA = (s: String) => s + "a" 9 | val appendB = (s: String) => s + "b" 10 | val appendC = (s: String) => s + "c" 11 | 12 | case class HttpRequest( 13 | headers: Map[String, String], 14 | payload: String, 15 | principal: Option[String] = None) 16 | 17 | def checkAuthorization(request: HttpRequest) = { 18 | val authHeader = request.headers.get("Authorization") 19 | val mockPrincipal = authHeader match { 20 | case Some(headerValue) => Some("AUser") 21 | case _ => None 22 | } 23 | request.copy(principal = mockPrincipal) 24 | } 25 | def logFingerprint(request: HttpRequest) = { 26 | val fingerprint = request.headers.getOrElse("X-RequestFingerprint", "") 27 | println("FINGERPRINT=" + fingerprint) 28 | request 29 | } 30 | 31 | def composeFilters(filters: Seq[Function1[HttpRequest, HttpRequest]]) = 32 | filters.reduce { 33 | (allFilters, currentFilter) => allFilters compose currentFilter 34 | } 35 | 36 | def run(): Unit = { 37 | println("CompositionExamples :") 38 | val appendCBA = appendA compose appendB compose appendC 39 | println("appendA + appendB + appendC: " + appendCBA("z")) 40 | println() 41 | 42 | val filterChain = composeFilters(Vector(checkAuthorization, logFingerprint)) 43 | val requestHeader = Map("Authorization" -> "Auth", "X-RequestFingerprint" -> "fingerprint") 44 | val request = HttpRequest(requestHeader, "body") 45 | println("FilterChain: " + filterChain(request)) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Scala/src/com/yourtion/Pattern16/DiscountBuilder.scala: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern16 2 | 3 | /** 4 | * Created by Yourtion on 05/04/2017. 5 | */ 6 | object DiscountBuilder { 7 | 8 | def discount(percent: Double) = { 9 | if(percent < 0.0 || percent > 100.0) 10 | throw new IllegalArgumentException("Discounts must be between 0.0 and 100.0.") 11 | (originalPrice: Double) => 12 | originalPrice - (originalPrice * percent * 0.01) 13 | } 14 | 15 | def run(): Unit = { 16 | println("DiscountBuilder :") 17 | println("200 50% discount -> " + discount(50)(200)) 18 | println("200 0% discount -> " + discount(0)(200)) 19 | println("200 100% discount -> " + discount(100)(200)) 20 | val twentyFivePercentOff = discount(25) 21 | println("Multi1 : " + (Vector(100.0, 25.0, 50.0, 25.0) map twentyFivePercentOff sum)) 22 | println("Multi2 : " + (Vector(75.0, 25.0) map twentyFivePercentOff sum)) 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /Scala/src/com/yourtion/Pattern16/FunctionBuilderExample.scala: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern16 2 | 3 | /** 4 | * Created by Yourtion on 05/04/2017. 5 | */ 6 | 7 | object FunctionBuilderExample { 8 | def run(): Unit = { 9 | DiscountBuilder.run() 10 | println() 11 | SelectorExample.run() 12 | println() 13 | CompositionExamples.run() 14 | println() 15 | PartialExamples.run() 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Scala/src/com/yourtion/Pattern16/PartialExamples.scala: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern16 2 | 3 | /** 4 | * Created by Yourtion on 05/04/2017. 5 | */ 6 | object PartialExamples { 7 | 8 | def addTwoInts(intOne: Int, intTwo: Int) = intOne + intTwo 9 | 10 | def taxForState(amount: Double, state: Symbol) = state match { 11 | // Simple tax logic, for example only! 12 | case ('NY) => amount * 0.0645 13 | case ('PA) => amount * 0.045 14 | // Rest of states... 15 | } 16 | 17 | def run(): Unit = { 18 | println("PartialExamples :") 19 | val addFortyTwo = addTwoInts(42, _: Int) 20 | println("100 addFortyTwo: " + addFortyTwo(100)) 21 | 22 | val nyTax = taxForState(_: Double, 'NY) 23 | println("nyTax 100 : " + nyTax(100)) 24 | 25 | val paTax = taxForState(_: Double, 'PA) 26 | println("paTax 100 : " + paTax(100)) 27 | 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /Scala/src/com/yourtion/Pattern16/SelectorExample.scala: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern16 2 | 3 | import scala.annotation.tailrec 4 | import scala.collection.immutable.Map 5 | 6 | /** 7 | * Created by Yourtion on 05/04/2017. 8 | */ 9 | object SelectorExample { 10 | 11 | def selector(path: Symbol*): (Map[Symbol, Any] => Option[Any]) = { 12 | 13 | if(path.size <= 0) throw new IllegalArgumentException("path must not be empty") 14 | 15 | @tailrec 16 | def selectorHelper(path: Seq[Symbol], ds: Map[Symbol, Any]): Option[Any] = 17 | if(path.size == 1) { 18 | ds.get(path(0)) 19 | }else{ 20 | val currentPiece = ds.get(path.head) 21 | currentPiece match { 22 | case Some(currentMap: Map[Symbol, Any]) => 23 | selectorHelper(path.tail, currentMap) 24 | case None => None 25 | case _ => None 26 | } 27 | } 28 | 29 | (ds: Map[Symbol, Any]) => selectorHelper(path.toSeq, ds) 30 | } 31 | 32 | def run(): Unit = { 33 | println("SelectorExample :") 34 | val simplePerspon = Map('name -> "Yourtion Guo") 35 | val name = selector('name) 36 | println("name from simplePerson: " + name(simplePerspon)) 37 | val moreComplexPerson = Map('name -> Map('First -> "Yourtion", 'last -> "Guo")) 38 | val firstName = selector('name, 'first) 39 | println("firstName from moreComplexPerson: " + firstName(moreComplexPerson)) 40 | val middleName = selector('name, 'middle) 41 | println("middleName from moreComplexPerson: " + middleName(moreComplexPerson)) 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /Scala/src/com/yourtion/Pattern17/MemoizationExample.scala: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern17 2 | 3 | /** 4 | * Created by Yourtion on 06/04/2017. 5 | */ 6 | object MemoizationExample { 7 | 8 | def expensiveLookup(id: Int) = { 9 | Thread.sleep(1000) 10 | println(s"Doing expensive lookup for $id") 11 | Map(42 -> "foo", 12 -> "bar", 1 -> "baz").get(id) 12 | } 13 | 14 | def memoizeExpensiveLookup() = { 15 | var cache = Map[Int, Option[String]]() 16 | (id: Int) => 17 | cache.get(id) match { 18 | case Some(result: Option[String]) => result 19 | case None => { 20 | val result = expensiveLookup(id) 21 | cache += id -> result 22 | result 23 | } 24 | } 25 | } 26 | 27 | 28 | def run(): Unit = { 29 | println("Expensive lookup :") 30 | println("One: " + expensiveLookup(42)) 31 | println("Two: " + expensiveLookup(42)) 32 | 33 | println("Memoize lookup :") 34 | val memoizedExpensiveLookup = memoizeExpensiveLookup 35 | println("One: " + memoizedExpensiveLookup(42)) 36 | println("Two: " + memoizedExpensiveLookup(42)) 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /Scala/src/com/yourtion/Pattern18/LazySequenceExample.scala: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern18 2 | 3 | import scala.util.Random 4 | 5 | /** 6 | * Created by Yourtion on 06/04/2017. 7 | */ 8 | object LazySequenceExample { 9 | 10 | val integers = Stream.from(0) 11 | 12 | val generate = new Random() 13 | val randoms = Stream.continually(generate.nextInt) 14 | 15 | def pagedSequence(pageNum: Int): Stream[String] = 16 | getPage(pageNum) match { 17 | case Some(page: String) => page #:: pagedSequence(pageNum + 1) 18 | case None => Stream.Empty 19 | } 20 | 21 | def getPage(page: Int) = 22 | page match { 23 | case 1 => Some("Page1") 24 | case 2 => Some("Page2") 25 | case 3 => Some("Page3") 26 | case _ => None 27 | } 28 | 29 | def run(): Unit = { 30 | println("Some Ints :") 31 | val someints = integers take 5 32 | someints foreach println 33 | println() 34 | 35 | println("aFewRabdom :") 36 | val aFewRabdom = randoms take 5 37 | aFewRabdom foreach println 38 | println() 39 | 40 | println("aFewMoreRabdom :") 41 | val aFewMoreRabdom = randoms take 6 42 | aFewMoreRabdom foreach println 43 | println() 44 | 45 | println("print Hello :") 46 | val printHellos = Stream.continually(println("hello")) 47 | println(printHellos take 5 ) 48 | println() 49 | println(printHellos take 5 force) 50 | println() 51 | 52 | println("aStream head :") 53 | val aStream = "foo" #:: "bar" #:: Stream[String]() 54 | println("Head:" + aStream.head) 55 | println("Tail: " + aStream.tail) 56 | println() 57 | 58 | println("pages :") 59 | println(pagedSequence(1) take 2 force) 60 | println(pagedSequence(1) force) 61 | println() 62 | 63 | val holdsHead = { 64 | def pagedSequence(pageNum: Int): Stream[String] = 65 | getPage(pageNum) match { 66 | case Some(page: String) => { 67 | println("Realizing " + page) 68 | page #:: pagedSequence(pageNum + 1) 69 | } 70 | case None => Stream.Empty 71 | } 72 | pagedSequence(1) 73 | } 74 | 75 | println("holdsHead :") 76 | println(holdsHead force) 77 | println() 78 | 79 | def doesntHoldHead = { 80 | def pagedSequence(pageNum: Int): Stream[String] = 81 | getPage(pageNum) match { 82 | case Some(page: String) => { 83 | println("Realizing " + page) 84 | page #:: pagedSequence(pageNum + 1) 85 | } 86 | case None => Stream.Empty 87 | } 88 | pagedSequence(1) 89 | } 90 | println("doesntHoldHead :") 91 | println(doesntHoldHead force) 92 | println() 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /Scala/src/com/yourtion/Pattern19/FocusedMutationExample.scala: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern19 2 | 3 | import scala.collection.immutable.Stream 4 | import scala.collection.{IndexedSeq, immutable, mutable} 5 | import scala.collection.mutable.ArrayBuffer 6 | import scala.util.Random 7 | 8 | /** 9 | * Created by Yourtion on 06/04/2017. 10 | */ 11 | object FocusedMutationExample { 12 | case class Purchase(storeNumber: Int, customerNumber: Int, itemNumber: Int) 13 | 14 | val r = new Random 15 | def makeTestPurchase = Purchase(r.nextInt(100), r.nextInt(1000), r.nextInt(500)) 16 | def infiniteTestPurchases: Stream[Purchase] = 17 | makeTestPurchase #:: infiniteTestPurchases 18 | 19 | val oneHundredThousand = 100000 20 | val fiveHundredThousand = 500000 21 | 22 | def immutableSequenceEventProcessing(count: Int) = { 23 | val testPurchases = infiniteTestPurchases.take(count) 24 | var mapOfPurchases = immutable.Map[Int, List[Purchase]]() 25 | 26 | for (purchase <- testPurchases) 27 | mapOfPurchases.get(purchase.storeNumber) match { 28 | case None => mapOfPurchases = 29 | mapOfPurchases + (purchase.storeNumber -> List(purchase)) 30 | case Some(existing: List[Purchase]) => mapOfPurchases = 31 | mapOfPurchases + (purchase.storeNumber -> (purchase :: existing)) 32 | } 33 | } 34 | 35 | def immutableSequenceEventProcessingFoldl(count: Int) = { 36 | val testPurchases = infiniteTestPurchases.take(count) 37 | var mapOfPurchases = immutable.Map[Int, List[Purchase]]() 38 | 39 | for (purchase <- testPurchases) 40 | mapOfPurchases.get(purchase.storeNumber) match { 41 | case None => mapOfPurchases = 42 | mapOfPurchases + (purchase.storeNumber -> List(purchase)) 43 | case Some(existing: List[Purchase]) => mapOfPurchases = 44 | mapOfPurchases + (purchase.storeNumber -> (purchase :: existing)) 45 | } 46 | } 47 | 48 | 49 | def mutableSequenceEventProcessing(count: Int) = { 50 | val testPurchases = infiniteTestPurchases.take(count) 51 | val mapOfPurchases = mutable.Map[Int, List[Purchase]]() 52 | 53 | for (purchase <- testPurchases) 54 | mapOfPurchases.get(purchase.storeNumber) match { 55 | case None => mapOfPurchases.put(purchase.storeNumber, List(purchase)) 56 | case Some(existing: List[Purchase]) => 57 | mapOfPurchases.put(purchase.storeNumber, (purchase :: existing)) 58 | } 59 | 60 | mapOfPurchases.toMap 61 | } 62 | 63 | def time[R](block: => R): R = { 64 | val start = System.nanoTime 65 | val result = block 66 | val end = System.nanoTime 67 | val elapsedTimeMs = (end - start) * 0.000001 68 | println("Elapsed time: %.3f msecs".format(elapsedTimeMs)) 69 | result 70 | } 71 | 72 | def timeRuns[R](block: => R, count: Int) = 73 | for (_ <- Range(0, count)) time { block } 74 | 75 | def testImmutable(count: Int): IndexedSeq[Int] = { 76 | var v = Vector[Int]() 77 | for (c <- Range(0, count)) 78 | v = v :+ c 79 | v 80 | } 81 | 82 | def testMutable(count: Int): IndexedSeq[Int] = { 83 | val s = ArrayBuffer[Int](count) 84 | for (c <- Range(0, count)) 85 | s.append(c) 86 | s.toIndexedSeq 87 | } 88 | 89 | val oneMillion = 1000000 90 | 91 | def testMutableNoConversion(count: Int): IndexedSeq[Int] = { 92 | val s = ArrayBuffer[Int](count) 93 | for (c <- Range(0, count)) 94 | s.append(c) 95 | s 96 | } 97 | 98 | def run(): Unit = { 99 | println("Immutable :") 100 | timeRuns(testImmutable(oneMillion), 5) 101 | println() 102 | 103 | println("Mutable :") 104 | timeRuns(testMutable(oneMillion), 5) 105 | println() 106 | 107 | println("MutableNoConversion :") 108 | timeRuns(testMutableNoConversion(oneMillion), 5) 109 | println() 110 | 111 | println("fiveTestPurchases :") 112 | val fiveTestPurchases = infiniteTestPurchases.take(5) 113 | for(purchase <- fiveTestPurchases) println(purchase) 114 | println("Immutable :") 115 | timeRuns(immutableSequenceEventProcessing(fiveHundredThousand), 5) 116 | println("Mutable :") 117 | timeRuns(mutableSequenceEventProcessing(fiveHundredThousand), 5) 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /Scala/src/com/yourtion/Pattern20/FlowControlExample.scala: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern20 2 | 3 | /** 4 | * Created by Yourtion on 07/04/2017. 5 | */ 6 | object FlowControlExample { 7 | def choose[E](num: Int, first: () => E, second: () => E, third: () => E) = 8 | if (num == 1) first() 9 | else if (num == 2) second() 10 | else if (num == 3) third() 11 | 12 | def test[E](expression: E) = expression 13 | 14 | def testTwice[E](expression: E) = { 15 | expression 16 | expression 17 | } 18 | 19 | def printTwice[E](expression: E) { 20 | println(expression) 21 | println(expression) 22 | } 23 | 24 | def testByName[E](expression: => E) = { 25 | expression 26 | expression 27 | } 28 | 29 | def simplerChoose[E](num: Int, first: => E, second: => E, third: => E) = 30 | if (num == 1) first 31 | else if (num == 2) second 32 | else if (num == 3) third 33 | 34 | def timeRun[E](toTime: => E) = { 35 | val start = System.currentTimeMillis 36 | toTime 37 | System.currentTimeMillis - start 38 | } 39 | def avgTime[E](times: Int, toTime: => E) = { 40 | val allTimes = for (_ <- Range(0, times)) yield timeRun(toTime) 41 | allTimes.sum / times 42 | } 43 | 44 | def run(): Unit = { 45 | println("choose :") 46 | choose(2, () => println("hello, world"), () => println("goodbye, cruel world"), () => println("meh, indifferent world")) 47 | println("test :") 48 | test(println("hello, world")) 49 | println("testTwice :") 50 | testTwice(println("hello, world")) 51 | println("printTwice :") 52 | printTwice(5 * 5) 53 | println("testByName :") 54 | testByName(println("hello, world")) 55 | println("simplerChoose :") 56 | simplerChoose(2, println("hello, world"), println("goodbye, cruel world"), println("meh, indifferent world")) 57 | println() 58 | 59 | println("avgTime : ") 60 | println(avgTime(5, Thread.sleep(1000))) 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Scala/src/com/yourtion/Pattern21/DSLExample.scala: -------------------------------------------------------------------------------- 1 | package com.yourtion.Pattern21 2 | 3 | import scala.collection.JavaConverters._ 4 | import scala.io.Source 5 | 6 | /** 7 | * Created by Yourtion on 07/04/2017. 8 | */ 9 | 10 | object ExtendedExample { 11 | case class CommandResult(status: Int, output: String, error: String) 12 | 13 | class Command(commandParts: List[String]) { 14 | def run = { 15 | val processBuilder = new ProcessBuilder(commandParts.asJava) 16 | val process = processBuilder.start() 17 | val status = process.waitFor() 18 | val outputAsString = Source.fromInputStream(process.getInputStream()).mkString("") 19 | val errorAsString = Source.fromInputStream(process.getErrorStream()).mkString("") 20 | CommandResult(status, outputAsString, errorAsString) 21 | } 22 | 23 | } 24 | 25 | implicit class CommandVector(existingCommands: Vector[String]) { 26 | def run = { 27 | val pipedCommands = existingCommands.mkString(" | ") 28 | Command("/bin/sh", "-c", pipedCommands).run 29 | } 30 | def pipe(nextCommand: String): Vector[String] = { 31 | existingCommands :+ nextCommand 32 | } 33 | } 34 | object Command { 35 | def apply(commandString: String) = new Command(commandString.split("\\s").toList) 36 | def apply(commandParts: String*) = new Command(commandParts.toList) 37 | } 38 | 39 | implicit class CommandString(firstCommandString: String) { 40 | def run = Command(firstCommandString).run 41 | def pipe(secondCommandString: String) = 42 | Vector(firstCommandString, secondCommandString) 43 | } 44 | 45 | def run(): Unit = { 46 | println("Command Extended :") 47 | println("ls -al" pipe "grep ." pipe "wc" run) 48 | } 49 | } 50 | 51 | object DSLExample { 52 | case class CommandResult(status: Int, output: String, error: String) 53 | 54 | class Command(commandParts: List[String]) { 55 | def run() = { 56 | val processBuilder = new ProcessBuilder(commandParts.asJava) 57 | val process = processBuilder.start() 58 | val status = process.waitFor() 59 | val outputAsString = 60 | Source.fromInputStream(process.getInputStream()).mkString("") 61 | val errorAsString = 62 | Source.fromInputStream(process.getErrorStream()).mkString("") 63 | CommandResult(status, outputAsString, errorAsString) 64 | } 65 | } 66 | 67 | object Command { 68 | def apply(commandString: String) = new Command(commandString.split("\\s").toList) 69 | } 70 | 71 | implicit class CommandString(commandString: String) { 72 | def run() = Command(commandString).run 73 | } 74 | 75 | def run(): Unit = { 76 | println("Command ls :") 77 | println(Command("ls -al").run()) 78 | println() 79 | println("Command ls as String :") 80 | println("ls -al" run) 81 | 82 | ExtendedExample.run() 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /Scala/src/com/yourtion/PatternDemo/Example.scala: -------------------------------------------------------------------------------- 1 | package com.yourtion.PatternDemo 2 | 3 | /** 4 | * Created by Yourtion on 9/7/16. 5 | */ 6 | object Example extends App { 7 | 8 | override def main(args: Array[String]): Unit = { 9 | 10 | println("\nPattern01 Example : \n") 11 | com.yourtion.Pattern01.PersonExample.run() 12 | com.yourtion.Pattern01.PersonExampleEx.run() 13 | println("------------------------------------") 14 | 15 | println("\nPattern02 Example : \n") 16 | com.yourtion.Pattern02.PersonExampleCC.run() 17 | println("------------------------------------") 18 | 19 | println("\nPattern03 Example : \n") 20 | com.yourtion.Pattern03.RegisterClient.run() 21 | println("------------------------------------") 22 | 23 | println("\nPattern04 Example : \n") 24 | com.yourtion.Pattern04.PersonHarness.run() 25 | println("------------------------------------") 26 | 27 | println("\nPattern05 Example : \n") 28 | com.yourtion.Pattern05.HigherOrderFunctions.run() 29 | com.yourtion.Pattern05.TheLambdaBarAndGrille.run() 30 | println("------------------------------------") 31 | 32 | println("\nPattern06 Example : \n") 33 | com.yourtion.Pattern06.GradeReporter.run() 34 | println("------------------------------------") 35 | 36 | println("\nPattern07 Example : \n") 37 | com.yourtion.Pattern07.PersonCollectorExample.run() 38 | println("------------------------------------") 39 | 40 | println("\nPattern08 Example : \n") 41 | com.yourtion.Pattern08.PersonExamples.run() 42 | println("------------------------------------") 43 | 44 | println("\nPattern09 Example : \n") 45 | com.yourtion.Pattern09.CalculatorExample.run() 46 | println("------------------------------------") 47 | 48 | println("\nPattern10 Example : \n") 49 | com.yourtion.Pattern10.VisitorExample.run() 50 | println("------------------------------------") 51 | 52 | println("\nPattern11 Example : \n") 53 | com.yourtion.Pattern11.Services.run() 54 | println("------------------------------------") 55 | 56 | println("\nPattern12 Example : \n") 57 | com.yourtion.Pattern12.Names.run() 58 | println("------------------------------------") 59 | 60 | println("\nPattern13 Example : \n") 61 | com.yourtion.Pattern13.MutualRecursionExample.run() 62 | println("------------------------------------") 63 | 64 | println("\nPattern14 Example : \n") 65 | com.yourtion.Pattern14.DiscountExample.run() 66 | println("------------------------------------") 67 | 68 | println("\nPattern15 Example : \n") 69 | com.yourtion.Pattern15.ChainExample.run() 70 | println("------------------------------------") 71 | 72 | println("\nPattern16 Example : \n") 73 | com.yourtion.Pattern16.FunctionBuilderExample.run() 74 | println("------------------------------------") 75 | 76 | println("\nPattern17 Example : \n") 77 | com.yourtion.Pattern17.MemoizationExample.run() 78 | println("------------------------------------") 79 | 80 | println("\nPattern18 Example : \n") 81 | com.yourtion.Pattern18.LazySequenceExample.run() 82 | println("------------------------------------") 83 | 84 | println("\nPattern19 Example : \n") 85 | com.yourtion.Pattern19.FocusedMutationExample.run() 86 | println("------------------------------------") 87 | 88 | println("\nPattern20 Example : \n") 89 | com.yourtion.Pattern20.FlowControlExample.run() 90 | println("------------------------------------") 91 | 92 | println("\nPattern21 Example : \n") 93 | com.yourtion.Pattern21.DSLExample.run() 94 | println("------------------------------------") 95 | 96 | } 97 | 98 | } 99 | -------------------------------------------------------------------------------- /Scala/src/com/yourtion/TinyWeb/Controller.scala: -------------------------------------------------------------------------------- 1 | package com.yourtion.TinyWeb 2 | 3 | /** 4 | * Created by Yourtion on 9/5/16. 5 | */ 6 | trait Controller { 7 | def handleRequest(httpRequest: HttpRequest): HttpResponse 8 | } 9 | 10 | class FunctionController(view: View, doRequest: (HttpRequest) => 11 | Map[String, List[String]] ) extends Controller { 12 | 13 | def handleRequest(request: HttpRequest): HttpResponse = 14 | try { 15 | val model = doRequest(request) 16 | val responseBody = view.render(model) 17 | HttpResponse(responseBody, 200) 18 | } catch { 19 | case e: ControllerException => 20 | HttpResponse("", e.getStatusCode) 21 | case e: RenderingException => 22 | HttpResponse("Exception while rendering.", 500) 23 | case e: Exception => 24 | HttpResponse("", 500) 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /Scala/src/com/yourtion/TinyWeb/ControllerException.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.TinyWeb; 2 | 3 | /** 4 | * Created by Yourtion on 9/5/16. 5 | */ 6 | public class ControllerException extends RuntimeException { 7 | 8 | private Integer statusCode; 9 | 10 | public ControllerException(Integer statusCode) { 11 | this.statusCode = statusCode; 12 | } 13 | 14 | public Integer getStatusCode() { 15 | return statusCode; 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /Scala/src/com/yourtion/TinyWeb/Example.scala: -------------------------------------------------------------------------------- 1 | package com.yourtion.TinyWeb 2 | 3 | import scala.util.Random 4 | 5 | /** 6 | * Created by Yourtion on 9/5/16. 7 | */ 8 | object Example extends App { 9 | 10 | def greetingViewRenderer(model: Map[String, List[String]]) = 11 | "

Friendly Greetings:

%s".format( 12 | model 13 | getOrElse("greetings", List[String]()) 14 | map(renderGreeting) 15 | mkString ", ") 16 | 17 | private def renderGreeting(greeting: String) = 18 | "

%s

".format(greeting) 19 | 20 | def greetingView = new FunctionView(greetingViewRenderer) 21 | 22 | def handleGreetingRequest(request: HttpRequest) = 23 | Map("greetings" -> request.body.split(",").toList.map(makeGreeting)) 24 | 25 | private def random = new Random() 26 | private def greetings = Vector("Hello", "Greetings", "Salutations", "Hola") 27 | private def makeGreeting(name: String) = 28 | "%s, %s".format(greetings(random.nextInt(greetings.size)), name) 29 | 30 | def greetingController = new FunctionController(greetingView, handleGreetingRequest) 31 | 32 | private def loggingFilter(request: HttpRequest) = { 33 | println("In Logging Filter - request for path: %s".format(request.path)) 34 | request 35 | } 36 | 37 | def tinyweb = new TinyWeb( 38 | Map("/greeting" -> greetingController), 39 | List(loggingFilter)) 40 | def testHttpRequest = HttpRequest(body = "Mike,Joe,John,Steve", path = "/greeting") 41 | 42 | override def main(args: Array[String]): Unit = { 43 | val testResponse = tinyweb.handleRequest(testHttpRequest) 44 | if (testResponse.isDefined) { 45 | println("responseCode: " + testResponse.get.responseCode) 46 | println("responseBody: ") 47 | println(testResponse.get.body) 48 | } 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /Scala/src/com/yourtion/TinyWeb/Filter.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.TinyWeb; 2 | 3 | /** 4 | * Created by Yourtion on 9/5/16. 5 | */ 6 | public interface Filter { 7 | 8 | public HttpRequest doFilter(HttpRequest request); 9 | 10 | } 11 | -------------------------------------------------------------------------------- /Scala/src/com/yourtion/TinyWeb/HttpData.scala: -------------------------------------------------------------------------------- 1 | package com.yourtion.TinyWeb 2 | 3 | /** 4 | * Created by Yourtion on 9/5/16. 5 | */ 6 | 7 | case class HttpRequest(headers: Map[String, String] = Map(), body: String, path: String) 8 | case class HttpResponse(body: String, responseCode: Integer) -------------------------------------------------------------------------------- /Scala/src/com/yourtion/TinyWeb/RenderingException.java: -------------------------------------------------------------------------------- 1 | package com.yourtion.TinyWeb; 2 | 3 | /** 4 | * Created by Yourtion on 9/5/16. 5 | */ 6 | public class RenderingException extends RuntimeException { 7 | 8 | public RenderingException(Exception e) { 9 | super(e); 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /Scala/src/com/yourtion/TinyWeb/TinyWeb.scala: -------------------------------------------------------------------------------- 1 | package com.yourtion.TinyWeb 2 | 3 | /** 4 | * Created by Yourtion on 9/5/16. 5 | */ 6 | class TinyWeb(controllers: Map[String, Controller], 7 | filters: List[(HttpRequest) => HttpRequest]) { 8 | 9 | def handleRequest(httpRequest: HttpRequest): Option[HttpResponse] = { 10 | val composedFilter = filters.reverse.reduceLeft( 11 | (composed, next) => composed compose next) 12 | val filteredRequest = composedFilter(httpRequest) 13 | val controllerOption = controllers.get(filteredRequest.path) 14 | controllerOption map { controller => controller.handleRequest(filteredRequest) } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Scala/src/com/yourtion/TinyWeb/View.scala: -------------------------------------------------------------------------------- 1 | package com.yourtion.TinyWeb 2 | 3 | /** 4 | * Created by Yourtion on 9/5/16. 5 | */ 6 | 7 | trait View { 8 | def render(model: Map[String, List[String]]): String 9 | } 10 | 11 | class FunctionView(viewRenderer: (Map[String, List[String]]) => String) extends View { 12 | def render(model: Map[String, List[String]]) = 13 | try 14 | viewRenderer(model) 15 | catch { 16 | case e: Exception => throw new RenderingException(e) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /ScreenShot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yourtion/LearningFunctionalProgramming/0ccfffe61b8e46ebdc5fdf485b328cee32ac7aac/ScreenShot.png --------------------------------------------------------------------------------