![Page 2: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/2.jpg)
OOP HANGOVER
![Page 3: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/3.jpg)
DESIGN
![Page 4: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/4.jpg)
DESIGNBefore After
![Page 5: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/5.jpg)
MONOLITHIC DESIGN
![Page 6: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/6.jpg)
OO DESIGNNoun-orientedVerb-orientedDomain-driven?
![Page 7: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/7.jpg)
NOUNSCustomerDAOCustomerServiceCustomerController
![Page 8: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/8.jpg)
VERBSRegisterCustomerPromoteCustomerToVIPRenderCustomerProfilePage
![Page 9: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/9.jpg)
OO DESIGN PRINCIPLESSingle ResponsibilityInterface SegregationDependency Inversion
![Page 10: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/10.jpg)
SINGLE RESPONSIBILITYpublic class ZipDownloadService
public List<File> downloadAndExtract(String location)
![Page 11: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/11.jpg)
SINGLE RESPONSIBILITYpublic class FileDownloader
public List<File> downloadFiles(String location) ...
public class ZipExtractor
public File extractZip(File archive) ...
![Page 12: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/12.jpg)
OR ... JUST FUNCTIONS(defn downloadfiles [location] (...))
(defn extractzip [archive] (...))
![Page 13: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/13.jpg)
CLOJUREin a nutshell
( some-function arg1 arg2 arg3 )
![Page 14: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/14.jpg)
INTERFACE SEGREGATIONpublic class ProductCatalog public ProductId Save(Product product) ...
public Product FindById(ProductId id) ...
![Page 15: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/15.jpg)
INTERFACE SEGREGATIONpublic class ProductSaver public ProductId Save(Product product) ...
public class ProductFinder public Product FindById(ProductId id) ...
![Page 16: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/16.jpg)
Somethin' ain't right
![Page 17: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/17.jpg)
INTERFACE SEGREGATIONpublic class ProductRepository public ProductId Save(Product product) ...
public class ProductQuery public Product FindById(ProductId id) ...
![Page 18: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/18.jpg)
Feelin' good now
![Page 19: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/19.jpg)
OR ... JUST FUNCTIONS(defn saveproduct [product] (...))
(defn findproductbyid [id] (...))
![Page 20: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/20.jpg)
Applying OO design principleseventually leads to...
functional design
![Page 21: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/21.jpg)
WHAT'S MISSINGCode organizationEncapsulationInheritance hierarchiesPolymorphism
![Page 22: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/22.jpg)
NO CODE ORGANIZATION?
(ns my.product.repository)
(defn save [product] (...))
(defn findbyid [id] (...))
(require '[my.product.repository :as productrepo])
(productrepo/findbyid 42)
![Page 23: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/23.jpg)
NO ENCAPSULATION?
Data is not an objectData is immutable
![Page 24: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/24.jpg)
NO INHERITANCE HIERARCHIES?
Blimey! What a showstopper
![Page 25: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/25.jpg)
NO POLYMORPHISM?
We'll get there
![Page 26: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/26.jpg)
COMPOSITION
![Page 27: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/27.jpg)
![Page 28: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/28.jpg)
COMPOSITIONAvoiding hard-coded dependencies
![Page 29: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/29.jpg)
OO COMPOSITIONpublic class ProfilePage
public String render(Repository repository, int customerId) return toHtml(repository.loadProfile(customerId));
Repository repository = new Repository();ProfilePage page = new ProfilePage();
String html = page.render(repository, customerId);
![Page 30: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/30.jpg)
FP COMPOSITION(defn renderpage [repositoryfn customerid] (tohtml (repositoryfn customerid)))
(defn loadprofile [customerid] (...))
(renderpage loadprofile customerid)
![Page 31: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/31.jpg)
OO "DEPENDENCY INJECTION"ProfilePage pageInjected = new ProfilePage(new Repository());
pageInjected.render(customerId);
![Page 32: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/32.jpg)
FP "DEPENDENCY INJECTION"(def renderinjected (fn [customerid] (renderpage loadprofile customerid)))
(renderinjected customerid)
![Page 33: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/33.jpg)
PARTIAL APPLICATION(def renderinjected (partial renderpage loadprofile))
(renderinjected customerid)
![Page 34: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/34.jpg)
"ADAPTER" PATTERN(defn parseint [s] (Integer/parseInt s))
(renderpage (comp loadprofile parseint) customerid)
(defn toviewmodel [profile] (...))
(renderpage (comp toviewmodel loadprofile) customerid)
![Page 35: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/35.jpg)
"DECORATOR" PATTERN(defn withlogging [f] (fn [& args] (log/debug "Called with params" args) (def [result (apply f args)] (log/debug "Returned" result) result)))
(renderpage (withlogging loadprofile) customerid)
![Page 36: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/36.jpg)
POLYMORPHISM
![Page 37: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/37.jpg)
![Page 38: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/38.jpg)
POLYMORPHISMI don't know.
I don't want to know.
![Page 39: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/39.jpg)
POLYMORPHISMSubtypeParametricAd-hoc
![Page 40: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/40.jpg)
OO POLYMORPHISMInheritance hierarchyInterfacesDependency inversion
![Page 41: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/41.jpg)
public interface JsonObj String toJson();
![Page 42: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/42.jpg)
public class JsonString implements JsonObj private final String value;
public JsonString(String value) this.value = value;
public String toJson() return "\"" + value + "\"";
![Page 43: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/43.jpg)
public class JsonList implements JsonObj private final List<? extends JsonObj> list;
public JsonString(List<? extends JsonObj> list) this.list = list;
public String toJson() return "[" + list.stream() .map(JsonObj::toJson) .collect(joining(",")) + "]";
![Page 44: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/44.jpg)
JsonObj obj = new JsonList(asList( new JsonString("a"), new JsonList(asList( new JsonString("b"), new JsonString("c") )), new JsonString("d")));
System.out.println(obj.toJson());
// ["a",["b","c"],"d"]
![Page 45: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/45.jpg)
LIMITATIONS
Need wrapper typesCannot extend existing types
![Page 46: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/46.jpg)
Too constraining!
![Page 47: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/47.jpg)
FP POLYMORPHISMFunction compositionDispatch on parameters
![Page 48: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/48.jpg)
PROTOCOLSopen type system
![Page 49: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/49.jpg)
(defprotocol Json (tojson [this]))
![Page 50: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/50.jpg)
(extendtype String Json (tojson [this] (str "\"" this "\"")))
(extendtype List Json (tojson [this] (str "[" (>> this (map tojson) (string/join ",")) "]")))
(extendtype nil Json (tojson [this] "null"))
![Page 51: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/51.jpg)
(tojson ["a" ["b" "c"] nil "d"])
;;=> ["a",["b","c"],null,"d"]
![Page 52: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/52.jpg)
Why stop there?
![Page 53: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/53.jpg)
MULTIMETHODS
![Page 54: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/54.jpg)
(defmulti greet :country)
(defmethod greet "LT" [person] (println "Labas," (:name person) ". Kaip sekasi?"))
(defmethod greet "FR" [person] (println "Bonjour," (:name person) "!"))
(defmethod greet :default [person] (println "Hi," (:name person)))
(greet :name "Jacques" :country "FR")
;;=> Bonjour, Jacques !
![Page 55: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/55.jpg)
(defmulti say (fn [text n] (even? n)))
(defmethod say true [text n] (println text n "is even"))
(defmethod say false [text n] (println text n "is odd"))
(say "Guess what?" 5)
;;=> Guess what? 5 is odd
![Page 56: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/56.jpg)
CONCLUSIONDesignCompositionPolymorphism
![Page 57: Living without Objects (Thinking in Functions)](https://reader034.vdocuments.net/reader034/viewer/2022042716/55c6cfdfbb61eb9f7c8b460e/html5/thumbnails/57.jpg)
I'm probably over time already
(questions? "Osvaldas Grigas" @ogrigas)