Update README.md
This commit is contained in:
		@@ -11,27 +11,33 @@ tags:
 | 
				
			|||||||
---
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Name / classification
 | 
					## Name / classification
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Filterer
 | 
					Filterer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Intent
 | 
					## Intent
 | 
				
			||||||
The intent of this design pattern is to introduce a functional interface that will add a functionality for container-like objects to easily return filtered versions of themselves.
 | 
					
 | 
				
			||||||
 | 
					The intent of this design pattern is to introduce a functional interface that will add a 
 | 
				
			||||||
 | 
					functionality for container-like objects to easily return filtered versions of themselves.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Explanation
 | 
					## Explanation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Real world example
 | 
					Real world example
 | 
				
			||||||
 | 
					
 | 
				
			||||||
> We are designing a threat(malware) detection system. We can have different types of threats and systems. We have a requirement that
 | 
					> We are designing a threat (malware) detection software which can analyze target systems for 
 | 
				
			||||||
> system should be aware of threats that are present in it. In the design we have to take into consideration that new Threat types can be
 | 
					> threats that are present in it. In the design we have to take into consideration that new 
 | 
				
			||||||
> added later. Also there is a requirement that a system can filter itself based on the threats that it possesses (system acts as container-like object for threats).
 | 
					> Threat types can be added later. Additionally, there is a requirement that the threat detection 
 | 
				
			||||||
>
 | 
					> system can filter the detected threats based on different criteria (the target system acts as 
 | 
				
			||||||
 | 
					> container-like object for threats).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
In plain words
 | 
					In plain words
 | 
				
			||||||
 | 
					
 | 
				
			||||||
> We need to be able to filter different types of systems(container-like objects) based on properties of Threats that they contain.
 | 
					> Filterer pattern is a design pattern that helps container-like objects return filtered versions 
 | 
				
			||||||
> Adding new properties for Threats should be easy (we still need the ability to filter by those new properties).
 | 
					> of themselves. 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
**Programmatic Example**
 | 
					**Programmatic Example**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
To model the threat detection example presented above we introduce `Threat` and `ThreatAwareSystem` interfaces.
 | 
					To model the threat detection example presented above we introduce `Threat` and `ThreatAwareSystem` 
 | 
				
			||||||
 | 
					interfaces.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```java
 | 
					```java
 | 
				
			||||||
public interface Threat {
 | 
					public interface Threat {
 | 
				
