I have nearly redundant java methods. The body of these methods is always the same. Only one or two java expressions (java code lines) are different. I want to do a code refactoring of these nearly redundant methods, but I'm searching for the best way to do this. It's not so easy, because of the dynamic code lines.
Here are three methods with the same body but with dynmamic java code in it:
public static final boolean doSomething1() {
Date date = new Date();
long currentTime = date.getTime();
long maxTime = currentTime + (TIMEOUT * 1000);
while (currentTime < maxTime) {
try {
//START OF MY DYNAMIC CODE
//example 1
for (WebElement element : list) {
if (element.isDisplayed()) {
element.click();
return true;
}
}
//END OF MY DYNAMIC CODE
}
catch (Exception e) {
LOG.error("exception");
}
currentTime = new Date().getTime();
}
return false;
}
public static final boolean doSomething2() {
Date date = new Date();
long currentTime = date.getTime();
long maxTime = currentTime + (TIMEOUT * 1000);
while (currentTime < maxTime) {
try {
//START OF MY DYNAMIC CODE
//example 2
for (WebElement webElement : webElementList) {
WebElement parent = getParentElement(webElement);
}
return true;
//END OF MY DYNAMIC CODE
}
catch (Exception e) {
LOG.error("exception");
}
currentTime = new Date().getTime();
}
return false;
}
public static final boolean doSomething3() {
Date date = new Date();
long currentTime = date.getTime();
long maxTime = currentTime + (TIMEOUT * 1000);
while (currentTime < maxTime) {
try {
//START OF MY DYNAMIC CODE
//example 3
for (WebElement element : list) {
if (element.isDisplayed() && element.getText().equalsIgnoreCase(size))
return true;
}
//END OF MY DYNAMIC CODE
}
catch (Exception e) {
LOG.error("exception");
}
currentTime = new Date().getTime();
}
return false;
}
So, how is it possible to write one method with the opportunity to set the dynamic lines of code?
You could use the Strategy Pattern.
Example using BooleanSupplier as Strategy:
private static boolean doSomethingHelper(BooleanSupplier checker) {
Date date = new Date();
long currentTime = date.getTime();
long maxTime = currentTime + (TIMEOUT * 1000);
while (currentTime < maxTime) {
try {
if (checker.getAsBoolean())
return true;
}
catch (Exception e) {
LOG.error("exception");
}
currentTime = new Date().getTime();
}
return false;
}
public static boolean doSomething1() {
return doSomethingHelper(() -> true);
}
public static boolean doSomething2() {
return doSomethingHelper(() -> false);
}
public static boolean doSomething3() {
return doSomethingHelper(() -> {
System.out.println("test");
return true;
});
}
Pass a boolean parameter whose value is the first operand of the X == true (which is more easily written as X):
public static final boolean doSomething1() {
return doSomethingCommon(true);
}
public static final boolean doSomething2() {
return doSomethingCommon(false);
}
private static final boolean doSomethingCommon(boolean param) {
// ...
if (param) {
return true;
}
// ...
}
You have several choices:
Aspect oriented programming
Strategy design pattern
Lambdas in JDK 8.
I'd prefer that last one. Everyone should be using JDK 8 now.
I hope lines of code like this are just hastily written poor examples, not typical of the way you write:
if (true == true)
Use the Template Method design pattern:
abstract class DynamicImpl {
protected abstract boolean doSomethingImpl();
public final boolean doSomething() {
Date date = new Date();
long currentTime = date.getTime();
long maxTime = currentTime + (TIMEOUT * 1000);
while (currentTime < maxTime) {
try {
if (doSomethingImpl()) {
return true;
}
}
catch (Exception e) {
LOG.error("exception");
}
currentTime = new Date().getTime();
}
return false;
}
}
With this class in place you can do your static methods as follows:
private static final DynamicImpl d1 = new DynamicImpl() {
protected boolean doSomethingImpl() {
return true;
}
};
private static final DynamicImpl d2 = new DynamicImpl() {
protected boolean doSomethingImpl() {
return false;
}
};
private static final DynamicImpl d3 = new DynamicImpl() {
protected boolean doSomethingImpl() {
System.out.println("test")
return true;
}
};
public static final boolean doSomething1() {
return d1.doSomething();
}
public static final boolean doSomething2() {
return d2.doSomething();
}
public static final boolean doSomething3() {
return d3.doSomething();
}
Related
I've implemented a stopwatch class for my own little library and tested it by executing the following snippet:
public class Main {
public static void main(String[] args) throws Exception {
StopWatch sw = new StopWatch();
sw.start();
Thread.sleep(3000);
sw.stop();
System.out.println(sw.getMilli());
System.out.println(sw.getDuration().getNano());
System.out.println(sw.getDuration().getSeconds());
}
}
I get the following result:
20
2011600
3
You can see that the numbers differ. I checked my StopWatch class round about 10 times, but I cant find mistakes. Can you find them?
This is my stopwatch-implementation:
import java.time.Instant;
import java.time.Duration;
public class StopWatch {
private Instant startDate;
private Instant stopDate;
public StopWatch() {
reset();
}
public void start() {
if (startDate == null) {
startDate = Instant.now();
}
}
public void stop() {
if (stopDate == null && startDate != null) {
stopDate = Instant.now();
}
}
public void reset() {
startDate = null;
stopDate = null;
}
public Duration getDuration() {
if (startDate != null && stopDate != null) {
return Duration.between(startDate, stopDate);
}
return null;
}
public long getMilli() {
if (startDate != null && stopDate != null) {
return Duration.between(startDate, stopDate).getNano() / 1000000L;
}
return 0;
}
}
I missunderstood how objects of the class Duration work. getNano() does not return the total amount of nanoseconds between a range, but the rest of nanoseconds that do not fit into a whole second. I deleted getDuration() and reimplemented getMilli() like that:
public long getMilli() {
if (startDate != null && stopDate != null) {
Duration duration = Duration.between(startDate, stopDate);
long nanos = duration.getSeconds() * 1000000000 + duration.getNano();
return nanos / 1000000;
}
return 0;
}
I want to return a String from a callback
My class which fetch date from server in a thread and i want this value in main thread as a String. I am beginner in Java.
public class InternetDate {
private final Activity activity;
private String finalDate = "";
public InternetDate(Activity activity) {
this.activity = activity;
}
public void setDateAndTimeFormat(String dateAndTimeFormat) {
mDateAndTimeFormat = dateAndTimeFormat;
}
public void getCurrentDate(OnGetDate onGetDate) {
new BackgroundTask(activity) {
#Override
public void doInBackground() {
try {
finalDate = getCurrentDateFromInternet();
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
}
#Override
public void onPostExecute() {
try {
JSONObject jb = new JSONObject(finalDate);
String name = jb.getString("UnixTimeStamp");
onGetDate.onSuccess(name);
if (progressDialog.isShowing()) {
progressDialog.dismiss();
}
} catch (JSONException e) {
}
}
}.execute();
}
private String getCurrentDateFromInternet() throws Exception {
String date_api = example.com/api;
URL url = new URL(date_api);
BufferedReader in = null;
try {
in = new BufferedReader(new InputStreamReader(url.openStream()));
return in.readLine();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
}
}
}
public interface OnGetDate {
void onSuccess(String date);
}
I want this as a String. Please help me to archive this String in MainThread
private String getDate(){
String currentDate = "";
InternetDate internetDate = new InternetDate(this);
internetDate.getCurrentDate(new InternetDate.OnGetDate() {
#Override
public void onSuccess(String date) {
currentDate = date; // Null return
}
});
return currentDate;
}
You might wait for the response using a semaphore, but this kind of code is blocking by nature and leads to apps with a poor user experience, because the ui thread is blocked during the whole process
//import java.util.concurrent.*;
//[...]
private String getDate() throws TimeoutException {
final String[] result = new String[]{null};
final Semaphore sem = new Semaphore(0);
new InternetDate(this).getCurrentDate(new InternetDate.OnGetDate() {
#Override
public void onSuccess(String date) {
result[0] = date; // Null return
sem.release();
}
});
try {
if (sem.tryAcquire(10, TimeUnit.SECONDS)) {
return result[0];
} else {
throw new TimeoutException("no response after 10 seconds");
}
} catch(InterruptedException e) {
return null;
}
}
You can use Executors :
private String getDate() throws ExecutionException, InterruptedException {
// This line is non-blocking:
Future<String> future = Executors.newCachedThreadPool()
.submit(() -> new InternetDate().getCurrentDateFromInternet());
// The invocation of 'get' is blocking:
return future.get();
}
I assume getCurrentDateFromInternet returns the date in the format you want.
Your problem can be solved using a MutableLiveData object without blocking the UI thread.
Let's start assuming you have a main class named MainThread where your getDate method lives.
In this class first create the following MutableLiveData object:
private MutableLiveData<String> date = new MutableLiveData<>();
The object above will be updated with the date value as soon as it's available to your program.
Next create/update the method that'll make a call to the getDate method (which we'll keep for simplicity's sake):
private void exampleDateMethod() {
// first create an observer; in the observer you put the code that does something with the Date
date.observe(this, new Observer<String>() {
#Override
public void onChanged( String date ) {
// this is where you do something with the date, an example:
findViewById( R.id.date_view ).setText( date );
}
});
// pass the MutableLiveData to the getDate method so that its value can be updated:
getDate( date );
}
And change the getDate method to pass the Date to the MutableLiveData object:
private void getDate( MutableLiveData<String> liveDate ){
internetDate.getCurrentDate(new InternetDate.OnGetDate() {
#Override
public void onSuccess(String date) {
// set the value of the MutableLiveData object, this will notify the observer and execute the code in its onChanged method
liveData.setValue( date );
}
});
}
I spawn worker threads to do job:
List<Future<WorkerInfo>> futures = new ArrayList<>();
for (int i = 0; i < numOfUsers; i++) {
Future<WorkerInfo> future = threadExecutor.submit(() -> runLoad(arguments));
futures.add(future);
}
Now runLoad(..) function returns the state of the worker:
private WorkerInfo runLoad(int load,...) {
// start of the load
long start = System.currentTimeMillis();
Thread.currentThread().setName("LoadWorker with load: " + load);
try {
for (int i = 0; i < load; i++) {
// do something
}
long end = System.currentTimeMillis() - start;
return WorkerInfo .success(load, end);
} catch (IOException e) {
long end = System.currentTimeMillis() - start;
return new WorkerInfo (load, end, e.getMessage(), e);
}
}
The WorkerInfo class is simple class holding data:
public class WorkerInfo {
private final int load;
private final long time;
private final String message;
private final Throwable error;
public WorkerInfo (int load, long time, String message, Throwable error) {
this.load = load;
this.time = time;
this.message = message;
this.error = error;
}
public static WorkerInfo success(int load, long end) {
return new WorkerInfo(load,end,"",null);
}
public boolean hasError(){
return error != null;
}
public int getLoad() {
return load;
}
public String getMessage() {
return message;
}
public Throwable getError() {
return error;
}
}
Now i want to check if there was any error after the execution has finnished.
private void checkError(List<Future<WorkerInfo>> futures) {
List<String> errors = new ArrayList<>();
for (Future<WorkerInfo > future : futures) {
WorkerInfo workerInfo = unpackFuture(future);
if (workerInfo .hasError()) {
String message = workerInfo .getMessage();
errors.add(message);
}
}
if (!errors.isEmpty()) {
// what to throw here?
}
}
WHat is the best practice when multiple worker throw error? Lets say i am running 6 workers and 4 of them end with error. What error message should i throw then? What is the best way to aggregate the error messages into one? Or how to handle this?
Thanks for help!
I'm trying to learn how to use Hystrix. I've created this class below:
public class CommandReturnAllExceptFive extends HystrixCommand<Integer> {
public static final Integer SLEEP_TIME = 5000;
private Integer x;
public CommandReturnAllExceptFive(Integer x) {
super(getHystrixConfiguration());
this.x = x;
System.out.println("Is circuit breaker open? " + (this.circuitBreaker.isOpen() ? "yes" : "no"));
System.out.println("Requests so far: "+(this.metrics.getRollingCount(HystrixEventType.FAILURE)));
}
public void setX(Integer x) {
this.x = x;
}
private static HystrixCommand.Setter getHystrixConfiguration() {
HystrixCommandProperties.Setter properties
= HystrixCommandProperties.Setter()
.withCircuitBreakerSleepWindowInMilliseconds(SLEEP_TIME)
.withCircuitBreakerEnabled(true)
.withCircuitBreakerRequestVolumeThreshold(1)
.withCircuitBreakerErrorThresholdPercentage(1)
.withMetricsRollingStatisticalWindowBuckets(1)
.withMetricsRollingStatisticalWindowBuckets(1);
HystrixCommandGroupKey groupKey = HystrixCommandGroupKey.Factory.asKey("ReturnAllExceptFive");
return HystrixCommand.Setter.withGroupKey(groupKey).andCommandPropertiesDefaults(properties);
}
protected Integer run() throws Exception {
if (x == 5) {
throw new Exception();
}
return x;
}
}
with the following unit test:
#Test
public void testCommandReturnAllExceptFive_doesStallBeforeCallingAgain() {
boolean exceptionIsThrown = false;
try {
CommandReturnAllExceptFive returnAllExceptFive = new CommandReturnAllExceptFive(5);
returnAllExceptFive.execute();
} catch (Exception ex) {
exceptionIsThrown = true;
}
assertThat(exceptionIsThrown, is(true));
long timeNow = System.currentTimeMillis();
boolean callIsSuccessful = false;
while (!callIsSuccessful) {
try {
CommandReturnAllExceptFive returnAllExceptFive = new CommandReturnAllExceptFive(1);
returnAllExceptFive.execute();
callIsSuccessful = true;
} catch (Exception ex) {
}
}
long timeAfter = System.currentTimeMillis();
long timeToSuccess = timeAfter - timeNow;
System.out.println("timeNow: "+timeNow+"\ntimeAfter: "+timeAfter);
//assertThat(timeToSuccess >= CommandReturnAllExceptFive.SLEEP_TIME, is(true));
}
which is basically verifying that the call fails at 5, and that it does stall for the specified period of time after a successful execution. The debugging statements indicate that the circuit is never closed, but it should be closed after the first call since that one throws an exception, hence indicating failure. Can anyone help me out here?
I would like to know how to access the Service and Domains properly in this sample class placed in src/java folder
public class NewsIngestion implements Runnable {
private String str;
private int num;
private Logger log = Logger.getLogger("grails.app");
private static boolean isRunning;
private Thread t;
private WorkerJobService jobService;
private NewsService newsService;
public NewsIngestion(String s, int n)
{
jobService = new WorkerJobService();
newsService = new NewsService();
str = s;
num = n;
isRunning = false;
t = new Thread (this, "NewsIngestion");
}
public void run ()
{
while(isRunning){
try{
if(jobService.isJobEnabled("ConsumeFeedsJob") && jobService.lockJob("ConsumeFeedsJob")){
log.info("${this.class.name}: ConsumeFeedsJob started");
try{
// get all sources
List sources = (List) InvokerHelper.invokeMethod(RSSFeed.class, "list", null);
for(int i = 0; i < sources.size(); i++) {
RSSFeed s = (RSSFeed) sources.get(i);
// check if it's time to read the source
int diff = DateTimeUtil.getSecondsDateDiff(s.getLastChecked(), new Date());
if(s.getLastChecked() == null || diff >= s.getCheckInterval()){
List keyword_list = (List) InvokerHelper.invokeMethod(Keyword.class, "list", null);
for(int j = 0; j < keyword_list.size(); j++) {
String keyword = (String) keyword_list.get(j);
try{
newsService.ingestNewsFromSources(keyword, s);
}catch(Exception e){
log.error("${this.class.name}: ${e}");
}
log.debug("Completed reading feeds for ${keyword}.");
log.info("${this.class.name}: Reading feeds for '${keyword}' (${s.feedName}) took ${Float.toString(st2.getDuration())} second(s).");
}
s.setLastChecked(new Date());
InvokerHelper.invokeMethod(RSSFeed.class, "save", null);
}
log.info("${this.class.name}: Reading feeds for '${s.feedName}' for all keywords took ${Float.toString(st.getDuration())} second(s).");
}
}catch(Exception e){
log.error("${this.class.name}: Exception: ${e}");
}
log.info("${this.class.name}: ConsumeFeedsJob ended.");
// unlock job
jobService.unlockJob("ConsumeFeedsJob");
}
log.info("alfred: success");
}
catch (Exception e){
log.info("alfred exception: " + e.getMessage());
}
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
log.info(e.getMessage());
}
}
}
public void start() {
if(t == null){
t = new Thread (this, "NewsIngestion");
}
if(!isRunning){
isRunning = true;
t.start();
}
}
public void stop() {
isRunning = false;
}
public boolean isRunning() {
return isRunning;
}
}
I'm encountering this error message:
No Hibernate Session bound to thread,
and configuration does not allow
creation of non-transactional one here
Thanks.
You shouldn't instantiate the service class by yourself, but instead take the class instance from the main context
import org.codehaus.groovy.grails.commons.ApplicationHolder
def ctx = ApplicationHolder.application.mainContext
def newsService = ctx.newsService
If you're using Java
import org.codehaus.groovy.grails.commons.ApplicationHolder
public class SomeClass {
SomeService someService;
public SomeClass() {
someService = (SomeService) ApplicationHolder.getApplication().getMainContext().getBean("someService");
}
}
Consider using Spring and #Transactional annotation or AOP.