From dd446b1fd2582832fde5b29f36aaab3113548834 Mon Sep 17 00:00:00 2001 From: Yevhenii Medviediev Date: Mon, 18 Sep 2023 16:28:24 +0300 Subject: [PATCH] add grasp principles --- .obsidian/workspace.json | 51 ++++++++++--------- arch-grasp-controller.md | 5 ++ arch-grasp-creator.md | 5 ++ arch-grasp-high-cohesion.md | 6 +++ arch-grasp-indirection.md | 5 ++ arch-grasp-information-expert.md | 46 +++++++++++++++++ arch-grasp-low-coupling.md | 8 +++ arch-grasp-polymorphism.md | 5 ++ arch-grasp-protected-variations.md | 5 ++ arch-grasp-pure-fabrication.md | 8 +++ arch-grasp.md | 29 +++++++++++ ...ch-solid-dependency-inversion-principle.md | 0 ...h-solid-interface-segregation-principle.md | 0 ...rch-solid-liskov-substitution-principle.md | 0 ....md => arch-solid-open-closed-principle.md | 0 ...h-solid-single-responsibility-principle.md | 0 arch-solid.md | 10 ++-- 17 files changed, 153 insertions(+), 30 deletions(-) create mode 100644 arch-grasp-controller.md create mode 100644 arch-grasp-creator.md create mode 100644 arch-grasp-high-cohesion.md create mode 100644 arch-grasp-indirection.md create mode 100644 arch-grasp-information-expert.md create mode 100644 arch-grasp-low-coupling.md create mode 100644 arch-grasp-polymorphism.md create mode 100644 arch-grasp-protected-variations.md create mode 100644 arch-grasp-pure-fabrication.md create mode 100644 arch-grasp.md rename arch-dependency-inversion-principle.md => arch-solid-dependency-inversion-principle.md (100%) rename arch-interface-segregation-principle.md => arch-solid-interface-segregation-principle.md (100%) rename arch-liskov-substitution-principle.md => arch-solid-liskov-substitution-principle.md (100%) rename arch-open-closed-principle.md => arch-solid-open-closed-principle.md (100%) rename arch-single-responsibility-principle.md => arch-solid-single-responsibility-principle.md (100%) diff --git a/.obsidian/workspace.json b/.obsidian/workspace.json index e6a72cd..fa6c0d0 100644 --- a/.obsidian/workspace.json +++ b/.obsidian/workspace.json @@ -4,16 +4,16 @@ "type": "split", "children": [ { - "id": "697f5d4ef0274c85", + "id": "7b73df235fbf3cf0", "type": "tabs", "children": [ { - "id": "9efbade930908c16", + "id": "4944064c3fbbcafb", "type": "leaf", "state": { "type": "markdown", "state": { - "file": "Readme.md", + "file": "arch-grasp-high-cohesion.md", "mode": "source", "source": false } @@ -93,7 +93,7 @@ "state": { "type": "backlink", "state": { - "file": "Readme.md", + "file": "arch-grasp-high-cohesion.md", "collapseAll": false, "extraContext": false, "sortOrder": "alphabetical", @@ -110,7 +110,7 @@ "state": { "type": "outgoing-link", "state": { - "file": "Readme.md", + "file": "arch-grasp-high-cohesion.md", "linksCollapsed": false, "unlinkedCollapsed": true } @@ -133,7 +133,7 @@ "state": { "type": "outline", "state": { - "file": "Readme.md" + "file": "arch-grasp-high-cohesion.md" } } } @@ -141,7 +141,8 @@ } ], "direction": "horizontal", - "width": 300 + "width": 300, + "collapsed": true }, "left-ribbon": { "hiddenItems": { @@ -153,34 +154,34 @@ "command-palette:Open command palette": false } }, - "active": "9efbade930908c16", + "active": "4944064c3fbbcafb", "lastOpenFiles": [ + "arch-grasp-low-coupling.md", + "arch-grasp.md", + "arch-solid.md", + "arch-solid-dependency-inversion-principle.md", + "arch-solid-interface-segregation-principle.md", + "arch-solid-liskov-substitution-principle.md", + "arch-solid-open-closed-principle.md", + "arch-solid-single-responsibility-principle.md", + "arch-grasp-protected-variations.md", + "arch-grasp-polymorphism.md", + "arch-grasp-information-expert.md", + "arch-grasp-indirection.md", + "arch-grasp-high-cohesion.md", + "arch-grasp-creator.md", + "arch-grasp-controller.md", + "arch-grasp-pure-fabrication.md", + "Readme.md", "tls-termination.md", "TBD.md", "tls.md", "http-request.md", "http-header-hsts.md", "Bibliography.md", - "arch-solid.md", - "arch-single-responsibility-principle.md", - "arch-open-closed-principle.md", - "arch-liskov-substitution-principle.md", - "arch-interface-segregation-principle.md", - "arch-dependency-inversion-principle.md", - "arch-grasp.md", "node-js-non-blocking.md", "nodejs-import-internal-node-modules-arrangement.md", "ts-types-vs-interfaces.md", - "Readme.md", - "[arch-liskov-substitution.md", - "ts-turn-modules-into-types.md", - "ts-structural-type-system.md", - "ts-nominal-type-system.md", - "ts-dot-ts-files.md", - "ts-const-assertion.md", - "ts-assertion-function.md", - "nodejs-top-level-await.md", - "nodejs-callback-hell-does-not-exist.md", "Untitled.canvas" ] } \ No newline at end of file diff --git a/arch-grasp-controller.md b/arch-grasp-controller.md new file mode 100644 index 0000000..b869fd0 --- /dev/null +++ b/arch-grasp-controller.md @@ -0,0 +1,5 @@ +--- +tags: + - architecture + - grasp +--- diff --git a/arch-grasp-creator.md b/arch-grasp-creator.md new file mode 100644 index 0000000..b869fd0 --- /dev/null +++ b/arch-grasp-creator.md @@ -0,0 +1,5 @@ +--- +tags: + - architecture + - grasp +--- diff --git a/arch-grasp-high-cohesion.md b/arch-grasp-high-cohesion.md new file mode 100644 index 0000000..7feac5b --- /dev/null +++ b/arch-grasp-high-cohesion.md @@ -0,0 +1,6 @@ +--- +tags: + - architecture + - grasp +--- +High Cohesion is a software design principle that emphasizes organizing and structuring code in a way that closely related functions and data are grouped together within a module or class \ No newline at end of file diff --git a/arch-grasp-indirection.md b/arch-grasp-indirection.md new file mode 100644 index 0000000..b869fd0 --- /dev/null +++ b/arch-grasp-indirection.md @@ -0,0 +1,5 @@ +--- +tags: + - architecture + - grasp +--- diff --git a/arch-grasp-information-expert.md b/arch-grasp-information-expert.md new file mode 100644 index 0000000..0d1679f --- /dev/null +++ b/arch-grasp-information-expert.md @@ -0,0 +1,46 @@ +--- +tags: + - architecture + - grasp +--- +A class that has all the required information to perform a task (make a decision) should be assigned to do it. In general, this means that all the internal logic of a functionality should be controlled by the 'nearest' class to which its functionality belongs. +# Example +```js +class Product { + constructor(name, productPrice) { + this.name = name; + this.productPrice = productPrice; + } + // this class knows everything about products. Therefore this class is an information expert to calculate its price. + get price() { + return this.productPrice; + } +} + +class Purchase { + constructor(name, ...collection) { + this.name = name; + this.collection = collection; + } + // this class knows everything about purchases. Therefore this class is an information expert to calculate its price. + get price() { + return this.collection.reduce((sum, entity) => { + // class Purchase doesn't need to know how to calculate price of each individual entity. It's up to these entities. He only knows that price of any entity is available by a public field price. These entities in their turn are information experts to calculate their price + return sum += entity.price; + }, 0); + } +} + +const product1 = new Product('Laptop', 2000); +const product2 = new Product('Mouse', 40); +const purchase1 = new Purchase('Work kit', product1, product2); + +const product3 = new Product('Book', 100); +const product4 = new Product('iPhone', 1000); + +const total = new Purchase('All together', purchase1, product3, product4); + +// Now it's easy to calculate total price +console.log(total.price); +``` + diff --git a/arch-grasp-low-coupling.md b/arch-grasp-low-coupling.md new file mode 100644 index 0000000..4ffac60 --- /dev/null +++ b/arch-grasp-low-coupling.md @@ -0,0 +1,8 @@ +--- +tags: + - architecture + - grasp +--- +modules/classes/functions should know about the properties of other modules/classes/functions only as much as they need to. The less they know, the more readable your code becomes, and it becomes easier to extend and modify. This principle also relates to defining architecture boundaries. + +The middleware concept is a good example of a violation of this principle. Each middleware can modify the HTTP `request`/`response`. Often, middlewares should be executed in a specific order because one middleware can add a new field to the `request` object while another one relies on the existence of this field. diff --git a/arch-grasp-polymorphism.md b/arch-grasp-polymorphism.md new file mode 100644 index 0000000..b869fd0 --- /dev/null +++ b/arch-grasp-polymorphism.md @@ -0,0 +1,5 @@ +--- +tags: + - architecture + - grasp +--- diff --git a/arch-grasp-protected-variations.md b/arch-grasp-protected-variations.md new file mode 100644 index 0000000..b869fd0 --- /dev/null +++ b/arch-grasp-protected-variations.md @@ -0,0 +1,5 @@ +--- +tags: + - architecture + - grasp +--- diff --git a/arch-grasp-pure-fabrication.md b/arch-grasp-pure-fabrication.md new file mode 100644 index 0000000..c0af3b1 --- /dev/null +++ b/arch-grasp-pure-fabrication.md @@ -0,0 +1,8 @@ +--- +tags: + - architecture + - grasp +--- +Pure fabrication refers to entities that do not exist in the business domain but are abstractions within the program. These abstractions can be system-level constructs that are easy to reuse. Such abstractions help reduce the amount of system-specific code within the business domain. +## Examples +Promise, Socket, Connection, Proxy, Request, Response, Server, Stream, Queue, Transaction, etc \ No newline at end of file diff --git a/arch-grasp.md b/arch-grasp.md new file mode 100644 index 0000000..93b72ec --- /dev/null +++ b/arch-grasp.md @@ -0,0 +1,29 @@ +--- +tags: + - architecture + - grasp +--- +GRASP - General responsibility assignment software patterns + +> [!INFO] +> First was proposed by Craig Larman in his book "Applying UML and Patterns" + +## Principles +- [[arch-grasp-low-coupling|Low Coupling]] +- [[arch-grasp-information-expert|Information Expert]] +- [[arch-grasp-controller|Controller]] +- [[arch-grasp-pure-fabrication|Pure Fabrication]] +- [[arch-grasp-protected-variations|Protected Variations]] +- [[arch-grasp-high-cohesion|High Cohesion]] +- [[arch-grasp-creator|Creator]] +- [[arch-grasp-polymorphism|Polymorphism]] +- [[arch-grasp-indirection|Indirection]] + +### Creator +Problem: Who should create instance(who should hold and destroy link) + +Solution: Who contains or aggregate instances, who use them heavily, who has all the information for initialization. + +Why: to low coupling + +Examples: constructor, factory, pool diff --git a/arch-dependency-inversion-principle.md b/arch-solid-dependency-inversion-principle.md similarity index 100% rename from arch-dependency-inversion-principle.md rename to arch-solid-dependency-inversion-principle.md diff --git a/arch-interface-segregation-principle.md b/arch-solid-interface-segregation-principle.md similarity index 100% rename from arch-interface-segregation-principle.md rename to arch-solid-interface-segregation-principle.md diff --git a/arch-liskov-substitution-principle.md b/arch-solid-liskov-substitution-principle.md similarity index 100% rename from arch-liskov-substitution-principle.md rename to arch-solid-liskov-substitution-principle.md diff --git a/arch-open-closed-principle.md b/arch-solid-open-closed-principle.md similarity index 100% rename from arch-open-closed-principle.md rename to arch-solid-open-closed-principle.md diff --git a/arch-single-responsibility-principle.md b/arch-solid-single-responsibility-principle.md similarity index 100% rename from arch-single-responsibility-principle.md rename to arch-solid-single-responsibility-principle.md diff --git a/arch-solid.md b/arch-solid.md index 50ef7da..5462aeb 100644 --- a/arch-solid.md +++ b/arch-solid.md @@ -4,8 +4,8 @@ tags: - solid --- SOLID stands for 5 principles: -- S - [[arch-single-responsibility-principle|Single Responsibility Principle]] -- O - [[arch-open-closed-principle|Open/Close Principle]] -- L - [[arch-liskov-substitution-principle|Liskov's Substitution Principle]] -- I - [[arch-interface-segregation-principle|Interface Segregation Principle]] -- D - [[arch-dependency-inversion-principle|Dependency Inversion Principle]] \ No newline at end of file +- S - [[arch-solid-single-responsibility-principle|Single Responsibility Principle]] +- O - [[arch-solid-open-closed-principle|Open/Close Principle]] +- L - [[arch-solid-liskov-substitution-principle|Liskov's Substitution Principle]] +- I - [[arch-solid-interface-segregation-principle|Interface Segregation Principle]] +- D - [[arch-solid-dependency-inversion-principle|Dependency Inversion Principle]] \ No newline at end of file