Created
September 20, 2020 13:33
-
-
Save SiAust/dbb82bc191ff613908f05da324990b27 to your computer and use it in GitHub Desktop.
Composing functions with default method combine.
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
import java.security.MessageDigest; | |
import java.util.Base64; | |
import java.util.Scanner; | |
import java.util.function.Function; | |
class ChainOfResponsibilityDemo { | |
/** | |
* Accepts a request and returns new request with data wrapped in the tag <transaction>...</transaction> | |
*/ | |
static RequestHandler wrapInTransactionTag = req -> | |
new Request(String.format("<transaction>%s</transaction>", req.getData())); | |
/** | |
* Accepts a request and returns a new request with calculated digest inside the tag <digest>...</digest> | |
*/ | |
static RequestHandler createDigest = req -> { | |
String digest = ""; | |
try { | |
final MessageDigest md5 = MessageDigest.getInstance("MD5"); | |
final byte[] digestBytes = md5.digest(req.getData().getBytes("UTF-8")); | |
digest = new String(Base64.getEncoder().encode(digestBytes)); | |
} catch (Exception ignored) { | |
System.out.println("An error occurred"); | |
} | |
return new Request(req.getData() + String.format("<digest>%s</digest>", digest)); | |
}; | |
/** | |
* Accepts a request and returns a new request with data wrapped in the tag <request>...</request> | |
*/ | |
static RequestHandler wrapInRequestTag = req -> | |
new Request(String.format("<request>%s</request>", req.getData())); | |
/** | |
* It should represents a chain of responsibility combined from another handlers. | |
* The format: commonRequestHandler = handler1.setSuccessor(handler2.setSuccessor(...)) | |
* The combining method setSuccessor may has another name | |
*/ | |
static RequestHandler commonRequestHandler = wrapInTransactionTag.combine(createDigest.combine(wrapInRequestTag)); | |
/** | |
* It represents a handler and has two methods: one for handling requests and other for combining handlers | |
*/ | |
@FunctionalInterface | |
interface RequestHandler { | |
// !!! write a method handle that accept request and returns new request here | |
// it allows to use lambda expressions for creating handlers below | |
Request handle(Request request); | |
// !!! write a default method for combining this and other handler single one | |
// the order of execution may be any but you need to consider it when composing handlers | |
// the method may has any name | |
default RequestHandler combine(RequestHandler requestHandler) { | |
Function<String, Integer> function = String::length; | |
return request -> requestHandler.handle(this.handle(request)); | |
} | |
} | |
/** | |
* Immutable class for representing requests. | |
* If you need to change the request data then create new request. | |
*/ | |
static class Request { | |
private final String data; | |
public Request(String requestData) { | |
this.data = requestData; | |
} | |
public String getData() { | |
return data; | |
} | |
} | |
// Don't change the code below | |
public static void main(String[] args) throws Exception { | |
final Scanner scanner = new Scanner(System.in); | |
final String requestData = scanner.nextLine(); | |
final Request notCompletedRequest = new Request(requestData); | |
System.out.println(commonRequestHandler.handle(notCompletedRequest).getData()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment