├── .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 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/jsLibraryMappings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/kotlinc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
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 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/.idea/runConfigurations/PatternScala.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/.idea/runConfigurations/TinyWebClojure.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/runConfigurations/TinyWebJava.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/.idea/runConfigurations/TinyWebScala.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
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 | 
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
--------------------------------------------------------------------------------