Skip to content

Instantly share code, notes, and snippets.

@tp-hk
Last active April 12, 2025 21:38

Revisions

  1. tp-hk revised this gist Feb 23, 2024. 1 changed file with 8 additions and 1 deletion.
    9 changes: 8 additions & 1 deletion Refactoring: Improving the Design of Existing Code.md
    Original file line number Diff line number Diff line change
    @@ -23,4 +23,11 @@

    ### 8 Moving Features

    - Move functions: mainly when it ref elements in other contexts more than its current context. Often a new context/class will be needed if moving a group of functions
    - Move functions: mainly when it ref elements in other contexts more than its current context. Often a new context/class will be needed if moving a group of functions
    - Move fields
    - Move (caller) statements into functions: when caller statement is duplicated before calling functions
    - Move (function) statements into callers: when function needs to support varying behaviors based on callers, should move those behaviors to the callers
    - Replace inline code (loose end/duplicate) with function calls (either extracted into functions or from libraries)
    - Slide: i.e. code is easier to understand when things that are related to each other appear together
    - Split loop: when code inside a loop does different things, split into multiple loops (refactor, then optimize)
    - Replace loop with pipeline: use HOF to run different callbacks for diff. operations instead of having everything in one loop similar to above e.g. `data.filter(...).map(...).reduce(...)`
  2. tp-hk revised this gist Feb 23, 2024. 1 changed file with 11 additions and 5 deletions.
    16 changes: 11 additions & 5 deletions Refactoring: Improving the Design of Existing Code.md
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,7 @@
    # Refactoring: Improving the Design of Existing Code (2023 H2)

    - [6 A First Set of Refactoring](https://gist.github.com/tp-hk/6b81247b7475094f3985e6d0d2ace5c1#)
    - [7 Encapsulation](https://gist.github.com/tp-hk/6b81247b7475094f3985e6d0d2ace5c1#2-planning-a-migration)
    - [7 Encapsulation]([https://gist.github.com/tp-hk/6b81247b7475094f3985e6d0d2ace5c1#2-planning-a-migration](https://gist.github.com/tp-hk/6b81247b7475094f3985e6d0d2ace5c1/#7-encapsulation))
    - [8 Moving Features]([https://gist.github.com/tp-hk/6b81247b7475094f3985e6d0d2ace5c1#2-planning-a-migration](https://gist.github.com/tp-hk/6b81247b7475094f3985e6d0d2ace5c1/#8-moving-features))

    ---

    @@ -14,7 +14,13 @@
    - To ensure data is calculated in right order: Replace temp by query
    - Hide connections between classes:
    - Hide delegate: `aPerson.department.manager => aPerson.manager` - Motivation: since there's no need to reveal to client that department is responsible for tracking manager, it's better to hide department from client.
    - Remove middle man (opposite of above): `aPerson.manager => aPerson.department.manager` - motivation: When too many hidden delegation is added. Note: there's no reason to remove middle man or hide delegation.
    - Remove middle man (opposite of above): `aPerson.manager => aPerson.department.manager` - motivation: When too many hidden delegation is added. Note: there's no absolute reason to either remove middle man or hide delegation.
    - Substitute algorithm: Motivation: Substitute a complicated algorithm by something simple/existing tool. This should be done only if the method is simple enough
    - Split class: split responsibilities into child class, then apply "change reference to value" so child objects are always replaced like a primitive values instead of getting reference updated
    - Inline class: usually happens after refactoring a class which leave little responsibilities to it, or when collapsing context into inline class between spliting.
    - Class reorg:
    - Split class: split responsibilities into child class, then apply "change reference to value" so child objects are always replaced like a primitive values instead of getting reference updated
    - Inline class: usually happens after refactoring a class which leave little responsibilities to it, or when collapsing context into inline class between spliting.
    - Substitute algorithm: Use existing algorithms/API

    ### 8 Moving Features

    - Move functions: mainly when it ref elements in other contexts more than its current context. Often a new context/class will be needed if moving a group of functions
  3. tp-hk revised this gist Feb 23, 2024. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions Refactoring: Improving the Design of Existing Code.md
    Original file line number Diff line number Diff line change
    @@ -16,3 +16,5 @@
    - Hide delegate: `aPerson.department.manager => aPerson.manager` - Motivation: since there's no need to reveal to client that department is responsible for tracking manager, it's better to hide department from client.
    - Remove middle man (opposite of above): `aPerson.manager => aPerson.department.manager` - motivation: When too many hidden delegation is added. Note: there's no reason to remove middle man or hide delegation.
    - Substitute algorithm: Motivation: Substitute a complicated algorithm by something simple/existing tool. This should be done only if the method is simple enough
    - Split class: split responsibilities into child class, then apply "change reference to value" so child objects are always replaced like a primitive values instead of getting reference updated
    - Inline class: usually happens after refactoring a class which leave little responsibilities to it, or when collapsing context into inline class between spliting.
  4. tp-hk revised this gist Feb 23, 2024. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions Refactoring: Improving the Design of Existing Code.md
    Original file line number Diff line number Diff line change
    @@ -9,8 +9,8 @@

    - Hide info from the rest of the system:
    - Encapsulate record: "record" - POJO; "object" - class instance. Object is better for mutable data, also hide the internal representation of the data and provides controlled access to internal data
    - Encapsulate collection:
    - Replace primitive with objects:
    - Encapsulate collection: provide modifier methods, for getter return a copy of collection
    - Replace primitive with objects: wrap primitive values in class so behaviors can be added
    - To ensure data is calculated in right order: Replace temp by query
    - Hide connections between classes:
    - Hide delegate: `aPerson.department.manager => aPerson.manager` - Motivation: since there's no need to reveal to client that department is responsible for tracking manager, it's better to hide department from client.
  5. tp-hk revised this gist Feb 20, 2024. 1 changed file with 9 additions and 3 deletions.
    12 changes: 9 additions & 3 deletions Refactoring: Improving the Design of Existing Code.md
    Original file line number Diff line number Diff line change
    @@ -7,6 +7,12 @@

    ### 7 Encapsulation

    - Hide delegate: `aPerson.department.manager => aPerson.manager` - Motivation: since there's no need to reveal to client that department is responsible for tracking manager, it's better to hide department from client.
    - Remove middle man (opposite of above): `aPerson.manager => aPerson.department.manager` - motivation: When too many hidden delegation is added. Note: there's no reason to remove middle man or hide delegation.
    - Substitute algorithm: Motivation: Substitute a complicated algorithm by something simple/existing tool. This should be done only if the method is simple enough
    - Hide info from the rest of the system:
    - Encapsulate record: "record" - POJO; "object" - class instance. Object is better for mutable data, also hide the internal representation of the data and provides controlled access to internal data
    - Encapsulate collection:
    - Replace primitive with objects:
    - To ensure data is calculated in right order: Replace temp by query
    - Hide connections between classes:
    - Hide delegate: `aPerson.department.manager => aPerson.manager` - Motivation: since there's no need to reveal to client that department is responsible for tracking manager, it's better to hide department from client.
    - Remove middle man (opposite of above): `aPerson.manager => aPerson.department.manager` - motivation: When too many hidden delegation is added. Note: there's no reason to remove middle man or hide delegation.
    - Substitute algorithm: Motivation: Substitute a complicated algorithm by something simple/existing tool. This should be done only if the method is simple enough
  6. tp-hk renamed this gist Feb 20, 2024. 1 changed file with 0 additions and 0 deletions.
  7. tp-hk revised this gist Feb 20, 2024. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -9,4 +9,4 @@

    - Hide delegate: `aPerson.department.manager => aPerson.manager` - Motivation: since there's no need to reveal to client that department is responsible for tracking manager, it's better to hide department from client.
    - Remove middle man (opposite of above): `aPerson.manager => aPerson.department.manager` - motivation: When too many hidden delegation is added. Note: there's no reason to remove middle man or hide delegation.

    - Substitute algorithm: Motivation: Substitute a complicated algorithm by something simple/existing tool. This should be done only if the method is simple enough
  8. tp-hk revised this gist Feb 20, 2024. 1 changed file with 12 additions and 0 deletions.
    12 changes: 12 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,12 @@
    # Refactoring: Improving the Design of Existing Code (2023 H2)

    - [6 A First Set of Refactoring](https://gist.github.com/tp-hk/6b81247b7475094f3985e6d0d2ace5c1#)
    - [7 Encapsulation](https://gist.github.com/tp-hk/6b81247b7475094f3985e6d0d2ace5c1#2-planning-a-migration)

    ---

    ### 7 Encapsulation

    - Hide delegate: `aPerson.department.manager => aPerson.manager` - Motivation: since there's no need to reveal to client that department is responsible for tracking manager, it's better to hide department from client.
    - Remove middle man (opposite of above): `aPerson.manager => aPerson.department.manager` - motivation: When too many hidden delegation is added. Note: there's no reason to remove middle man or hide delegation.

  9. tp-hk revised this gist Jun 19, 2023. 1 changed file with 6 additions and 1 deletion.
    7 changes: 6 additions & 1 deletion Righting Software.md
    Original file line number Diff line number Diff line change
    @@ -31,4 +31,9 @@
    1. Ask what could change along the axes of volatility: same user over time vs same tiime but different users
    2. Observe solutions masquerading as requirements, generalize the examples/requirement into the underlying candidate for volatility
    - Not everything that is a variable is volatile. Variable: can be controlled using conditional code; Volatility: Changes or risks that are open-ended/has ripple effect.
    - Once candidates for volatility are identifed, compile into a list
    - Once candidates for volatility are identifed, compile into a list, then transition into architectural diagram.
    - Sometimes a component can encapsulate 1+ volatilities
    - Sometimes volatilities can be operational concept (e.g. latency)
    - Volatilities can also be encapsulated into 3rd party service
    - Start with simple decisions, which will constrain the system
    - Nature of business (changed rarely) should not be captured as volatility
  10. tp-hk revised this gist Jun 19, 2023. 1 changed file with 4 additions and 1 deletion.
    5 changes: 4 additions & 1 deletion Righting Software.md
    Original file line number Diff line number Diff line change
    @@ -28,4 +28,7 @@
    - Benefits: smaller areas of impact for testing; better maintainability
    - Drawbacks: Takes longer to decompose than functional decomposition. Requirement analysis is still required to identify areas of volatility.
    - Identifying volatility
    - ....
    1. Ask what could change along the axes of volatility: same user over time vs same tiime but different users
    2. Observe solutions masquerading as requirements, generalize the examples/requirement into the underlying candidate for volatility
    - Not everything that is a variable is volatile. Variable: can be controlled using conditional code; Volatility: Changes or risks that are open-ended/has ripple effect.
    - Once candidates for volatility are identifed, compile into a list
  11. tp-hk revised this gist Jun 19, 2023. 1 changed file with 9 additions and 1 deletion.
    10 changes: 9 additions & 1 deletion Righting Software.md
    Original file line number Diff line number Diff line change
    @@ -20,4 +20,12 @@
    - Bloated client: Client will be required to combine functions from different services, instead of just invoking operations/presenting data. Each service also becomes an entry point, leading to multiple points of failure.
    - Bloated service: Client has single entry point, but services are coupled to each other (A -> B -> C). e.g. A must be aware of B. e.g. A must handle error when B fails i.e. A becomes bloated service
    - Domain decomposition: more complex than functionality decomposition, can cause avoidance of cross-domain connectivity, reducing communication to CRUD/state changes
    - Hallmark of bad design: when any change to system affects the client; Ideally, the client and services should be able to evolve independently.
    - Hallmark of bad design: when any change to system affects the client; Ideally, the client and services should be able to evolve independently.
    - Trading system decomposition [example]([url](https://drive.google.com/file/d/1Fcrf6f7YrZwJirf-FLkEg3z17_LfWc0_/view?usp=sharing))
    - **The method: Decompose based on volatility**
    - Volatility decomposition: Identify areas of potential change, encapsulate those into building blocks, then implement the behavior as interaction b/w the encapsulate areas of volatility.
    - The encapsulation can be functional by nature, but can have no meaning for the business.
    - Benefits: smaller areas of impact for testing; better maintainability
    - Drawbacks: Takes longer to decompose than functional decomposition. Requirement analysis is still required to identify areas of volatility.
    - Identifying volatility
    - ....
  12. tp-hk revised this gist Jun 19, 2023. 1 changed file with 3 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion Righting Software.md
    Original file line number Diff line number Diff line change
    @@ -13,9 +13,11 @@
    ### 2 Decomposition

    - Architecture: 1. breakdown of systems into components; 2. perscribes interaction at runtime
    - Functionality decomposition: defines building blocks (service) based on functionality. Problems: Couple functionality with requirements. Consequences:
    - Functionality decomposition: defines building blocks (service) based on functionality. Useful for discovering hidden/implied functionas by drilling down the requirements.
    - Functionality decomposition problems: Couple functionality with requirements. Consequences:
    - Changing requirement requires new decomposition: one service per variant of functionality, or one mega service
    - Precluding reuse: system has A -> B -> C; B itself can't be reused without A, C
    - Bloated client: Client will be required to combine functions from different services, instead of just invoking operations/presenting data. Each service also becomes an entry point, leading to multiple points of failure.
    - Bloated service: Client has single entry point, but services are coupled to each other (A -> B -> C). e.g. A must be aware of B. e.g. A must handle error when B fails i.e. A becomes bloated service
    - Domain decomposition: more complex than functionality decomposition, can cause avoidance of cross-domain connectivity, reducing communication to CRUD/state changes
    - Hallmark of bad design: when any change to system affects the client; Ideally, the client and services should be able to evolve independently.
  13. tp-hk revised this gist Jun 19, 2023. 2 changed files with 2 additions and 12 deletions.
    3 changes: 2 additions & 1 deletion Righting Software.md
    Original file line number Diff line number Diff line change
    @@ -16,5 +16,6 @@
    - Functionality decomposition: defines building blocks (service) based on functionality. Problems: Couple functionality with requirements. Consequences:
    - Changing requirement requires new decomposition: one service per variant of functionality, or one mega service
    - Precluding reuse: system has A -> B -> C; B itself can't be reused without A, C
    - Bloated client: Client will be required to combine functions from different services, instead of just invoking operations/presenting data.
    - Bloated client: Client will be required to combine functions from different services, instead of just invoking operations/presenting data. Each service also becomes an entry point, leading to multiple points of failure.
    - Bloated service: Client has single entry point, but services are coupled to each other (A -> B -> C). e.g. A must be aware of B. e.g. A must handle error when B fails i.e. A becomes bloated service
    - Hallmark of bad design: when any change to system affects the client; Ideally, the client and services should be able to evolve independently.
    11 changes: 0 additions & 11 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -1,11 +0,0 @@
    # Righting Software (2023 H2)


    ---

    ### 1 The Method

    - "The Method" provides decision tree for system design and project design
    - The design of complex system is a collection of many smaller design decisions, arranged in a decision tree. Each branch = Design option; Each level down = finer decision; Each leaf = valid solution
    - Prune the tree by constraints
    - Enforce design through communications: reviews, inspections & mentoring
  14. tp-hk revised this gist Jun 19, 2023. 2 changed files with 5 additions and 8 deletions.
    8 changes: 5 additions & 3 deletions Righting Software.md
    Original file line number Diff line number Diff line change
    @@ -13,6 +13,8 @@
    ### 2 Decomposition

    - Architecture: 1. breakdown of systems into components; 2. perscribes interaction at runtime
    - Functionality decomposition: defines building blocks (service) based on functionality. Problems:
    - Couple functionality with requirements. Changing requirement requires new decomposition, precluding reuse (system A -> B -> C; B itself can't be reused without A, C), and leading to complex system (one service per variant of functionality, or one mega service)
    -
    - Functionality decomposition: defines building blocks (service) based on functionality. Problems: Couple functionality with requirements. Consequences:
    - Changing requirement requires new decomposition: one service per variant of functionality, or one mega service
    - Precluding reuse: system has A -> B -> C; B itself can't be reused without A, C
    - Bloated client: Client will be required to combine functions from different services, instead of just invoking operations/presenting data.
    - Hallmark of bad design: when any change to system affects the client; Ideally, the client and services should be able to evolve independently.
    5 changes: 0 additions & 5 deletions Righting Software_OLD.md
    Original file line number Diff line number Diff line change
    @@ -1,5 +0,0 @@
    # Righting Software (2023 H2)

    - The method = analysis & (system + proj) design procsss
    - Limiting the design time forces you to produce a good-enough design.
    - Design decision tree: Each branching in the tree represents a possible design option that leads to additional, finer design decisions. The leaves of the tree represent complete design solutions for the requirements. Each leaf is a consistent, distinct, and valid solution.
  15. tp-hk revised this gist Jun 19, 2023. 2 changed files with 22 additions and 4 deletions.
    21 changes: 17 additions & 4 deletions Righting Software.md
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,18 @@
    # Righting Software (2023 H2)
    # Righting Software - Juval Lowy (2023 H2)

    - The method = analysis & (system + proj) design procsss
    - Limiting the design time forces you to produce a good-enough design.
    - Design decision tree: Each branching in the tree represents a possible design option that leads to additional, finer design decisions. The leaves of the tree represent complete design solutions for the requirements. Each leaf is a consistent, distinct, and valid solution.

    ---

    ### 1 The Method

    - The design of complex system is a collection of many smaller design decisions, arranged in a decision tree. Each branch = Design option; Each level down = finer decision; Each leaf = valid solution
    - "The Method" provides decision tree for system design and project design
    - Prune the tree by constraints
    - Enforce design through communications: reviews, inspections & mentoring

    ### 2 Decomposition

    - Architecture: 1. breakdown of systems into components; 2. perscribes interaction at runtime
    - Functionality decomposition: defines building blocks (service) based on functionality. Problems:
    - Couple functionality with requirements. Changing requirement requires new decomposition, precluding reuse (system A -> B -> C; B itself can't be reused without A, C), and leading to complex system (one service per variant of functionality, or one mega service)
    -
    5 changes: 5 additions & 0 deletions Righting Software_OLD.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,5 @@
    # Righting Software (2023 H2)

    - The method = analysis & (system + proj) design procsss
    - Limiting the design time forces you to produce a good-enough design.
    - Design decision tree: Each branching in the tree represents a possible design option that leads to additional, finer design decisions. The leaves of the tree represent complete design solutions for the requirements. Each leaf is a consistent, distinct, and valid solution.
  16. tp-hk revised this gist Jun 19, 2023. 1 changed file with 11 additions and 0 deletions.
    11 changes: 11 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,11 @@
    # Righting Software (2023 H2)


    ---

    ### 1 The Method

    - "The Method" provides decision tree for system design and project design
    - The design of complex system is a collection of many smaller design decisions, arranged in a decision tree. Each branch = Design option; Each level down = finer decision; Each leaf = valid solution
    - Prune the tree by constraints
    - Enforce design through communications: reviews, inspections & mentoring
  17. tp-hk revised this gist Jun 14, 2023. 1 changed file with 5 additions and 0 deletions.
    5 changes: 5 additions & 0 deletions Righting Software.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,5 @@
    # Righting Software (2023 H2)

    - The method = analysis & (system + proj) design procsss
    - Limiting the design time forces you to produce a good-enough design.
    - Design decision tree: Each branching in the tree represents a possible design option that leads to additional, finer design decisions. The leaves of the tree represent complete design solutions for the requirements. Each leaf is a consistent, distinct, and valid solution.
  18. tp-hk revised this gist Apr 19, 2023. 1 changed file with 8 additions and 7 deletions.
    15 changes: 8 additions & 7 deletions System Design Fundamentals.md
    Original file line number Diff line number Diff line change
    @@ -26,10 +26,11 @@

    ### 4 Composition

    - Don't build system based on requirements, but based on use cases
    - There should be only a few core use cases, other are variations created by different interactions
    - Identify the smallest set of building blocks that satisfy the core use cases (composable design). Ideally there should be ~10 components
    - With the above, design can change but core use cases won't
    - Composable design
    - Doesn't satisfy any use case in particular
    - Features are aspects of integration, not implementation
    - Don't build system based on requirements, but based on use cases
    - There should be only a few core use cases, other are variations created by different interactions
    - Identify the smallest set of building blocks that satisfy the core use cases (composable design). Ideally there should be ~10 components
    - With the above, design can change but core use cases won't
    - Composable design
    - Doesn't satisfy any use case in particular
    - Features are aspects of integration, not implementation
    - System must respond to changing requirements. The trick is not to resist, but to contain the change. Funcational decomposition spreads the change
  19. tp-hk revised this gist Apr 19, 2023. 1 changed file with 11 additions and 1 deletion.
    12 changes: 11 additions & 1 deletion System Design Fundamentals.md
    Original file line number Diff line number Diff line change
    @@ -22,4 +22,14 @@
    - layers imply top-down. Each layer is also an encapsulation. Within a layer are services (entities)
    - layers (top to bottom):
    - client layer (user/another system/techs) - volatility in client technology. Try to equalize all clients -- single point of entry to system
    - business layer - volatility in changes of system behavior. Good requirement is always behavioral (leave less room for interpretation) not functional i.e. use case/sequence of activities.
    - business layer - volatility in changes of system behavior. Good requirement is always behavioral (leave less room for interpretation) not functional i.e. use case/sequence of activities.

    ### 4 Composition

    - Don't build system based on requirements, but based on use cases
    - There should be only a few core use cases, other are variations created by different interactions
    - Identify the smallest set of building blocks that satisfy the core use cases (composable design). Ideally there should be ~10 components
    - With the above, design can change but core use cases won't
    - Composable design
    - Doesn't satisfy any use case in particular
    - Features are aspects of integration, not implementation
  20. tp-hk revised this gist Mar 26, 2023. 1 changed file with 9 additions and 1 deletion.
    10 changes: 9 additions & 1 deletion Monolith to Microservices.md
    Original file line number Diff line number Diff line change
    @@ -89,4 +89,12 @@
    - Spy tools can be used to intercept/stub functionality e.g. verify email should be sent without actually sending
    - Parallel run isn't canary release, which redirect some users to new functionality.
    - Parallel run is a way to implement dark launching (function released but invisible)
    - Parallel run, canary releasing, dark launching all work to support progressive delivery
    - Parallel run, canary releasing, dark launching all work to support progressive delivery
    - Migration patterns: Decorating collaborator
    - Allow attaching functionality without knowing the underlying logic.
    - Use case: monolith returns result -> proxy will intercept, forward to new service -> new service provides additional functionality, optionally new service can make call to monolith to get more data -> new service returns decorated result
    - Where to use: when required info can be extracted from inbound request/response. Not recommended when request & response to/from monolith don't contain info needed by new service.
    - Migration patterns: Change Data Capture
    - Step: Detect any CUD operation to table, then make call to new service
    - Ways to implement change data capture: DB trigger, transaction log poller, batch delta copier
    - Caveat: unable to intercept either at decorator or strangler, and cannot change underlying codebase
  21. tp-hk revised this gist Mar 26, 2023. 1 changed file with 9 additions and 1 deletion.
    10 changes: 9 additions & 1 deletion Monolith to Microservices.md
    Original file line number Diff line number Diff line change
    @@ -81,4 +81,12 @@
    - 3. Create new implementation using the abstraction. New impl. can be microservice etc/
    - 4. Switch abstraction to use new implementation e.g. use feature flags
    - 5. Clean up old code and optionally abstraction
    - 6. Fallback: if new implementation fails, switch back to old impl.
    - 6. Fallback: if new implementation fails, switch back to old impl.
    - Migration pattern: Parallel Run
    - Both new + old impl. will be called, but only one (typically old impl.) will be considered source of truth.
    - Useful for verifying functional and non-functional parameters of new impl. especially for high risk areas
    - End goal isn't to replace the implmentations, but to reduce bugs in one of the impls.
    - Spy tools can be used to intercept/stub functionality e.g. verify email should be sent without actually sending
    - Parallel run isn't canary release, which redirect some users to new functionality.
    - Parallel run is a way to implement dark launching (function released but invisible)
    - Parallel run, canary releasing, dark launching all work to support progressive delivery
  22. tp-hk revised this gist Mar 26, 2023. 1 changed file with 10 additions and 2 deletions.
    12 changes: 10 additions & 2 deletions Monolith to Microservices.md
    Original file line number Diff line number Diff line change
    @@ -64,7 +64,7 @@
    - Migration patterns: Strangler fig application
    - New & old systems coexist, allow new code to grow incrementatlly and eventually replace old system. Easy rollback if required.
    - Useful when: no need to touch existing system/existing system is black box, works well wehn functionality to move isn't deep inside system. Existing code can still be worked on by others.
    - Steps
    - Steps:
    - 1: Identify asset to move
    - 2: Start implmentating new functionality in microservice. Deploy but not released to public. Parallel run with old code
    - 3: Redirect calls to microservice. Prereq: need to have clear inbound calls. If not, consider Branch by Abstraction pattern
    @@ -73,4 +73,12 @@
    - Migration patterns: UI composition
    - Example: Modules are migrated to MFEs one at a time; For mobile app: configs and layout of UI components is defined in declarative fashion on server side, so UI can be changed without new release
    - Migration patterns: Branch by Abstraction
    - Useful when: functionality to extract is deep inside existing system i.e. strangler fig is not suitable. Using long-lived branches with new functionality getting developed is an option but not optimal. Branch by Abstraction will be a better option.
    - Useful when: functionality to extract is deep inside existing system i.e. strangler fig is not suitable, or when changes will take a long tim. Using long-lived branches with new functionality getting developed is an option but not optimal. Branch by Abstraction will be a better option.
    - Try to use strangler fig pattern before considering this one
    - Steps:
    - 1. Create an abstraction for the functionality to be replaced
    - 2. Change existing client to use the abstraction
    - 3. Create new implementation using the abstraction. New impl. can be microservice etc/
    - 4. Switch abstraction to use new implementation e.g. use feature flags
    - 5. Clean up old code and optionally abstraction
    - 6. Fallback: if new implementation fails, switch back to old impl.
  23. tp-hk revised this gist Mar 26, 2023. 1 changed file with 9 additions and 4 deletions.
    13 changes: 9 additions & 4 deletions Monolith to Microservices.md
    Original file line number Diff line number Diff line change
    @@ -61,11 +61,16 @@
    - First thing to consider is whether monolith will be modified (more flexibility).
    - Biggest barrier is code isn't organized around business domains. Can use seam - a seam is a defined around the code to chnage, then work on new implementation, and swap after change has been made.
    - Rewrite - try salvage existing codebase first. If not, rewrite small pieces of functionality at a time and release regularly.
    - Migration patterns: Strangler fig app:
    - Migration patterns: Strangler fig application
    - New & old systems coexist, allow new code to grow incrementatlly and eventually replace old system. Easy rollback if required.
    - Useful when: no need to touch existing system/existing system is black box. Existing code can still be worked on by others.
    - Useful when: no need to touch existing system/existing system is black box, works well wehn functionality to move isn't deep inside system. Existing code can still be worked on by others.
    - Steps
    - 1: Identify asset to move
    - 2: Start implmentating new functionality in microservice. Deploy but not released to public. Parallel run with old code
    - 3: Redirect calls to microservice
    - Variation: "Shallow" extraction - Existing functionality will be exposed to MS
    - 3: Redirect calls to microservice. Prereq: need to have clear inbound calls. If not, consider Branch by Abstraction pattern
    - Variation: "Shallow" extraction - Existing functionality will be exposed to MS
    - Use HTTP proxy to redirect calls
    - Migration patterns: UI composition
    - Example: Modules are migrated to MFEs one at a time; For mobile app: configs and layout of UI components is defined in declarative fashion on server side, so UI can be changed without new release
    - Migration patterns: Branch by Abstraction
    - Useful when: functionality to extract is deep inside existing system i.e. strangler fig is not suitable. Using long-lived branches with new functionality getting developed is an option but not optimal. Branch by Abstraction will be a better option.
  24. tp-hk revised this gist Mar 26, 2023. 1 changed file with 19 additions and 3 deletions.
    22 changes: 19 additions & 3 deletions Monolith to Microservices.md
    Original file line number Diff line number Diff line change
    @@ -46,10 +46,26 @@
    - How to know if transition is working
    - Define measures to track
    - Regular checkpoints (review quantitative + qualitative measures)
    - quantitative measures e.g. number of deployments, failure rates, cycle time
    - qualitative measures e.g. team's feelings
    - Quantitative measures e.g. number of deployments, failure rates, cycle time
    - Qualitative measures e.g. team's feelings
    - Avoid sunk cost fallacy
    - Key: take small steps, be open to new approaches
    - Misc.
    - "Reuse is not a direct outcome people want. Reuse is something people hope will lead to other benefits"
    - Irreversible vs reversible decisions
    - Irreversible vs reversible decisions


    ### 3 Splitting the monolith

    - Do migration over small steps, allow going back if needed. For each step, copy code instead of changing functionality
    - First thing to consider is whether monolith will be modified (more flexibility).
    - Biggest barrier is code isn't organized around business domains. Can use seam - a seam is a defined around the code to chnage, then work on new implementation, and swap after change has been made.
    - Rewrite - try salvage existing codebase first. If not, rewrite small pieces of functionality at a time and release regularly.
    - Migration patterns: Strangler fig app:
    - New & old systems coexist, allow new code to grow incrementatlly and eventually replace old system. Easy rollback if required.
    - Useful when: no need to touch existing system/existing system is black box. Existing code can still be worked on by others.
    - Steps
    - 1: Identify asset to move
    - 2: Start implmentating new functionality in microservice. Deploy but not released to public. Parallel run with old code
    - 3: Redirect calls to microservice
    - Variation: "Shallow" extraction - Existing functionality will be exposed to MS
  25. tp-hk revised this gist Mar 26, 2023. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion System Design Fundamentals.md
    Original file line number Diff line number Diff line change
    @@ -22,4 +22,4 @@
    - layers imply top-down. Each layer is also an encapsulation. Within a layer are services (entities)
    - layers (top to bottom):
    - client layer (user/another system/techs) - volatility in client technology. Try to equalize all clients -- single point of entry to system
    - business layer - volatility in changes of system behavior. Good requirement is always behavioral (leave less room for interpretation) not functional i.e. use case.
    - business layer - volatility in changes of system behavior. Good requirement is always behavioral (leave less room for interpretation) not functional i.e. use case/sequence of activities.
  26. tp-hk revised this gist Mar 25, 2023. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion System Design Fundamentals.md
    Original file line number Diff line number Diff line change
    @@ -21,4 +21,5 @@
    - any interaction between areas of volatility?
    - layers imply top-down. Each layer is also an encapsulation. Within a layer are services (entities)
    - layers (top to bottom):
    - client layer (user/another system/techs) - client technology volatility.
    - client layer (user/another system/techs) - volatility in client technology. Try to equalize all clients -- single point of entry to system
    - business layer - volatility in changes of system behavior. Good requirement is always behavioral (leave less room for interpretation) not functional i.e. use case.
  27. tp-hk revised this gist Mar 25, 2023. 1 changed file with 11 additions and 2 deletions.
    13 changes: 11 additions & 2 deletions System Design Fundamentals.md
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    # System Design Fundamentals.md (2023 H1)
    # System Design Fundamentals - Juval Lowy (2023 H1)

    ---

    @@ -12,4 +12,13 @@

    - Decompose based on volatility
    - Each areas of change is encapsulated (in a vault) - each represents an area of volatility
    - No block if no volatility
    - No block if no volatility

    ### 3 Using layers

    - Ask:
    - are volatilities in software system?
    - any interaction between areas of volatility?
    - layers imply top-down. Each layer is also an encapsulation. Within a layer are services (entities)
    - layers (top to bottom):
    - client layer (user/another system/techs) - client technology volatility.
  28. tp-hk revised this gist Mar 23, 2023. No changes.
  29. tp-hk revised this gist Mar 23, 2023. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion System Design Fundamentals.md
    Original file line number Diff line number Diff line change
    @@ -11,4 +11,5 @@
    ### 2 What to do

    - Decompose based on volatility
    - Each areas of change is encapsulated (in a vault)
    - Each areas of change is encapsulated (in a vault) - each represents an area of volatility
    - No block if no volatility
  30. tp-hk revised this gist Mar 21, 2023. 2 changed files with 3 additions and 2 deletions.
    3 changes: 2 additions & 1 deletion System Design Fundamentals.md
    Original file line number Diff line number Diff line change
    @@ -10,4 +10,5 @@

    ### 2 What to do

    - ...
    - Decompose based on volatility
    - Each areas of change is encapsulated (in a vault)
    2 changes: 1 addition & 1 deletion _Tech Books Summary_.md
    Original file line number Diff line number Diff line change
    @@ -1 +1 @@
    # Somewhat curated sumamries of technical books. Take it with a grain of salt
    # Somewhat curated sumamries of technical materials. Take it with a grain of salt