1673567340
Web3Auth is where passwordless auth meets non-custodial key infrastructure for Web3 apps and wallets. By aggregating OAuth (Google, Twitter, Discord) logins, different wallets and innovative Multi Party Computation (MPC) - Web3Auth provides a seamless login experience to every user on your application.
Checkout the official Web3Auth Documentation and SDK Reference to get started!
...and a lot more
In your project-level settings.gradle
file, add JitPack repository:
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
maven { url "https://jitpack.io" } // <-- Add this line
}
}
Then, in your app-level build.gradle
dependencies section, add the following:
dependencies {
// ...
implementation 'org.torusresearch:web3auth-android-sdk:-SNAPSHOT'
}
Open your app's AndroidManifest.xml
file and add the following permission:
<uses-permission android:name="android.permission.INTERNET" />
Hop on to the Web3Auth Dashboard and create a new project. Use the Client ID of the project to start your integration.
Add {YOUR_APP_PACKAGE_NAME}://auth
to Whitelist URLs.
Copy the Project ID for usage later.
Open your app's AndroidManifest.xml
file and add the following deep link intent filter to your sign-in activity:
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- Accept URIs: {YOUR_APP_PACKAGE_NAME}://* -->
<data android:scheme="{YOUR_APP_PACKAGE_NAME}" />
</intent-filter>
Make sure your sign-in activity launchMode is set to singleTop in your AndroidManifest.xml
<activity
android:launchMode="singleTop"
android:name=".YourActivity">
// ...
</activity>
In your sign-in activity', create an Web3Auth
instance with your Web3Auth project's configurations and configure it like this:
class MainActivity : AppCompatActivity() {
// ...
private lateinit var web3Auth: Web3Auth
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
web3Auth = Web3Auth(
Web3AuthOptions(context = this,
clientId = getString(R.string.web3auth_project_id),
network = Web3Auth.Network.MAINNET,
redirectUrl = Uri.parse("{YOUR_APP_PACKAGE_NAME}://auth"),
whiteLabel = WhiteLabelData( // Optional param
"Web3Auth Sample App", null, null, "en", true,
hashMapOf(
"primary" to "#123456"
)
)
)
)
// Handle user signing in when app is not alive
web3Auth.setResultUrl(intent?.data)
// ...
}
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
// Handle user signing in when app is active
web3Auth.setResultUrl(intent?.data)
// ...
}
private fun onClickLogin() {
val selectedLoginProvider = Provider.GOOGLE // Can be Google, Facebook, Twitch etc
val loginCompletableFuture: CompletableFuture<Web3AuthResponse> = web3Auth.login(LoginParams(selectedLoginProvider))
loginCompletableFuture.whenComplete { loginResponse, error ->
if (error == null) {
// render logged in UI
} else {
// render login error UI
}
}
}
//...
}
Checkout the examples for your preferred blockchain and platform in our examples repository
Checkout the Web3Auth Demo to see how Web3Auth can be used in an application.
Further checkout the app folder within this repository, which contains a sample app.
Author: Web3Auth
Source code: https://github.com/Web3Auth/web3auth-android-sdk
#web3 #Java #Kotlin
1673263260
web3j-quorum is an extension to web3j providing support for JP Morgan's Quorum API.
web3j is a lightweight, reactive, type safe Java library for integrating with clients (nodes) on distributed ledger or blockchain networks.
For further information on web3j, please refer to the main project page and the documentation at Read the Docs.
Add the relevant dependency to your project:
Java 8:
<dependency>
<groupId>org.web3j</groupId>
<artifactId>quorum</artifactId>
<version>4.8.4</version>
</dependency>
Java 8:
compile ('org.web3j:quorum:4.8.4')
See instructions as per the Quorum project page
To send synchronous requests:
Quorum quorum = Quorum.build(new HttpService("http://localhost:22001"));
Web3ClientVersion web3ClientVersion = quorum.web3ClientVersion().send();
String clientVersion = web3ClientVersion.getWeb3ClientVersion();
To send asynchronous requests:
Quorum quorum = Quorum.build(new HttpService("http://localhost:22001"));
Web3ClientVersion web3ClientVersion = quorum.web3ClientVersion().sendAsync().get();
String clientVersion = web3ClientVersion.getWeb3ClientVersion();
To use an RxJava Observable:
Quorum quorum = Quorum.build(new HttpService("http://localhost:22001"));
quorum.web3ClientVersion().observable().subscribe(x -> {
String clientVersion = x.getWeb3ClientVersion();
...
});
web3j also supports fast inter-process communication (IPC) via file sockets to clients running on the same host as web3j. To connect simply use UnixIpcService or WindowsIpcService instead of HttpService when you create your service:
// OS X/Linux/Unix:
Quorum quorum = Quorum.build(new UnixIpcService("/path/to/socketfile"));
...
// Windows
Quorum quorum = Quorum.build(new WindowsIpcService("/path/to/namedpipefile"));
...
Smart contract wrappers generated using web3j 2.0+ work out the box with with web3j-quorum.
The only difference is that you'll need to use the Quorum ClientTransactionManager:
QuorumTransactionManager transactionManager = new QuorumTransactionManager(
web3j, "0x<from-address>", Arrays.asList("<privateFor-public-key>", ...);
YourSmartContract contract = YourSmartContract.deploy(
<web3j>, <transactionManager>, GAS_PRICE, GAS_LIMIT,
<param1>, ..., <paramN>).send();
These wrappers are similar to the web3j smart contract wrappers with the exception that the transactions are signed by the Quorum nodes rather then by web3j. They also support the privateFor field on transactions.
See the web3j documentation for a detailed overview of smart contracts and web3j.
web3j supports sending raw private transactions through a connection to Quorum Transaction Managers. Code examples
Credentials credentials = ...
//connect to quorum node via http or ipc as described above
Quorum quorum = ...
EnclaveService enclaveService = new EnclaveService("http://TESSERA_THIRD_PARTY_URL", TESSERA_THIRD_PARTY_PORT, httpClient);
Enclave enclave = new Tessera(enclaveService, quorum);
QuorumTransactionManager qrtxm = new QuorumTransactionManager(
quorum, credentials, TM_FROM_KEY, Arrays.asList(TM_TO_KEY_ARRAY),
enclave,
30, // Retry times
2000); // Sleep
Credentials credentials = ...
//connect to quorum node via http or ipc as described above
Quorum quorum = ...
//build http client that supports ipc connection
UnixDomainSocketFactory socketFactory = new UnixDomainSocketFactory(new File("TESSERA_IPC_PATH"));
OkHttpClient client = new OkHttpClient.Builder()
.socketFactory(socketFactory)
.build();
EnclaveService enclaveService = new EnclaveService("http://localhost", TESSERA_THIRD_PARTY_PORT, client);
Enclave enclave = new Tessera(enclaveService, quorum);
QuorumTransactionManager qrtxm = new QuorumTransactionManager(
quorum, credentials, TM_FROM_KEY, Arrays.asList(TM_TO_KEY_ARRAY),
enclave,
30, // Retry times
2000); // Sleep
Credentials credentials = ...
//connect to quorum node via http or ipc as described above
Quorum quorum = ...
//build http client that supports ipc connection
UnixDomainSocketFactory socketFactory = new UnixDomainSocketFactory(new File("CONSTELLATION_IPC_PATH"));
OkHttpClient client = new OkHttpClient.Builder()
.socketFactory(socketFactory)
.build();
EnclaveService enclaveService = new EnclaveService("http://localhost", CONSTELLATION_THIRD_PARTY_PORT, client);
Enclave enclave = new Constellation(enclaveService, quorum);
QuorumTransactionManager qrtxm = new QuorumTransactionManager(
quorum, credentials, TM_FROM_KEY, Arrays.asList(TM_TO_KEY_ARRAY),
enclave,
30, // Retry times
2000); // Sleep
YourSmartContract.deploy(quorum,
qrtxm,
GAS_PRICE, GAS_LIMIT,
<param1>, ..., <paramN>).send();
Using a single QuorumTransactionManager method signAndSend
RawTransaction rawTransaction = ...
EthSendTransaction ethSendTransaction = qrtxm.signAndSend(rawTransaction);
Using multiple exposed QuorumTransactionManager methods (storeRawRequest, sign, sendRaw
)
//send raw bytecode to QuorumTranasctionManager
SendResponse storeRawResponse = qrtxm.storeRawRequest(HEX_ENCODED_SMARTCONTRACT_BYTECODE, TM_FROM_KEY, Arrays.asList(TM_TO_KEY_ARRAY));
String tesseraTxHash = Numeric.toHexString(Base64.getDecoder().decode(storeRawResponse.getKey()));
//create raw transaction with hash returned from QuorumTransactionManager
RawTransaction rawTransaction = ...
//sign raw transaction
String signedTx = qrtxm.sign(rawTransaction);
//send signed raw transaction to quorum node
EthSendTransaction ethSendTransaction = qrtxm.sendRaw(signedTx, Arrays.asList(TM_TO_KEY_ARRAY));
Retrieving a private transaction payload with Enclave receive
method
String payload = enclave.receiveRequest(tesseraTxHash, TM_TO_KEY);
Sample code for sending raw private transactions via smart contract, QuorumTransactionManager and Enclave
// Raw txn
RawTransactionManager qrtxm = new RawTransactionManager(
quorum,
credentials,
30, // Retry times
2000); // Sleep
YourSmartContract.deploy(quorum,
qrtxm,
GAS_PRICE, GAS_LIMIT,
<param1>, ..., <paramN>).send();
Author: web3j
Source code: https://github.com/web3j/web3j-quorum
License: View license
#quorum #Java #web3
1672583340
Maven extension for VS Code. It provides a project explorer and shortcuts to execute Maven commands, improving user experience for Java developers who use Maven.
For troubleshooting, please refer to the page HERE.
Maven Explorer
The extension scans pom.xml
in your workspace, and displays all Maven projects and their modules in the sidebar.
Run Plugin Goals
The extension parse effective-pom of Maven projects, and displays all plugins and plugin goals hierarchically.
POM File Editing
The extension provides Maven specific completion suggestions when editing POM files, including snippets and artifact hints.
Re-Run Historical Commands
It preserves history of goals for each project, so you can fast re-run previous long commands, e.g. mvn <goals> -Dparam1=value1 -Dparam2=value2 -Dparam3=value3 ...
There are 2 entries for it:
Maven: History ...
-> Select a project -> Select command from the historyHistory ...
-> Select command from the historyArchetype Related
The extension loads archetypes listed in local/remote catalog. After selection, the extension sends mvn archetype:generate -D...
to terminal. There are 2 entries for it:
Maven: Generate from Maven Archetype
Generate from Maven Archetype
With following steps, you can update the local cache of Maven remote catalog. It takes some time to download meta data from Maven central repository.
Command Palette -> select Maven: Update Maven Archetype Catalog
.
JAVA_HOME and Other Environment Variables
This extension executes Maven by opening a terminal session and then calling Maven in that session. Maven requires the JAVA_HOME environment variable to be set. Maven will also look for other variables such as MAVEN_OPTS. If you prefer not to set those variables permanently you can configure them, or any other environment variable, in settings:
{
"maven.terminal.customEnv": [
{
"environmentVariable": "MAVEN_OPTS", // variable name
"value": "-Xms1024m -Xmx4096m" // value
},
{
"environmentVariable": "JAVA_HOME", // variable name
"value": "C:\\Program Files\\Java\\jdk-9.0.4" // value
}
]
}
Special Handling for JAVA_HOME
If you have Red Hat's Java Language Support extension installed, then you can specify JAVA_HOME in settings for that extension:
{
"java.home": "C:\\Program Files\\Java\\jdk-9.0.4" // Red Hat Java Language Support Setting
}
This extension (Maven for Java) can reuse that setting if you desire:
{
"maven.terminal.useJavaHome": true // Use the Red Hat Java Language Support Setting for JAVA_HOME
}
With this support, you can specify JAVA_HOME in one place and you do not need to use the maven.terminal.customEnv
setting unless you have other environment variables to set.
If you have JAVA_HOME configured through the maven.terminal.customEnv
setting, and also specify to reuse the Red Hat setting, then the value from maven.terminal.customEnv
will take precedence.
Default Options for Maven CommandThe usage of Maven executable is:
usage: mvn [options] [<goal(s)>] [<phase(s)>]
You can use maven.executable.options
to specify default options for all your Maven commands executed in current project.
{
"maven.executable.options": "-o -s ./settings.xml" // work offline, and use an alternative settings file
}
Folder Exclusion for Searching POM Files
To speed up the searching of Maven projects, you can exclude folders in settings:
{
"maven.excludedFolders": [
"**/.*", // exclude hidden folders
"**/node_modules", // exclude node modules to speed up
"**/target" // exclude duplicated pom file in target folder
]
}
Customize Favorite Maven Commands
Specify a favorite command in settings:
{
"maven.terminal.favorites": [
{
"alias": "full-build without tests",
"command": "clean package -DskipTests"
}
]
}
Now right-click on an project item, and then click Favorite ...
. The option full-build without tests
should show up.
Name | Description | Default Value |
---|---|---|
maven.dependency.enableConflictDiagnostics | Specify whether to show diagnostics for conflict dependencies. | true |
maven.excludedFolders | Specifies file path pattern of folders to exclude while searching for Maven projects. | [ "**/.*", "**/node_modules", "**/target", "**/bin", "**/archetype-resources" ] |
maven.executable.preferMavenWrapper | Specifies whether you prefer to use Maven wrapper. If true, it tries using 'mvnw' by walking up the parent folders. If false, or 'mvnw' is not found, it tries 'mvn' in PATH instead. | true |
maven.executable.path | Specifies absolute path of your 'mvn' executable. When this value is empty, it tries using 'mvn' or 'mvnw' according to the value of 'maven.executable.preferMavenWrapper'. E.g. /usr/local/apache-maven-3.6.0/bin/mvn | |
maven.executable.options | Specifies default options for all mvn commands. E.g. -o -DskipTests | |
maven.explorer.projectName | Format of project node name shown in Maven explorer. | ${project.name} |
maven.projectOpenBehavior | "Default method of opening newly created project. | "Interactive" |
maven.pomfile.autoUpdateEffectivePOM | Specifies whether to update effective-pom automatically whenever changes detected. | false |
maven.pomfile.globPattern | Specifies the glob pattern used to look for pom.xml files. | **/pom.xml |
maven.pomfile.prefetchEffectivePom | Specifies whether to prefetch effective pom on startup. | false |
maven.terminal.useJavaHome | If this value is true, and if the setting java.home has a value, then the environment variable JAVA_HOME will be set to the value of java.home when a new terminal window is created. | false |
maven.terminal.customEnv | Specifies an array of environment variable names and values. These environment variable values will be added before Maven is executed.environmentVariable : Name of the environment variable to set.value : Value of the environment variable to set. | [] |
maven.terminal.favorites | Specify pre-defined favorite commands to execute.alias : A short name for the command.command : Content of the favorite command. | [] |
maven.view | Specifies the way of viewing Maven projects. Possible values: flat , hierarchical . | flat |
maven.settingsFile | Specifies the absolute path of Maven settings.xml file. If not specified, ~/.m2/settings.xml is used. | null |
maven.showInExplorerContextMenu | If this value is true, add a command to create Maven Projects in the Explorer context menu for folders. | true |
VS Code collects usage data and sends it to Microsoft to help improve our products and services. Read our privacy statement to learn more. If you don’t wish to send usage data to Microsoft, you can set the telemetry.enableTelemetry
setting to false
. Learn more in our FAQ.
This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.
Refer to CHANGELOG
Author: microsoft
Source code: https://github.com/microsoft/vscode-maven
License: View license
#Java #VSCode
1672582920
Slack WebHook Integration for Java
Basic Examples
// Send simple message
SlackApi api = new SlackApi("https://hooks.slack.com/services/id_1/id_2/token");
api.call(new SlackMessage("my message"));
// Send simple message with custom name
SlackApi api = new SlackApi("https://hooks.slack.com/services/id_1/id_2/token");
api.call(new SlackMessage("Mafagafo", "my message"));
// Send simple message in different room
SlackApi api = new SlackApi("https://hooks.slack.com/services/id_1/id_2/token");
api.call(new SlackMessage("#general", null, "my message"));
// Send simple message in different room with custom name
SlackApi api = new SlackApi("https://hooks.slack.com/services/id_1/id_2/token");
api.call(new SlackMessage("#general", "Mafagafo", "my message"));
// Send simple message in different room with custom name and tag someone in the message so he will get notified
SlackApi api = new SlackApi("https://hooks.slack.com/services/id_1/id_2/token");
api.call(new SlackMessage("#general", "Mafagafo", "Hi @gpedro : your API rocks").setLinkNames(true));
Installation
Add the following dependency in pom.xml
<dependency>
<groupId>net.gpedro.integrations.slack</groupId>
<artifactId>slack-webhook</artifactId>
<version>1.4.0</version>
</dependency>
Configuration
Add
Add Incoming WebHooks Integration
Change Log
footer
, footer-icon
, ts
(#24) and link_names
(#25) attributesAuthor: gpedro
Source code: https://github.com/gpedro/slack-webhook
License: MIT license
#Java #slack
1672387741
In programming, design patterns help solve general, repetitive problems that developers encounter. It is not a code, rather it's a proven and tested paradigm used to prevent subtle issues. Design patterns are classified into three categories, Creational Design Pattern, Behavioural Design Pattern, and Structural Design Pattern, based on the problems they solve. In today’s blog, we will discuss the creational design patterns and understand their subcategories. So, without further ado, let’s begin!
#Java #software-development #webappdevelopment #javadevelopmentcompany #CustomSoftwareDevelopment
1671383640
In this article, we will learn how to send push notifications from AWS Lambda to Android apps using Pusher Beams. Build a simple demo application and create a Lambda function using Java. Upload and test functionality using Eclipse.
Pusher Beams allows you to customize push notifications you send to your devices via a server. However it can be expensive to run a server 24 hours a day 7 days a week and we may only need to send notifications every so often. This is where AWS Lambda can help. Lambda functions are serverless and work on a pay as you go model (with a generous free tier). This means that you only pay for when you use the function. We’re going to explore how we can setup Pusher Beams on an Android client using an AWS Lambda function running Java to trigger the notifications.
We will need to have a user that has registered for notifications and signed up for an interest we will call “hello”, so we can test out our implementation. We’re going to create a very basic Android app that doesn’t actually show anything to the user except for the notification on the lock screen.
Create a new Empty Activity project using Android Studio and name it something like LambdaPush. Provide a Package name and remember this as you will need it for completing the Firebase set up. We will be using Kotlin as the language choice for this tutorial and supporting Android 16+ (Jelly Bean).
Log in to your Firebase account here and go to your console. If you do not already have a project created you will need to create one and name it anything you like, if you have a project select it. Within the Project Overview page select Add App and follow the instruction for creating a new Android application.
Once you have completed the setup for your Android app you will be returned to the dashboard. You will need to go to the project settings (found within the “settings cog” in the top left). Once in the project settings select the Cloud Messaging tab. Copy the Server Key you will need it for setting up your Pusher Beams instance.
Login or create an account to access your dashboard here. Create a new beams instance using the dashboard.
Complete step one of the Android setup guide, by providing your FCM server key you copied earlier and Continue. We will pick up the remainder later on in this tutorial. Press the X to exit the setup guide and you will be returned to your dashboard for that instance. Scroll to the bottom of the page and you will find your Beams instance ID and secret key, make note of these you will need them later.
Open your app level build.gradle
file and add the following into your dependencies:
// app/build.gradle
...
dependencies {
...
implementation 'com.google.firebase:firebase-messaging:17.1.0'
implementation 'com.pusher:push-notifications-android:1.4.0'
...
}
...
Here we are adding the Firebase messaging SDK and the Pusher Beams SDK. You should already have the Google Service SDK and google-services.json
added to your project when setting up the Firebase app.
Synchronize Gradle by pressing the Sync Now button.
Open your main activity and add the following import:
import com.pusher.pushnotifications.PushNotifications
Add the following to your onCreate
function:
PushNotifications.start(applicationContext, "YOUR_INSTANCE_ID")
PushNotifications.addDeviceInterest("hello")
Remember to replace YOUR_INSTANCE_ID
with the instance id from your Pusher Beams console and run the application.
Open your Eclipse IDE and press CMD + N this will open the new project wizard. Expand the AWS folder (make sure you have the AWS Toolkit installed if you don’t see this) and select AWS Lambda Java Project and click Next.
In the next window provide a Project name, Group ID, Artifact ID and Class Name. You may leave these as the default if you wish. For the Input Type, choose Custom, to complete the set up select Finish.
Once the project has finished setting up open the pom.xml
. Add the following within your dependencies:
// pom.xml
<dependencies>
...
<dependency>
<groupId>com.pusher</groupId>
<artifactId>push-notifications-server-java</artifactId>
<version>1.1.0</version>
</dependency>
...
</dependencies>
Create a new file in the lambda package called RequestClass.java
. Within this file add the following:
// src/main/java/RequestClass.java
package com.amazonaws.lambda.demo;
public class RequestClass {
String title;
String message;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public RequestClass(String title, String message) {
this.title = title;
this.message = message;
}
public RequestClass() {
}
}
This code will be used by our Lambda function in order to parse the data we will pass in to the function to create our push message. Next open your LambdaFunctionHandler.java
and replace the contents with:
// src/main/java/RequestClass.java
package com.amazonaws.lambda.demo;
import java.util.List;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.pusher.pushnotifications.PushNotifications;
public class LambdaFunctionHandler implements RequestHandler<RequestClass, String> {
@Override
public String handleRequest(RequestClass request, Context context) {
String instanceId = "YOUR_INSTANCE_ID";
String secretKey = "YOUR_SECRET_KEY";
PushNotifications beamsClient = new PushNotifications(instanceId, secretKey);
List<String> interests = Arrays.asList("hello");
Map<String, Map> publishRequest = new HashMap();
Map<String, String> fcmNotification = new HashMap();
fcmNotification.put("title", request.title);
fcmNotification.put("body", request.message);
Map<String, Map> fcm = new HashMap();
fcm.put("notification", fcmNotification);
publishRequest.put("fcm", fcm);
try {
beamsClient.publishToInterests(interests, publishRequest);
return "Push sent!";
} catch (IOException e) {
e.printStackTrace();
return "Push failed!";
} catch (InterruptedException e) {
e.printStackTrace();
return "Push failed!";
} catch (URISyntaxException e) {
e.printStackTrace();
return "Push failed!";
}
}
}
This code will be used by our Lambda function later on to publish notifications to devices that are registered for the hello
interest. We use the request.title
and request.message
to form part of the FCM notification. We’ll look at this in more detail when we come to test our integration. Remember to replace YOUR_INSTANCE_ID
and YOUR_SECRET_KEY
with the credentials from your Pusher Beams console.
Right click in the eclipse editor select AWS Lambda → Upload function to AWS Lambda.
On the next screen select a IAM role if you have one. If you don’t use the Create button to make a new one and call it “lambda_basic_execution”. Next we would need to create a bucket on the AWS console here if we don’t already have one. Make sure that there are permissions to the root user. And lastly but most importantly make sure that the user created initially has all of the permissions required - AmazonS3FullAcces. Leave everything else the same and click Finish to upload your code to AWS Lambda.
Return to your Lambda function code in the Eclipse IDE. Right-click and select AWS Lambda → Run function on AWS Lambda. A dialog box will appear, make sure your lambda function is selected from the dropdown list and that the Enter the JSON input for your function radio button is selected. In text field provided add the following:
{"title": "hello", "message": "Just a friendly hello"}
Notice how our keys in the JSON object are title and message. These are the event keys we were using in our code to provide the title and body for the push notification.
If everything has worked as expected you should receive a push to your device.
We’ve learnt how to create an AWS Lambda function using Java that can publish a push notification using Pusher Beams to an Android device.
Original article sourced at: https://pusher.com
#Android #Java #Lambda
1671173493
It is a list of Java programming interview questions and answers to help you prepare for your next job interview. It covers topics such as Java fundamentals, OOPs, Design Patterns, Data Structures, Algorithms, and much more.
1669101390
In this article let's learn about Java Generics Tutorial with examples. What are generics in Java, and what is their use? Are you also contemplating the same? Look no further as we attempt to explain what generics in Java along with examples. Below are the topics we will be discussing in this blog. So, let’s get started, shall we?
The word generics means parameterized types. Parameterized types are essential because they enable us to create databases, interfaces, and methods through which the type of data they operate is given as a parameter. In generics, it is possible to create a single class. A class interface or a method that operates on a parameterized type is called generic, like generic class or generic method, and generics only work with objects. And their type differs based on their type arguments.
The generics in java programming were introduced in J2SE 5 to deal with type-safe objects. It detects the bugs at compile time and makes the code stable. The java collections framework always supports the generics to specify the type of object to be stored. It is always essential to understand that Java can create generalized interfaces, classes, and methods operating with references to the object type. The object will be the superclass of all other classes; this object reference can refer to any object.
Generics in java added the type of safety lacking and streamlined the process since it is no longer necessary to explicitly employ casts to translate between object and the data that is operated on.
Thus, generics expand our ability to reuse the code, which is type safety and easy.
A simple generics in java example:
The below program demonstrates two different classes. The first is the generic class generics, and the second is the generic demo which uses generics.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
|
The output produced is:
Type of S is java.lang.integer
Value: 88
Type of S is java.lang.integer
Value: Test for generics
Generic methods introduce their type of parameters, i.e., static and non-static generic methods are allowed and constructors. The methods in a generic class can use a class type parameter and are, therefore, automatically generic relative to the type parameter. It is also possible to declare a generic method that uses one or more types of parameters on its own. It is also possible to create a method within a non-generic class. Type inference allows invoking a method as an ordinary method without specifying a type between brackets.
The below program declares a non-generic class called genmeth and a generic method within the same class demo (). The generic method shows if an object is a member of an array, which can also be used with any object and array as long as that array contains objects compatible with the type of the object.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
Output:
2 is in nums
7 is in nums
In the above program the syntax used for creating demo () is: <type-param-list> ret-type meth-name(param-list) { // ….
Also Read: Palindrome in Java
Constructors can be generic even if the constructed class is not generic. These constructors at least have one parameter, which is of generic type.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
The output will be:
Value 1000.0
Value 123.5
In this example, the constructor specifies a generic type parameter, a subclass of Number. A constructor can be called with any numeric type, which includes integer, float, or double. Though the constructor is not a generic class, its constructor is generic.
Any class type can replace the type parameters for many purposes, and sometimes limiting what is passed to a type parameter is helpful. Whenever we want to declare a bound type parameter, list the type parameters name followed by extends keyword and upper bound.
Let us assume that we need to create a generic class that contains a method that should return an average of an array of numbers. Then we want to use the class to obtain the average of an array of any type of Number, which may be an integer, double, or float. Thus, we should generically specify the type of numbers using a type parameter.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
In the above program, the average () method tries to obtain the float version of each Number in the nums array by calling float value since all numeric classes integer float double are subclasses of Number, which defines the float value method. This method is available for all numeric wrapper classes. The problem is that the compiler does not know that we intend to create state objects using only numeric types. And when we compile, we get errors reported. To solve this problem, we need to tell the compiler to pass only numeric type values to X. Further. We need to ensure that only numeric types are passed.
To handle these types of situations, java provides us with bounded types. When specifying these type parameters, you can create an upper bound that declares the superclass from which all types of arguments must be derived. This is done by using an extended keyword clause when specifying the type parameter as shown below:
1 | <X extends superclass> |
This specifies that X can only be replaced by a superclass or subclass of the superclass. Superclass defines an inclusive upper limit.
We can fix the class using an upper bound by specifying a Number as an upper bound, as shown below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
|
Output:
Average is 3.0
Average is 3.3
A number bounds type x. The compiler knows that all objects of type X can have double values since a number declares its method.
The general form or the syntax for declaring a generic class is shown below:
Class class-name <type-arg-list> { //……
And the syntax for declaring a reference to a generic class is:
1 | Class-name <type-arg-list> var-name= new class-name<type-arg-list>(cons-arg-list); |
Generic classes can also be a part of the class hierarchy in the same way a generic class can be. Thus, a generic class can act as both a superclass and a subclass. The main difference between the generic and non-generic classes is that in a generic hierarchy, any type of argument needed by a superclass must be passed to the hierarchy of subclasses, similar to how a hierarchy passes up constructor arguments.
Let us see an example that uses both a superclass and a subclass:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
In this example, we can see that Generic2 does not use the type parameter X except to pass the Generic superclass. Otherwise, it would not need to be generic, and it should specify the parameters required by its generic superclass; The subclass is free to add its type parameters.
There are also runtime comparisons in a generic hierarchy, i.e., instances that determines whether an object is an instance of a class. It returns true if the object is a specified type or can be cast to that specified type. This can be applied to objects of generic classes. One class instance can be cast to another type if both are compatible and their type arguments are the same. We can also override a method in a generic class like any other method.
Generic interfaces are additionally the same as generic classes and generic methods, and these are specified just like generic classes and declared the same as generic classes. If a class implements a generic interface, then the implementing class does not need to be generic.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
|
The output will be:
Minimum value inums: 3
Minimum value CHS: a
Generics is the addition to java, which is necessary for providing some transition to the path from old, pre-generics code. Millions of pre-generics legacy codes must remain functional and compatible with generics. Pre-generics code should be able to work with generics, and generic code must work with pre-generic code. To handle the transitions of generics, java allows a generic class that can be used without any arguments, and thus it creates a raw type for the class. This Raw type is compatible with legacy code which does not know generics. And there lies the main drawback to using this raw type is that the type safety of generics is lost. A Raw type is not type-safe. Thus, a variable of a raw type can be assigned as a reference to any object. One final point about raw-type and legacy code is that we should limit the use of raw types to the codes in which we must mix legacy code with the new generic code. Raw types are transitional features that should not be used for new code.
Adding generics to java caused a significant change to the collection framework since the entire collections framework must be re-engineered. All collections are now generic, and many of these methods which operate on collections take generic type parameters. The addition of generics affected every part of the collections, and Generics added that one type of feature, which was missing nothing but type safety.
Wildcard arguments can be bounded in the same way that a type parameter can be bounded. A bounded wildcard is always essential when creating a generic type that will operate on a class hierarchy. To understand this, let us see an example of bounded wildcards.
In general, for establishing an upper bound for a wild card, we use the given below expression:
1 | <? extends superclass> |
This superclass is the name of a class that serves as an upper bound. And we should remember that this is inclusive because the class forming the upper bound is also within the bounds.
We can also specify a lower bound for a wildcard by adding a super clause to a wild card declaration.
1 | <? super subclass> |
In these types of cases, only that classes are superclasses of a subclass are the acceptable arguments. This is an exclusive clause because it will not match the specified class by a subclass.
There are also a few restrictions that we need to keep in mind when we use generics. They always involve creating objects of a type parameter, static members, exceptions, and arrays.
The instance of a type parameter cannot be created.
For example:
1 2 3 4 5 6 7 |
|
This is an illegal attempt to create an instance of T. The reason is T does not exist at runtime; how can the compiler know what type of object to be created? We should remember that erasure removes all types of parameters during the compilation process.
In this restriction, no static members can use a type parameter declared by the enclosing class. We cancan’tclare static members that use a type parameter declared by the enclosing class, and we can declare static generic methods, which define their type parameters.
There are mainly two critical generic restrictions that are applied to arrays. Firstly, we cannot instantiate an array whose base type is always a type parameter. And the second one is that we cannot create an array of type-specific generic references. We can pass a reference to a type-compatible array when an object is created and assign the references. We can also create an array of references to generic if we use a wildcard. And this is considered to be better than using an array of raw types because type checking will still be enforced.
Generic classes cannot extend throwable. This means that we cannot create generic exception classes.
Let us look at some topics in generics briefly:
When the java code is compiled, all generic type information is erased or removed, which means replacing type parameters with their bound type, which is an object if no explicit bound is specified, and then applying the appropriate casts for maintaining type compatibility with the types specified with the type arguments.
The compiler enforces this type of compatibility and this approach to generic means that no type parameters exist at run time. And called a source-code mechanism.
The inclusion of generics gives rise to a new type of error called ambiguity; this error occurs when erasure causes two seemingly separate generic declarations to resolve to the same erased type, which causes a conflict. Often, the solution to ambiguity involves restricting the code since ambiguity often means that we have a conceptual error in the design.
The compiler needs to add a bridge method to a class to handle situations in which the type erasure of an overriding method in a subclass does not produce the same erasure as a method in the superclass. In this case, a method can be generated, which uses the type erasure of the superclass, and this method calls the method that has the type erasure specified by the subclass. These bridge methods will occur only at the bytecode level and are not available for use. One last point we should consider about bridge points is their return type. This would cause an error in our source code and does not cause a problem handled correctly by the JVM.
Generics are the extensions to java since they streamline the creation of type-safety and reusable code. Generic code will be part of the future for all java programmers. This brings us to the end of the blog on generics in Java. We hope you can gain some valuable insights from the same. Check out Great Learning Academy’s Online Course on Java Programming and upskill today to learn more about such concepts.
Why generics are used in Java?
Generics allow types to be parameters when defining classes, interfaces, and methods. Type parameters allow the reuse of the same code with multiple inputs, somewhat like the more well-known formal parameters used in method declarations.
What is a generic class in Java with an example?
A generic class essentially indicates that its components or operations can be generalized by substituting any other type for the example T parameter, such as an integer, character, string, double, or another user-defined type.
What is the generic type?
A generic class or interface that is specified across types is referred to as a generic type. In essence, generic types enable code reuse by enabling the development of general, generic classes (or methods) that function with various kinds.
What is a generic code?
The term “generic code” refers to the code, including any subroutines, that Broderbund, its affiliates, or third parties utilize in other products or for other reasons that are now included in the Product.
What are the advantages of using generics?
The responsibility for type safety is now on the compiler due to generics. Since the right data type is guaranteed at compile time, developing code to test for it is not necessary. Type casting is not required, hence there is less chance of run-time errors.
Original article source at: https://www.mygreatlearning.com
1659563280
Themis is an open-source high-level cryptographic services library for securing data during authentication, storage, messaging, network exchange, etc. Themis solves 90% of typical data protection use cases that are common for most apps.
Themis helps to build both simple and complex cryptographic features easily, quickly, and securely. Themis allows developers to focus on the main thing: developing their applications.
Encrypt stored secrets in your apps and backend: API keys, session tokens, files.
Encrypt sensitive data fields before storing in database ("application-side field-level encryption").
Support searchable encryption, data tokenisation and data masking using Themis and Acra.
Exchange secrets securely: share sensitive data between parties, build simple chat app between patients and doctors.
Build end-to-end encryption schemes with centralised or decentralised architecture: encrypt data locally on one app, use it encrypted everywhere, decrypt only for authenticated user.
Maintain real-time secure sessions: send encrypted messages to control connected devices from your app, receive real-time sensitive data from your apps to your backend.
Compare secrets between parties without revealing them (zero-knowledge proof-based authentication).
One cryptographic library that fits them all: Themis is the best fit for multi-platform apps (e.g., iOS+Android+Electron app with Node.js backend) because it provides 100% compatible API and works in the same way across all supported platforms.
Themis provides ready-made building blocks (“cryptosystems”) which simplify usage of core cryptographic security operations.
Themis provides 4 important cryptographic services:
We created Themis to build other products on top of it - i.e. Acra and Hermes.
Installation
Refer to the Installation page to install Themis for your mobile, web, desktop, or server-side application. We highly recommend installation packages instead of building from source.
Languages
Themis is available for the following languages/platforms, refer to language howtos for each:
Platform | Documentation | Examples | Version |
---|---|---|---|
⚛️ React Native (iOS, Android) | React Native Howto | docs/examples/react-native | |
🔶 Swift (iOS, macOS) | Swift Howto | docs/examples/swift | |
📱 Objective-C (iOS, macOS) | Objective-C Howto | docs/examples/objc | |
☕️ Java (Desktop) | Java (Desktop) Howto | Java projects | |
☎️ Java (Android) | Java (Android) Howto | Android projects | |
📞 Kotlin (Android) | Java (Android) Howto | Android projects | |
🔻 Ruby | Ruby Howto | docs/examples/ruby | |
🐍 Python | Python Howto | docs/examples/python | |
🐘 PHP | PHP Howto | docs/examples/php | |
➕ C++ | CPP Howto | docs/examples/c++ | |
🍭 Node.js | Javascript (Node.js) Howto | docs/examples/js | |
🖥 WebAssembly | Javascript (WebAssembly) Howto | docs/examples/js | |
🐹 Go | Go Howto | docs/examples/go | |
🦀 Rust | Rust Howto | docs/examples/rust | |
🕸 С++ PNaCl for Google Chrome | WebThemis project |
Availability
Themis supports following CPU architectures: x86_64/i386, ARM, Apple Silicon (ARM64), various Android architectures.
We build and verify Themis on the latest stable OS versions:
We plan to expand this list with a broader set of platforms. If you'd like to help improve or bring Themis to your favourite platform or language — get in touch.
Documentation
Documentation for Themis contains the ever-evolving official docs, which covers everything from deployment guidelines to use cases, with brief explanations of cryptosystems and architecture behind the main Themis library.
Refer to the documentation to learn more about:
Cryptography
Themis relies on proven cryptographic algorithms implemented by well-known cryptography libraries such as OpenSSL, LibreSSL, BoringSSL. Refer to Cryptograhy in Themis docs to learn more.
This distribution includes cryptographic software. The country in which you currently reside may have restrictions on the import, possession, use, and/or re-export to another country, of encryption software. BEFORE using any encryption software, please check your country's laws, regulations, and policies concerning the import, possession, or use, and re-export of encryption software, to see if this is permitted. See http://www.wassenaar.org/ for more information.
The U.S. Government Department of Commerce, Bureau of Industry and Security (BIS), has classified this software as Export Commodity Control Number (ECCN) 5D002.C.1, which includes information security software using or performing cryptographic functions with asymmetric algorithms. The form and manner of this distribution make it eligible for export under the License Exception ENC Technology Software Unrestricted (TSU) exception (see the BIS Export Administration Regulations, Section 740.13) for both object code and source code.
Submitting apps to the App Store
If your application uses Themis and you want to submit it to the Apple App Store, there are certain requirements towards declaring use of any cryptography.
Read about Apple export regulations on cryptography for Themis to find out what to do.
Security
Each change in Themis core library is being reviewed and approved by our internal team of cryptographers and security engineers. For every release, we perform internal audits by cryptographers who don't work on Themis.
We use a lot of automated security testing, i.e. static code analysers, fuzzing tools, memory analysers, unit tests (per each platform), integration tests (to find compatibility issues between different Themis-supported languages, OS and x86/x64 architectures). Read more about our security testing practices in Themis security docs.
If you believe that you've found a security-related issue, please drop us an email to dev@cossacklabs.com. Bug bounty program may apply.
GDPR, HIPAA, CCPA
As a cryptographic services library for mobile and server platforms, Themis is a "state of the art" encryption tool, which provides secure data exchange and storage.
Using Themis, you can reach better compliance with the current data privacy regulations, such as:
Read more about Regulations in docs.
Community
Themis is recommended by OWASP as data encryption library for mobile platforms.
Themis is widely-used for both non-commercial and commercial projects, some public applications and libraries can be found here.
Want to be featured on our blog and on the list of contributors, too? Write us about the project you’ve created using Themis!
Contributing
If you're looking for something to contribute to and gain eternal respect, just pick the things in the list of issues. Head over to our Contribution guidelines as your starting point.
Supporting Themis for all these numerous platforms is hard work, but we try to do our best to make using Themis convenient for everyone. Most issues that our users encounter are connected with the installation process and dependency management. If you face any challenges, please let us know.
Commercial support
At Cossack Labs, we offer professional support services for Themis and applications using Themis.
This support includes, but is not limited to the library integration, with a focus on web and mobile applications; designing and building end-to-end encryption schemes for mobile applications; security audits, for in-house library integrations or high-level protocol; custom application development that requires cryptography; consulting and training services.
Drop us an email to info@cossacklabs.com or check out the Cossack Labs cybersecurity services.
Contacts
If you want to ask a technical question, report a bug or suggest a feature, feel free to start a discussion on GitHub, raise an issue in the issue tracker, or write to dev@cossacklabs.com.
To talk to the business wing of Cossack Labs Limited, drop us an email to info@cossacklabs.com.
Author: cossacklabs
Source code: https://github.com/cossacklabs/themis
License: Apache-2.0 license
#Java, #С #С++ #Node.js #Python #Ruby #PHP #Go #Rust #WASM #React
1658920816
L'un de nos plus grands défis en tant que développeurs de logiciels consiste à organiser notre code afin qu'il soit plus facile à étendre et à maintenir. Le modèle de commande nous aide à le faire en encapsulant toutes les données nécessaires pour effectuer une action dans un seul Command
objet.
Vous reconnaissez peut-être le modèle Command parce que nous l'utilisons tout le temps dans notre vie quotidienne. Un bon exemple consiste à utiliser une télécommande pour allumer un téléviseur, changer de chaîne, augmenter le volume, etc. Chacune de ces actions est encapsulée dans le dispositif de télécommande.
Une autre chose à noter à propos de toutes ces actions est qu'elles sont réversibles : vous pouvez allumer le téléviseur, et vous pouvez également l'éteindre. De plus, certaines des actions doivent être effectuées dans l'ordre : vous devez allumer le téléviseur avant de pouvoir augmenter le volume.
Dans ce défi de code Java, vous découvrirez le modèle de conception de commande et verrez plusieurs exemples du modèle dans la pratique. Je discuterai également de la manière dont le modèle de commande implémente deux principes fondamentaux du modèle SOLID . Les deux principes sont le principe de responsabilité unique , qui stipule qu'une classe ne doit avoir qu'un seul travail, et le principe ouvert-fermé , qui stipule que les objets ou entités doivent être ouverts à l'extension mais fermés à la modification.
Le modèle de commande est l'un des 23 modèles de conception introduits avec les modèles de conception Gang of Four . La commande est un modèle de conception comportemental , ce qui signifie qu'elle vise à exécuter une action dans un modèle de code spécifique.
Voir Introduction aux modèles de conception pour un aperçu des quatre types de modèles de conception.
Lorsqu'il a été introduit pour la première fois, le modèle Command était parfois expliqué comme des rappels pour Java . Alors qu'il a commencé comme un modèle de conception orienté objet, Java 8 a introduit les expressions lambda , permettant une implémentation fonctionnelle objet du modèle de commande. Cet article inclut un exemple utilisant une expression lambda dans le modèle de commande.
Comme pour tous les modèles de conception, il est très important de savoir quand appliquer le modèle de commande et quand un autre modèle pourrait être meilleur. L'utilisation du mauvais modèle de conception pour un cas d'utilisation peut rendre votre code plus compliqué, pas moins.
Nous pouvons trouver de nombreux exemples du modèle de commande dans le kit de développement Java et dans l'écosystème Java. Un exemple populaire consiste à utiliser l' Runnable
interface fonctionnelle avec la Thread
classe. Une autre consiste à gérer les événements avec un ActionListener
. Explorons ces deux exemples.
Obtenez le code des exemples de modèle de commande présentés dans cet article.
Runnable
est une interface qui inclut la run()
méthode. L'extrait de code suivant montre la run()
signature de la méthode. Comme vous pouvez le voir, il est possible de passer une commande dans la run()
méthode :
@FunctionalInterface
public interface Runnable {
public abstract void run();
}
Thread
est la classe la plus utilisée qui reçoit un Runnable
. Voyons comment passer une commande à la Thread
classe :
Runnable command = () -> System.out.println("Executing command!");
Thread thread = new Thread(command); // Setting command
thread.start();
Dans ce code, nous implémentons le comportement de la commande dans la run()
méthode avec une expression lambda. Au lieu du lambda, nous pourrions utiliser une classe interne anonyme , qui est une classe sans nom qui implémente Runnable
et la run()
méthode. Mais cette approche rendrait le code plus verbeux. L'utilisation du lambda est plus concise et plus facile à lire.
Nous passons ensuite la commande à la Thread
classe. Enfin, nous exécutons la commande en appelant la start()
méthode.
Voici la sortie que nous pouvons attendre de ce code :
Executing command!
Un autre bon exemple dans le JDK est l' ActionListener
interface. Je sais que c'est une interface plus ancienne, mais elle convient comme exemple.
Dans le code suivant, nous créons un JFrame
et un JButton
. Nous définissons ensuite l'action dans le bouton en appelant la addActionListener()
méthode. Dans ce cas, nous allons simplement changer le texte de "Cliquez-moi" en "Cliquez". Ensuite, nous ajouterons le bouton au cadre et afficherons le cadre avec le bouton :
JFrame frame = new JFrame();
JButton button = new JButton("Click Me");
button.addActionListener(e -> button.setText("Clicked!")); // Command implementation
frame.add(button);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
La figure 1 montre les résultats de ce code après avoir cliqué sur le bouton.
IDG
Figure 1. ActionListener en action.
Maintenant que vous avez vu des exemples du modèle Command dans le JDK, créons le nôtre. Tout d'abord, regardez le diagramme de classes de la figure 2.
IDG
Figure 2. Un diagramme du modèle de commande pour une interface de véhicule.
Il y a trois parties dans le diagramme, que je vais expliquer.
La classe de base du modèle Command est l' Command
interface. Nous utilisons cette interface chaque fois que nous voulons exécuter ou annuler une commande :
public interface Command {
void execute();
void revert();
}
Ensuite, nous devons créer la classe qui a le comportement pour exécuter la commande. Nous commençons par l' Vehicle
interface, puis créons les classes Motorcycle
et pour l'implémenter :Truck
public interface Vehicle {
void start();
void stop();
void accelerate();
}
public class Motorcycle implements Vehicle {
@Override
public void start() {
System.out.println("Starting motorcycle...");
}
@Override
public void stop() {
System.out.println("Stopping motorcycle...");
}
@Override
public void accelerate() {
System.out.println("Accelerating motorcycle...");
}
}
public class Truck implements Vehicle {
@Override
public void start() {
System.out.println("Starting truck...");
}
@Override
public void stop() {
System.out.println("Stopping truck...");
}
@Override
public void accelerate() {
System.out.println("Accelerating truck...");
}
@Override
public void decelerate() {
System.out.println("Decelerating truck...");
}
}
Notez également que l' Vehicle
interface rend le code plus flexible et plus facile à modifier : nous pourrions facilement ajouter un autre véhicule tel que Car
celui qui implémente l' Vehicle
interface. Cette partie du modèle de commande est un excellent exemple du principe SOLIDE ouvert-fermé. (Rappelez-vous que ce principe stipule que les objets ou les entités doivent être extensibles.)
Maintenant, nous avons le comportement Motorcycle
et Truck
mais nous avons besoin d'une classe pour l'exécuter. Dans notre cas, cette classe sera le GhostRider
. GhostRider
conduira les classes Motorcycle
et .Truck
GhostRider
reçoit la commande dans le constructeur et invoque la execute()
méthode de la commande dans les méthodes takeAction()
et :revertAction()
public class GhostRider {
Command command;
public GhostRider(Command command){
this.command = command;
}
public void setCommand(Command command) {
this.command = command;
}
public void takeAction(){
command.execute();
}
public void revertAction() {
command.revert();
}
}
Maintenant, créons les commandes StartMotorcycle
, AccelerateMotorcycle
et StartAllVehicles
. Chaque commande implémente l' Command
interface et reçoit Vehicle
dans le constructeur. Ensuite, il invoque la méthode qui correspond à chaque classe de commande Vehicle
dans la execute()
méthode :
public class StartMotorcycle implements Command {
Vehicle vehicle;
public StartMotorcycle(Vehicle vehicle) {
this.vehicle = vehicle;
}
public void execute() {
vehicle.start();
}
@Override
public void revert() {
vehicle.stop();
}
}
public class AccelerateMotorcycle implements Command {
Vehicle vehicle;
public AccelerateMotorcycle(Vehicle vehicle){
this.vehicle = vehicle;
}
public void execute() {
vehicle.accelerate();
}
@Override
public void revert() {
vehicle.decelerate();
}
}
import java.util.List;
public class StartAllVehicles implements Command {
List<Vehicle> vehicles;
public StartAllVehicles(List<Vehicle> vehicles) {
this.vehicles = vehicles;
}
public void execute() {
vehicles.forEach(vehicle -> vehicle.start());
}
@Override
public void revert() {
vehicles.forEach(vehicle -> vehicle.stop());
}
}
Il est temps d'exécuter nos commandes ! Pour cela, nous instancions d'abord la Motorcycle
classe qui a le Command
comportement, puis nous le passons dans chaque Command
implémentation.
Notez que nous utilisons également la StartAllVehicles
commande pour démarrer (et arrêter) plusieurs véhicules à la fois.
Ensuite, nous instancions la GhostRider
classe qui exécutera chaque commande. Enfin, nous invoquons les méthodes takeAction()
et :revertAction()
public class RideVehicle {
public static void main(String[] args) {
Vehicle motorcycle = new Motorcycle();
StartMotorcycle startCommand = new StartMotorcycle(motorcycle);
GhostRider ghostRider = new GhostRider(startCommand);
ghostRider.takeAction();
AccelerateMotorcycle accelerateCommand = new AccelerateMotorcycle(motorcycle);
ghostRider.setCommand(accelerateCommand);
ghostRider.takeAction();
ghostRider.revertAction();
Vehicle truck = new Truck();
List<Vehicle> vehicles = List.of(motorcycle, truck);
StartAllVehicles startAllVehicles = new StartAllVehicles(vehicles);
startAllVehicles.execute();
startAllVehicles.revert();
}
}
Voici la sortie de ce code :
Starting motorcycle...
Accelerating motorcycle...
Decelerating motorcycle...
Starting motorcycle...
Starting truck...
Stopping motorcycle...
Stopping truck…
Une règle cruciale pour les modèles de conception est de savoir quand les utiliser. Peu importe la qualité d'un modèle, l'implémenter pour le mauvais cas d'utilisation rendra votre code bien pire. Voici quelques lignes directrices pour l'utilisation du modèle de commande :
Queue
, List
ou Set
dans l'implémentation d'une commande et les exécuter.Le cas d'utilisation développé ici implémente le modèle Command, mais il ne s'agit pas d'une situation réelle. Pour un cas d'utilisation plus courant dans les applications d'entreprise, consultez ma discussion sur l'utilisation du modèle de commande pour appliquer des remises dans un panier d'achat d'entreprise.
Pour résumer, rappelez-vous ce qui suit concernant le modèle de commande :
Thread
classe et Runnable
et ActionListener
les interfaces.Command
implémentation.Lien : https://www.infoworld.com/article/3667498/how-to-use-the-command-pattern-in-java.html
#Java
1657092516
Step Execution In Spring Batch
https://javatechonline.medium.com/step-execution-in-spring-batch-5ab52e006247
1656072039
How to Schedule a job in Java using Spring Boot Scheduler
#java #Java #scheduling #spring #spring-framework #spring-boot #cron
1656058261
How To Add JDK 18 Support In Eclipse?
https://javatechonline.com/how-to-add-jdk-18-support-in-eclipse/
1655985082
Java Design Patterns With Examples
https://javatechonline.com/java-design-patterns-java/
#java #Java #design-pattern #corejava