Skip to content

Commit

Permalink
Pr/1235 Review (#1250)
Browse files Browse the repository at this point in the history
* 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
ZhouSky committed Jul 4, 2020
1 parent 5192beb commit 6fe219d
Show file tree
Hide file tree
Showing 19 changed files with 927 additions and 0 deletions.
1 change: 1 addition & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@
<module>combinator</module>
<module>update-method</module>
<module>leader-followers</module>
<module>strangler</module>
<module>arrange-act-assert</module>
</modules>

Expand Down
31 changes: 31 additions & 0 deletions strangler/README.md
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/)


Binary file added strangler/etc/strangler.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
61 changes: 61 additions & 0 deletions strangler/etc/strangler.puml
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
66 changes: 66 additions & 0 deletions strangler/pom.xml
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>
69 changes: 69 additions & 0 deletions strangler/src/main/java/com/iluwatar/strangler/App.java
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 strangler/src/main/java/com/iluwatar/strangler/HalfArithmetic.java
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 strangler/src/main/java/com/iluwatar/strangler/HalfSource.java
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);
}
}

0 comments on commit 6fe219d

Please sign in to comment.