From 1e1fb7dc22816d368a17b5944a812d94de8600db Mon Sep 17 00:00:00 2001 From: Jack Hodges Date: Sun, 8 Oct 2023 17:16:33 +1100 Subject: [PATCH 1/3] Added documentation for Feature Toggle design pattern --- feature-toggle/README.md | 63 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 59 insertions(+), 4 deletions(-) diff --git a/feature-toggle/README.md b/feature-toggle/README.md index 915a255690da..ec78bab8edaa 100644 --- a/feature-toggle/README.md +++ b/feature-toggle/README.md @@ -10,10 +10,53 @@ tag: Feature Flag ## Intent -Used to switch code execution paths based on properties or groupings. Allowing new features to be released, tested -and rolled out. Allowing switching back to the older feature quickly if needed. It should be noted that this pattern, -can easily introduce code complexity. There is also cause for concern that the old feature that the toggle is eventually -going to phase out is never removed, causing redundant code smells and increased maintainability. +A technique used in software development to control and manage the rollout of specific features or functionality in a +program without changing the code. It can act as an on/off switch for features depending on the status or properties of +other values in the program. This is similar to A/B testing, where features are rolled out based on properties such as +location or device. Implementing this design pattern can increase code complexity, and it is important to remember to +remove redundant code if this design pattern is being used to phase out a system or feature. + +## Explanation +Real-world Example +> This design pattern works really well in any sort of development, in particular mobile development. Say you want to +> introduce a feature such as dark mode, but you want to ensure that the feature works correctly and don't want to roll +> out the feature to everyone immediately. You write in the code, and have it switched off as default. From here, it is +> easy to turn on the code for specific users based on selection criteria, or randomly. This will also allow the feature +> to be turned off easily without any drastic changes to the code, or any need for redeployment or updates. + +In plain words +> Feature Toggle is a way to introduce new features gradually instead of deployment all at once. + +Wikipedia says +> A feature toggle in software development provides an alternative to maintaining multiple feature branches in source +> code. A condition within the code enables or disables a feature during runtime. In agile settings the toggle is +> used in production, to switch on the feature on demand, for some or all the users. + +## Programmatic Example +This example shows Java code that allows a feature to show when it is enabled by the developer, and when a user is a +Premium member of the application. This is useful for subscription locked features. +```java +public class FeatureToggleExample { + // Bool for feature enabled or disabled + private static boolean isNewFeatureEnabled = false; + + public static void main(String[] args) { + boolean userIsPremium = true; // Example: Check if the user is a premium user + + // Check if the new feature should be enabled for the user + if (userIsPremium && isNewFeatureEnabled) { + // User is premium and the new feature is enabled + showNewFeature(); + } + } + + private static void showNewFeature() { + // If user is allowed to see locked feature, this is where the code would go + } +} +``` +The code shows how simple it is to implement this design pattern, and the criteria can be further refined or broadened +should the developers choose to do so. ## Class diagram ![alt text](./etc/feature-toggle.png "Feature Toggle") @@ -24,7 +67,19 @@ Use the Feature Toggle pattern when * Giving different features to different users. * Rolling out a new feature incrementally. * Switching between development and production environments. +* Quickly disable problematic features +* External management of feature deployment +* Ability to maintain multiple version releases of a feature +* 'Hidden' deployment, releasing a feature in code for designated testing but not publicly making it available + +## Consequences +Consequences involved with using the Feature Toggle pattern + +* Code complexity is increased +* Testing of multiple states is harder and more time-consuming +* Confusion between friends on why features are missing ## Credits * [Martin Fowler 29 October 2010 (2010-10-29).](http://martinfowler.com/bliki/FeatureToggle.html) +* [Feature Toggle - Java Design Patterns](https://java-design-patterns.com/patterns/feature-toggle/) From 1b2a8d8704cdd87fcf16f05935353367fec32624 Mon Sep 17 00:00:00 2001 From: Jack Hodges Date: Sun, 8 Oct 2023 17:20:10 +1100 Subject: [PATCH 2/3] Explanation for Feature Toggle Issue #2230 finished, added intent, explanation, programmatic example, applicability and consequences --- feature-toggle/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/feature-toggle/README.md b/feature-toggle/README.md index ec78bab8edaa..982108bc7440 100644 --- a/feature-toggle/README.md +++ b/feature-toggle/README.md @@ -78,6 +78,7 @@ Consequences involved with using the Feature Toggle pattern * Code complexity is increased * Testing of multiple states is harder and more time-consuming * Confusion between friends on why features are missing +* Keeping documentation up to date with all features can be difficult ## Credits From ad65d8beb11f6bc67035a0d18ef177bf02af8076 Mon Sep 17 00:00:00 2001 From: Jack Hodges Date: Wed, 18 Oct 2023 11:00:51 +1100 Subject: [PATCH 3/3] Explanation for Intercepting Filter #2236 finished --- intercepting-filter/README.md | 149 ++++++++++++++++++++++++++++++++-- 1 file changed, 144 insertions(+), 5 deletions(-) diff --git a/intercepting-filter/README.md b/intercepting-filter/README.md index 87339cfab069..3883fcd03355 100644 --- a/intercepting-filter/README.md +++ b/intercepting-filter/README.md @@ -7,8 +7,136 @@ tag: --- ## Intent -Provide pluggable filters to conduct necessary pre-processing and -post-processing to requests from a client to a target +An intercepting filter is a useful Java Design Pattern used when you want to pre-process +or post-process a request in an application. These filters are created and applied to the +request before it is given to the target application. Such examples of uses include authentication, +which is necessary to be processed before the request is given to the application. + +## Explanation +Real-world Example +> An example of using the Intercepting Filter design pattern is relevant when making an ecommerce +> platform. It is important to implement various filters for authentication of account, authentication +> of payment, logging and caching. Important types of filters in this example are authentication, logging, +> security, and caching filters. + +In plain words +> An intercepting filter in Java is like a series of security checkpoints for requests and responses in a +> software application. It checks and processes data as it comes in and goes out, helping with tasks like +> authentication, logging, and security, while keeping the core application safe and clean. + +Wikipedia says +> Intercepting Filter is a Java pattern which creates pluggable filters to process common services in a +> standard manner without requiring changes to core request processing code. + +## Programmatic Example +As an example, we can create a basic Filter class and define an Authentication Filter. The filter has missing logic, +but +```java +// 1. Define a Filter interface +interface Filter { + void runFilter(String request); +} +// 2. Create a Authentication filter +class AuthenticationFilter implements Filter { + public void runFilter(String request) { + // Authentication logic would be passed in here + if (request.contains("authenticated=true")) { + System.out.println("Authentication successful for request: " + request); + } else { + System.out.println("Authentication failed for request: " + request); + } + } +} +// 3. Create a Client to send requests and activate the filter +class Client { + // create an instance of the filter in the Client class + private Filter filter; + + // create constructor + public Client(Filter filter) { + this.filter = filter; + } + + // send the String request to the filter, the request does not have to be a string + // it can be anything + public void sendRequest(String request) { + filter.runFilter(request); + } +} +// 4. Demonstrate the Authentication Filter +public class AuthenticationFilterExample { + public static void main(String[] args) { + Filter authenticationFilter = new AuthenticationFilter(); + Client client = new Client(authenticationFilter); + + // Simulate requests for false + client.sendRequest("GET /public-page"); + // this request would come back as true as the link includes an argument + // for successful authentication + client.sendRequest("GET /private-page?authenticated=true"); + } +} +``` +This is a basic example of how to implement the skeleton of a filter. The authentication logic in AuthenticationFilterExample is missing, but can be filled into the gaps. + +Additionally, the client can be setup to run multiple filters on its request using a For loop populated with filters as can be seen below: +```java +// 1. Define a Filter interface +interface Filter { + void runFilter(String request); +} + +// 2. Create an Authentication filter +class AuthenticationFilter implements Filter { + public void runFilter(String request) { + // Authentication logic would be placed here + if (request.contains("authenticated=true")) { + System.out.println("Authentication successful for request: " + request); + } else { + System.out.println("Authentication failed for request: " + request); + } + } +} + +// 3. Create a Client to send requests and activate multiple filters +class Client { + // create a list of filters in the Client class + private List filters = new ArrayList<>(); + + // add filters to the list + public void addFilter(Filter filter) { + filters.add(filter); + } + + // send the request through all the filters + public void sendRequest(String request) { + for (Filter filter : filters) { + filter.runFilter(request); + } + } +} + +// 4. Demonstrate multiple filters +public class MultipleFiltersExample { + public static void main(String[] args) { + // Create a client + Client client = new Client(); + + // Add filters to the client + Filter authenticationFilter = new AuthenticationFilter(); + client.addFilter(authenticationFilter); + + // Add more filters as needed + // Filter anotherFilter = new AnotherFilter(); + // client.addFilter(anotherFilter); + + // Simulate requests + client.sendRequest("GET /public-page"); + client.sendRequest("GET /private-page?authenticated=true"); + } +} +``` +This method allows quick and easy manipulation and checking of data before authenticating a login or finishing some other sort of action. ## Class diagram ![alt text](./etc/intercepting-filter.png "Intercepting Filter") @@ -16,9 +144,20 @@ post-processing to requests from a client to a target ## Applicability Use the Intercepting Filter pattern when -* a system uses pre-processing or post-processing requests -* a system should do the authentication/ authorization/ logging or tracking of request and then pass the requests to corresponding handlers -* you want a modular approach to configuring pre-processing and post-processing schemes +* A program needs to pre-process or post-process data +* A system needs authorisation/authentication services to access sensitive data +* You want to log/audit requests or responses for debugging or storing purposes, such as timestamps and user actions +* You want to transform data of a type to another type before it is given to the end process +* You want to implement specific exception handling + +## Consequences +Consequences that come with implementing Intercepting Filter + +* Increase in code complexity, diminishing ease of readability +* Can have issues in the order that filters are applied if order is important +* Applying multiple filters to a request can create a delay in response time +* Testing the effects of multiple filters on a request can be hard +* Compatibility and version management can be difficult if you have a lot of filters ## Tutorials