-
-
Notifications
You must be signed in to change notification settings - Fork 26.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add simple implementation for strangler pattern. * Add strangler pattern in pom.xml. * change package name * Revert "change package name" This reverts commit 430bd90. * Code review for strangler Delete final of method parameters. Add final to private members. Change package name. * Revert "Code review for strangler" This reverts commit d506356. * Revert "Revert "Code review for strangler"" This reverts commit c8fd65f. * Remove unnecessary files
- Loading branch information
Showing
19 changed files
with
927 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
--- | ||
layout: pattern | ||
title: Strangler | ||
folder: strangler | ||
permalink: /patterns/strangler/ | ||
categories: Structural | ||
tags: | ||
- Extensibility | ||
--- | ||
|
||
## Intent | ||
Incrementally migrate a legacy system by gradually replacing specific pieces of functionality | ||
with new applications and services. As features from the legacy system are replaced, the new | ||
system eventually covers all the old system's features and may has its own new features, then | ||
strangling the old system and allowing you to decommission it. | ||
|
||
## Class diagram | ||
![alt text](./etc/strangler.png "Strangler") | ||
|
||
## Applicability | ||
This strangler pattern is a safe way to phase one thing out for something better, cheaper, or | ||
more expandable. Especially when you want to update legacy system with new techniques and need | ||
continuously develop new features at the same time. Note that this pattern indeed need extra effort, | ||
so usually use it when the system is not so simple. | ||
|
||
## Credits | ||
|
||
* [Strangler pattern](https://docs.microsoft.com/en-us/azure/architecture/patterns/strangler#context-and-problem) | ||
* [Legacy Application Strangulation : Case Studies](https://paulhammant.com/2013/07/14/legacy-application-strangulation-case-studies/) | ||
|
||
|
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
@startuml | ||
|
||
package com.iluwatar.strangler { | ||
class App { | ||
+ main(args : String[]) {static} | ||
} | ||
|
||
class OldArithmetic { | ||
- LOGGER : Logger {static} | ||
- VERSION : String {static} | ||
- source : OldSource | ||
+ sum(nums : int...) | ||
+ mul(nums : int...) | ||
} | ||
|
||
class HalfArithmetic { | ||
- LOGGER : Logger {static} | ||
- VERSION : String {static} | ||
- oldSource : OldSource | ||
- newSource : HalfSource | ||
+ sum(nums : int...) | ||
+ mul(nums : int...) | ||
+ ifHasZero(nums : int...) | ||
} | ||
|
||
class NewArithmetic { | ||
- LOGGER : Logger {static} | ||
- VERSION : String {static} | ||
- source : NewSource | ||
+ sum(nums : int...) | ||
+ mul(nums : int...) | ||
+ ifHasZero(nums : int...) | ||
} | ||
|
||
class OldSource { | ||
- LOGGER : Logger {static} | ||
- VERSION : String {static} | ||
+ accumulateSum(nums : int...) | ||
+ accumulateMul(nums : int...) | ||
} | ||
|
||
class HalfSource { | ||
- LOGGER : Logger {static} | ||
- VERSION : String {static} | ||
+ accumulateSum(nums : int...) | ||
+ ifNonZero(nums : int...) | ||
} | ||
|
||
class NewSource { | ||
- LOGGER : Logger {static} | ||
- VERSION : String {static} | ||
+ accumulateSum(nums : int...) | ||
+ accumulateMul(nums : int...) | ||
+ ifNonZero(nums : int...) | ||
} | ||
} | ||
OldArithmetic o--> OldSource | ||
HalfArithmetic o--> OldSource | ||
HalfArithmetic o--> HalfSource | ||
NewArithmetic o--> NewSource | ||
@enduml |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!-- | ||
The MIT License | ||
Copyright © 2014-2019 Ilkka Seppälä | ||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
The above copyright notice and this permission notice shall be included in | ||
all copies or substantial portions of the Software. | ||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
THE SOFTWARE. | ||
--> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<parent> | ||
<artifactId>java-design-patterns</artifactId> | ||
<groupId>com.iluwatar</groupId> | ||
<version>1.23.0-SNAPSHOT</version> | ||
</parent> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<artifactId>strangler</artifactId> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>org.junit.jupiter</groupId> | ||
<artifactId>junit-jupiter-engine</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
</dependencies> | ||
<build> | ||
<plugins> | ||
<plugin> | ||
<groupId>org.apache.maven.plugins</groupId> | ||
<artifactId>maven-assembly-plugin</artifactId> | ||
<executions> | ||
<execution> | ||
<configuration> | ||
<archive> | ||
<manifest> | ||
<mainClass>com.iluwatar.strangler.App</mainClass> | ||
</manifest> | ||
</archive> | ||
</configuration> | ||
</execution> | ||
</executions> | ||
</plugin> | ||
</plugins> | ||
</build> | ||
|
||
|
||
</project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
/* | ||
* The MIT License | ||
* Copyright © 2014-2019 Ilkka Seppälä | ||
* | ||
* Permission is hereby granted, free of charge, to any person obtaining a copy | ||
* of this software and associated documentation files (the "Software"), to deal | ||
* in the Software without restriction, including without limitation the rights | ||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
* copies of the Software, and to permit persons to whom the Software is | ||
* furnished to do so, subject to the following conditions: | ||
* | ||
* The above copyright notice and this permission notice shall be included in | ||
* all copies or substantial portions of the Software. | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
* THE SOFTWARE. | ||
*/ | ||
|
||
package com.iluwatar.strangler; | ||
|
||
/** | ||
* | ||
* <p>The Strangler pattern is a software design pattern that incrementally migrate a legacy | ||
* system by gradually replacing specific pieces of functionality with new applications and | ||
* services. As features from the legacy system are replaced, the new system eventually | ||
* replaces all of the old system's features, strangling the old system and allowing you | ||
* to decommission it.</p> | ||
* | ||
* <p>This pattern is not only about updating but also enhancement.</p> | ||
* | ||
* <p>In this example, {@link OldArithmetic} indicates old system and its implementation depends | ||
* on its source ({@link OldSource}). Now we tend to update system with new techniques and | ||
* new features. In reality, the system may too complex, so usually need gradual migration. | ||
* {@link HalfArithmetic} indicates system in the process of migration, its implementation | ||
* depends on old one ({@link OldSource}) and under development one ({@link HalfSource}). The | ||
* {@link HalfSource} covers part of {@link OldSource} and add new functionality. You can release | ||
* this version system with new features, which also supports old version system functionalities. | ||
* After whole migration, the new system ({@link NewArithmetic}) only depends on new source | ||
* ({@link NewSource}).</p> | ||
* | ||
*/ | ||
public class App { | ||
/** | ||
* Program entry point. | ||
* @param args command line args | ||
*/ | ||
public static void main(final String[] args) { | ||
final var nums = new int[]{1, 2, 3, 4, 5}; | ||
//Before migration | ||
final var oldSystem = new OldArithmetic(new OldSource()); | ||
oldSystem.sum(nums); | ||
oldSystem.mul(nums); | ||
//In process of migration | ||
final var halfSystem = new HalfArithmetic(new HalfSource(), new OldSource()); | ||
halfSystem.sum(nums); | ||
halfSystem.mul(nums); | ||
halfSystem.ifHasZero(nums); | ||
//After migration | ||
final var newSystem = new NewArithmetic(new NewSource()); | ||
newSystem.sum(nums); | ||
newSystem.mul(nums); | ||
newSystem.ifHasZero(nums); | ||
} | ||
} |
74 changes: 74 additions & 0 deletions
74
strangler/src/main/java/com/iluwatar/strangler/HalfArithmetic.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
/* | ||
* The MIT License | ||
* Copyright © 2014-2019 Ilkka Seppälä | ||
* | ||
* Permission is hereby granted, free of charge, to any person obtaining a copy | ||
* of this software and associated documentation files (the "Software"), to deal | ||
* in the Software without restriction, including without limitation the rights | ||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
* copies of the Software, and to permit persons to whom the Software is | ||
* furnished to do so, subject to the following conditions: | ||
* | ||
* The above copyright notice and this permission notice shall be included in | ||
* all copies or substantial portions of the Software. | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
* THE SOFTWARE. | ||
*/ | ||
|
||
package com.iluwatar.strangler; | ||
|
||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
/** | ||
* System under migration. Depends on old version source ({@link OldSource}) and | ||
* developing one ({@link HalfSource}). | ||
*/ | ||
public class HalfArithmetic { | ||
private static final Logger LOGGER = LoggerFactory.getLogger(HalfArithmetic.class); | ||
private static final String VERSION = "1.5"; | ||
|
||
private final HalfSource newSource; | ||
private final OldSource oldSource; | ||
|
||
public HalfArithmetic(HalfSource newSource, OldSource oldSource) { | ||
this.newSource = newSource; | ||
this.oldSource = oldSource; | ||
} | ||
|
||
/** | ||
* Accumulate sum. | ||
* @param nums numbers need to add together | ||
* @return accumulate sum | ||
*/ | ||
public int sum(int... nums) { | ||
LOGGER.info("Arithmetic sum {}", VERSION); | ||
return newSource.accumulateSum(nums); | ||
} | ||
|
||
/** | ||
* Accumulate multiplication. | ||
* @param nums numbers need to multiply together | ||
* @return accumulate multiplication | ||
*/ | ||
public int mul(int... nums) { | ||
LOGGER.info("Arithmetic mul {}", VERSION); | ||
return oldSource.accumulateMul(nums); | ||
} | ||
|
||
/** | ||
* Chech if has any zero. | ||
* @param nums numbers need to check | ||
* @return if has any zero, return true, else, return false | ||
*/ | ||
public boolean ifHasZero(int... nums) { | ||
LOGGER.info("Arithmetic check zero {}", VERSION); | ||
return !newSource.ifNonZero(nums); | ||
} | ||
} |
54 changes: 54 additions & 0 deletions
54
strangler/src/main/java/com/iluwatar/strangler/HalfSource.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
/* | ||
* The MIT License | ||
* Copyright © 2014-2019 Ilkka Seppälä | ||
* | ||
* Permission is hereby granted, free of charge, to any person obtaining a copy | ||
* of this software and associated documentation files (the "Software"), to deal | ||
* in the Software without restriction, including without limitation the rights | ||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
* copies of the Software, and to permit persons to whom the Software is | ||
* furnished to do so, subject to the following conditions: | ||
* | ||
* The above copyright notice and this permission notice shall be included in | ||
* all copies or substantial portions of the Software. | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
* THE SOFTWARE. | ||
*/ | ||
|
||
package com.iluwatar.strangler; | ||
|
||
import java.util.Arrays; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
/** | ||
* Source under development. Replace part of old source and has added some new features. | ||
*/ | ||
public class HalfSource { | ||
private static final Logger LOGGER = LoggerFactory.getLogger(HalfSource.class); | ||
private static final String VERSION = "1.5"; | ||
|
||
/** | ||
* Implement accumulate sum with new technique. | ||
* Replace old one in {@link OldSource} | ||
*/ | ||
public int accumulateSum(int... nums) { | ||
LOGGER.info("Source module {}", VERSION); | ||
return Arrays.stream(nums).reduce(0, Integer::sum); | ||
} | ||
|
||
/** | ||
* Check if all number is not zero. | ||
* New feature. | ||
*/ | ||
public boolean ifNonZero(int... nums) { | ||
LOGGER.info("Source module {}", VERSION); | ||
return Arrays.stream(nums).allMatch(num -> num != 0); | ||
} | ||
} |
Oops, something went wrong.