			||||||
@@ -47,19 +53,26 @@ public interface ThreatAwareSystem {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Notice the `filtered` method that returns instance of `Filterer` interface which is defined as:
 | 
					Notice the `filtered` method that returns instance of `Filterer` interface which is defined as:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```java
 | 
					```java
 | 
				
			||||||
@FunctionalInterface
 | 
					@FunctionalInterface
 | 
				
			||||||
public interface Filterer<G, E> {
 | 
					public interface Filterer<G, E> {
 | 
				
			||||||
  G by(Predicate<? super E> predicate);
 | 
					  G by(Predicate<? super E> predicate);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
it is used to fulfill the requirement for system to be able to filter itself based on threat properties.
 | 
					 | 
				
			||||||
The container-like object (`ThreatAwareSystem` in our case) needs to have a method that returns an instance of `Filterer`. This helper interface gives 
 | 
					 | 
				
			||||||
ability to covariantly specify a lower bound of contravariant `Predicate` in the subinterfaces of interfaces representing the container-like objects.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
In our example we will be able to pass a predicate that takes `? extends Threat` object and return `?  extends ThreatAwareSystem`
 | 
					It is used to fulfill the requirement for system to be able to filter itself based on threat 
 | 
				
			||||||
from `Filtered::by` method. A simple implementation of `ThreatAwareSystem` :
 | 
					properties. The container-like object (`ThreatAwareSystem` in our case) needs to have a method that 
 | 
				
			||||||
 | 
					returns an instance of `Filterer`. This helper interface gives ability to covariantly specify a 
 | 
				
			||||||
 | 
					lower bound of contravariant `Predicate` in the subinterfaces of interfaces representing the 
 | 
				
			||||||
 | 
					container-like objects.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					In our example we will be able to pass a predicate that takes `? extends Threat` object and 
 | 
				
			||||||
 | 
					return `?  extends ThreatAwareSystem` from `Filtered::by` method. A simple implementation 
 | 
				
			||||||
 | 
					of `ThreatAwareSystem`:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```java
 | 
					```java
 | 
				
			||||||
public class SimpleThreatAwareSystem implements ThreatAwareSystem {
 | 
					public class SimpleThreatAwareSystem implements ThreatAwareSystem {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -97,15 +110,21 @@ public class SimpleThreatAwareSystem implements ThreatAwareSystem {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
the `filtered` method is overridden to filter the threats list by given predicate.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
Now if we introduce a new subtype of `Threat` interface that adds probability with which given threat can appear :
 | 
					The `filtered` method is overridden to filter the threats list by given predicate.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Now if we introduce a new subtype of `Threat` interface that adds probability with which given 
 | 
				
			||||||
 | 
					threat can appear:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```java
 | 
					```java
 | 
				
			||||||
public interface ProbableThreat extends Threat {
 | 
					public interface ProbableThreat extends Threat {
 | 
				
			||||||
  double probability();
 | 
					  double probability();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
we can also introduce a new interface that represents a system that is aware of threats with their probabilities :
 | 
					
 | 
				
			||||||
 | 
					We can also introduce a new interface that represents a system that is aware of threats with their 
 | 
				
			||||||
 | 
					probabilities:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
````java
 | 
					````java
 | 
				
			||||||
public interface ProbabilisticThreatAwareSystem extends ThreatAwareSystem {
 | 
					public interface ProbabilisticThreatAwareSystem extends ThreatAwareSystem {
 | 
				
			||||||
  @Override
 | 
					  @Override
 | 
				
			||||||
@@ -115,9 +134,12 @@ public interface ProbabilisticThreatAwareSystem extends ThreatAwareSystem {
 | 
				
			|||||||
  Filterer<? extends ProbabilisticThreatAwareSystem, ? extends ProbableThreat> filtered();
 | 
					  Filterer<? extends ProbabilisticThreatAwareSystem, ? extends ProbableThreat> filtered();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
````
 | 
					````
 | 
				
			||||||
Notice how we override the `filtered` method in `ProbabilisticThreatAwareSystem` and specify different return covariant type
 | 
					
 | 
				
			||||||
by specifying different generic types. Our interfaces are clean and not cluttered by default implementations. We
 | 
					Notice how we override the `filtered` method in `ProbabilisticThreatAwareSystem` and specify 
 | 
				
			||||||
we will be able to filter `ProbabilisticThreatAwareSystem` by `ProbableThreat` properties :
 | 
					different return covariant type by specifying different generic types. Our interfaces are clean and 
 | 
				
			||||||
 | 
					not cluttered by default implementations. We we will be able to filter 
 | 
				
			||||||
 | 
					`ProbabilisticThreatAwareSystem` by `ProbableThreat` properties:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```java
 | 
					```java
 | 
				
			||||||
public class SimpleProbabilisticThreatAwareSystem implements ProbabilisticThreatAwareSystem {
 | 
					public class SimpleProbabilisticThreatAwareSystem implements ProbabilisticThreatAwareSystem {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -157,6 +179,7 @@ public class SimpleProbabilisticThreatAwareSystem implements ProbabilisticThreat
 | 
				
			|||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Now if we want filter `ThreatAwareSystem` by threat type we can do:
 | 
					Now if we want filter `ThreatAwareSystem` by threat type we can do:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```java
 | 
					```java
 | 
				
			||||||
Threat rootkit = new SimpleThreat(ThreatType.ROOTKIT, 1, "Simple-Rootkit");
 | 
					Threat rootkit = new SimpleThreat(ThreatType.ROOTKIT, 1, "Simple-Rootkit");
 | 
				
			||||||
Threat trojan = new SimpleThreat(ThreatType.TROJAN, 2, "Simple-Trojan");
 | 
					Threat trojan = new SimpleThreat(ThreatType.TROJAN, 2, "Simple-Trojan");
 | 
				
			||||||
@@ -167,7 +190,9 @@ ThreatAwareSystem threatAwareSystem = new SimpleThreatAwareSystem("System-1", th
 | 
				
			|||||||
ThreatAwareSystem rootkitThreatAwareSystem = threatAwareSystem.filtered()
 | 
					ThreatAwareSystem rootkitThreatAwareSystem = threatAwareSystem.filtered()
 | 
				
			||||||
           .by(threat -> threat.type() == ThreatType.ROOTKIT);
 | 
					           .by(threat -> threat.type() == ThreatType.ROOTKIT);
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
or if we want to filter `ProbabilisticThreatAwareSystem` :
 | 
					
 | 
				
			||||||
 | 
					Or if we want to filter `ProbabilisticThreatAwareSystem`:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```java
 | 
					```java
 | 
				
			||||||
ProbableThreat malwareTroyan = new SimpleProbableThreat("Troyan-ArcBomb", 1, ThreatType.TROJAN, 0.99);
 | 
					ProbableThreat malwareTroyan = new SimpleProbableThreat("Troyan-ArcBomb", 1, ThreatType.TROJAN, 0.99);
 | 
				
			||||||
ProbableThreat rootkit = new SimpleProbableThreat("Rootkit-System", 2, ThreatType.ROOTKIT, 0.8);
 | 
					ProbableThreat rootkit = new SimpleProbableThreat("Rootkit-System", 2, ThreatType.ROOTKIT, 0.8);
 | 
				
			||||||
@@ -178,27 +203,37 @@ ProbabilisticThreatAwareSystem simpleProbabilisticThreatAwareSystem =new SimpleP
 | 
				
			|||||||
ProbabilisticThreatAwareSystem filtered = simpleProbabilisticThreatAwareSystem.filtered()
 | 
					ProbabilisticThreatAwareSystem filtered = simpleProbabilisticThreatAwareSystem.filtered()
 | 
				
			||||||
           .by(probableThreat -> Double.compare(probableThreat.probability(), 0.99) == 0);
 | 
					           .by(probableThreat -> Double.compare(probableThreat.probability(), 0.99) == 0);
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Class diagram
 | 
					## Class diagram
 | 
				
			||||||
 | 
					
 | 
				
			||||||

 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Applicability
 | 
					## Applicability
 | 
				
			||||||
Pattern can be used when working with container-like objects that use subtyping, instead of parametrizing(generics) for extensible class structure.
 | 
					
 | 
				
			||||||
It enables you to easily extend filtering ability of container-like objects as business requirements change.
 | 
					Pattern can be used when working with container-like objects that use subtyping, instead of 
 | 
				
			||||||
 | 
					parametrizing (generics) for extensible class structure. It enables you to easily extend filtering 
 | 
				
			||||||
 | 
					ability of container-like objects as business requirements change.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Tutorials
 | 
					## Tutorials
 | 
				
			||||||
 | 
					
 | 
				
			||||||
* [Article about Filterer pattern posted on it's author's blog](https://blog.tlinkowski.pl/2018/filterer-pattern/)
 | 
					* [Article about Filterer pattern posted on it's author's blog](https://blog.tlinkowski.pl/2018/filterer-pattern/)
 | 
				
			||||||
* [Application of Filterer pattern in domain of text analysis](https://www.javacodegeeks.com/2019/02/filterer-pattern-10-steps.html)
 | 
					* [Application of Filterer pattern in domain of text analysis](https://www.javacodegeeks.com/2019/02/filterer-pattern-10-steps.html)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Known uses
 | 
					## Known uses
 | 
				
			||||||
One of the uses is present on the blog presented in [this](https://www.javacodegeeks.com/2019/02/filterer-pattern-10-steps.html) link. 
 | 
					
 | 
				
			||||||
It presents how to use `Filterer` pattern to create text issue analyzer with support for test cases used for unit testing.
 | 
					One of the uses is present on the blog presented in 
 | 
				
			||||||
 | 
					[this](https://www.javacodegeeks.com/2019/02/filterer-pattern-10-steps.html) link. It presents how 
 | 
				
			||||||
 | 
					to use `Filterer` pattern to create text issue analyzer with support for test cases used for unit 
 | 
				
			||||||
 | 
					testing.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Consequences
 | 
					## Consequences
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Pros:
 | 
					Pros:
 | 
				
			||||||
 * you can easily introduce new subtypes for container-like objects and subtypes for objects that are contained within them and still be able to filter easily be new properties of those new subtypes.
 | 
					 * You can easily introduce new subtypes for container-like objects and subtypes for objects that are contained within them and still be able to filter easily be new properties of those new subtypes.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Cons:
 | 
					Cons:
 | 
				
			||||||
 * covariant return types mixed with generics can be sometimes tricky
 | 
					 * Covariant return types mixed with generics can be sometimes tricky
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Credits
 | 
					## Credits
 | 
				
			||||||
 | 
					
 | 
				
			||||||
* Author of the pattern : [Tomasz Linkowski](https://tlinkowski.pl/)
 | 
					* Author of the pattern : [Tomasz Linkowski](https://tlinkowski.pl/)
 | 
				
			||||||
		Reference in New Issue
	
	Block a user