Tower Bridge
Piccadilly Circus
The Roman Baths
The circle
Notting Hill
Harrods
Total Pageviews
2017/06/30
2017/06/29
2017/06 UK
Heathrow airport
Bayswater street view
Buckingham Palace
Big Ben
British Museum
Cambridge
Windsor Castle at Windsor England
Bayswater street view
Buckingham Palace
Big Ben
British Museum
Cambridge
Windsor Castle at Windsor England
Labels:
Travel
2017/06/10
[Design Pattern] Builder Pattern
Definition of Builder Pattern
A complete Java builder pattern example
Example to use above builder pattern to create a User object
Benefits and Advantages
Conclusion
Using builder pattern for constructing objects when having a lot of parameters, especially if many of these parameters are null and when many of them share the same data type. A developer might feel that the extra code to implement a Builder might not justify its benefits for a small number of parameters, especially if the few parameters are required and of different types. In such cases, it might be considered desirable to use traditional constructors or, if immutability is not desired, use a no-argument constructor and require the client to know to call the necessary "set" methods.
Reference
[1] http://www.javaworld.com/article/2074938/core-java/too-many-parameters-in-java-methods-part-3-builder-pattern.html?page=2
[2] http://howtodoinjava.com/design-patterns/creational/builder-pattern-in-java/
- The builder pattern, as name implies, is an alternative way to construct complex objects.
- A builder pattern is more like fluent interface. A fluent interface is normally implemented by using method cascading (or method chaining).
- Builder pattern aims to “Separate the construction of a complex object from its representation so that the same construction process can create different representations.”
A complete Java builder pattern example
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 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | package albert.practice.designpattern.builder; import java.util.regex.Pattern; import lombok.Getter; import lombok.ToString; @Getter @ToString public class User { private final String firstName; private final String lastName; private final Integer age; private final String phone; private final String email; private User(UserBuilder builder) { this.firstName = builder.firstName; this.lastName = builder.lastName; this.age = builder.age; this.phone = builder.phone; this.email = builder.email; } public static class UserBuilder { private String firstName; private String lastName; private Integer age; private String phone; private String email; public UserBuilder firstName(String firstName) { this.firstName = firstName; return this; } public UserBuilder lastName(String lastName) { this.lastName = lastName; return this; } public UserBuilder age(Integer age) { this.age = age; return this; } public UserBuilder phone(String phone) { this.phone = phone; return this; } public UserBuilder email(String email) { this.email = email; return this; } public User build() { User user = new User(this); // Do some basic validations to check if (!isEmailValid(user.getEmail())) { throw new RuntimeException(user.getEmail() + " is invalid Email format!"); } return user; } public Boolean isEmailValid(String email) { Boolean isValid = Boolean.FALSE; Pattern EMAIL_PATTERN = Pattern.compile("^\\w+\\.*\\w+@(\\w+\\.){1,5}[a-zA-Z]{2,3}$"); if (EMAIL_PATTERN.matcher(email).matches()) { isValid = Boolean.TRUE; } return isValid; } } } |
Example to use above builder pattern to create a User object
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 | package albert.practice.designpattern.builder; import albert.practice.designpattern.builder.User.UserBuilder; import lombok.extern.slf4j.Slf4j; @Slf4j public class BuilderTest { public static void main(String[] args) { User albert = new UserBuilder() .lastName("Kuo") .firstName("Albert") .phone("1234567890") .age(30) .email("test@gmail.com") .build(); log.debug(" user1 = " + albert.toString()); User mandy = new UserBuilder() .lastName("Yeh") .firstName("Mandy") .email("yeh@gmail.com") .build(); log.debug(" user2 = " + mandy.toString()); } } |
Benefits and Advantages
- The number of lines of code increase at least to double in builder pattern, but the effort pays off in terms of design flexibility and much more readable code. The parameters to the constructor are reduced and are provided in highly readable method calls.
- The constructor is private, which means that this class can not be directly instantiated from the client code.
- The class is once again immutable. All attributes are final and they’re set on the constructor. Additionally, only provide getters for them.
- The builder uses the Fluent Interface idiom to make the client code more readable.
Conclusion
Using builder pattern for constructing objects when having a lot of parameters, especially if many of these parameters are null and when many of them share the same data type. A developer might feel that the extra code to implement a Builder might not justify its benefits for a small number of parameters, especially if the few parameters are required and of different types. In such cases, it might be considered desirable to use traditional constructors or, if immutability is not desired, use a no-argument constructor and require the client to know to call the necessary "set" methods.
Reference
[1] http://www.javaworld.com/article/2074938/core-java/too-many-parameters-in-java-methods-part-3-builder-pattern.html?page=2
[2] http://howtodoinjava.com/design-patterns/creational/builder-pattern-in-java/
Labels:
Design Pattern
2017/06/09
[Eclipse] project configuration is not up to date with pom.xml
Problem
I have Maven Project in Eclipse Mars.
One day I have an error in my project, but it does not have any negative effect to my implementation or maven build :
How-To
Although the root cause is still unclear, it works to follow these steps to get rid of this annoying error:
Step 1. Click this error => right click => Quick Fix
Step 2. Click Finish in Quick Fix window
Fixing problem in progress:
After fixing process, the problem is disappeared:
I have Maven Project in Eclipse Mars.
One day I have an error in my project, but it does not have any negative effect to my implementation or maven build :
How-To
Although the root cause is still unclear, it works to follow these steps to get rid of this annoying error:
Step 1. Click this error => right click => Quick Fix
Step 2. Click Finish in Quick Fix window
Fixing problem in progress:
After fixing process, the problem is disappeared:
2017/06/08
[Eclipse] EclEmma - Java Code Coverage for Eclipse
In computer science, code coverage is a measure used to describe the degree to which the source code of a program is executed when a particular test suite runs. A program with high code coverage, measured as a percentage, has had more of its source code executed during testing which suggests it has a lower chance of containing undetected software bugs compared to a program with low code coverage.
EclEmma is a free Java code coverage tool for Eclipse, it brings code coverage analysis directly into the Eclipse workbench.
Prerequisite
Prepare your unit test programs:
Execution
After you installed EclEmma Plugin, you can run Coverage as => JUnit Test
Then you can get the converge analysis report
Summary
While 100% code coverage is nice, it's not a good metric to blindly follow. 100% code coverage doesn't tell you anything other than you have tests that execute all your lines of code. Your code can still have bugs if that covered code does the wrong thing or doesn't do enough.
Reference
[1] https://en.wikipedia.org/wiki/Code_coverage
[2] http://www.eclemma.org/
[3] https://stackoverflow.com/questions/26360245/try-with-resource-unit-test-coverage
EclEmma is a free Java code coverage tool for Eclipse, it brings code coverage analysis directly into the Eclipse workbench.
Prerequisite
Prepare your unit test programs:
Execution
After you installed EclEmma Plugin, you can run Coverage as => JUnit Test
Then you can get the converge analysis report
Summary
While 100% code coverage is nice, it's not a good metric to blindly follow. 100% code coverage doesn't tell you anything other than you have tests that execute all your lines of code. Your code can still have bugs if that covered code does the wrong thing or doesn't do enough.
Reference
[1] https://en.wikipedia.org/wiki/Code_coverage
[2] http://www.eclemma.org/
[3] https://stackoverflow.com/questions/26360245/try-with-resource-unit-test-coverage
2017/06/07
[webMethods] Global Variable
Problem
若我們有些變數是全域使用的,在 webMethods 中要設定在哪邊,才能讓所有的 Java Service、Flow Service 使用?
How-To
可以在 Integration Server 設定 global variable,步驟如下:
Step 1. 進入 Integration Server Administrator,在 Navigation panel 中選擇 Settings => Global Variables
步驟 2. 按下 Add Global Variable
步驟 3. 輸入 key (Global variable 的名字) 與 value (Global variable 的值),並按下 Save Changes
接下來,我們可以建立一個 Flow Service 來做測試
步驟1. drag and drop debugLog 此套件到 Flow Service 中,點選 Pipeline tab,並點選 message
步驟 2. 在 message 中輸入 global variable 的名字,頭尾用 % 包起來,記得要勾選 Perform global variable substitution 此選項,並按下 OK 按鈕
步驟 3. 執行此 Flow Service 進行測試
若我們有些變數是全域使用的,在 webMethods 中要設定在哪邊,才能讓所有的 Java Service、Flow Service 使用?
How-To
可以在 Integration Server 設定 global variable,步驟如下:
Step 1. 進入 Integration Server Administrator,在 Navigation panel 中選擇 Settings => Global Variables
步驟 2. 按下 Add Global Variable
步驟 3. 輸入 key (Global variable 的名字) 與 value (Global variable 的值),並按下 Save Changes
接下來,我們可以建立一個 Flow Service 來做測試
步驟1. drag and drop debugLog 此套件到 Flow Service 中,點選 Pipeline tab,並點選 message
步驟 2. 在 message 中輸入 global variable 的名字,頭尾用 % 包起來,記得要勾選 Perform global variable substitution 此選項,並按下 OK 按鈕
步驟 3. 執行此 Flow Service 進行測試
Labels:
webMethods
2017/06/06
[Eclipse Plugin] EasyShell
While working in eclipse you may want to open selected file from project explorer to Windows File Explorer.
One way is by selecting file, go to properties, copying path and open Windows File Explorer then paste that path.
Another convenient way is to utilize EasyShell plugin
This Eclipse plugin allows to open a shell window or file manager from the popup menu in the navigation tree or editor view. Additionally it is possible to run selected file in the shell, copy file or directory path or run user defined external tools.
EasyShell usage looks like:
Reference
[1] https://marketplace.eclipse.org/content/easyshell
One way is by selecting file, go to properties, copying path and open Windows File Explorer then paste that path.
Another convenient way is to utilize EasyShell plugin
This Eclipse plugin allows to open a shell window or file manager from the popup menu in the navigation tree or editor view. Additionally it is possible to run selected file in the shell, copy file or directory path or run user defined external tools.
EasyShell usage looks like:
Reference
[1] https://marketplace.eclipse.org/content/easyshell
Labels:
Eclipse
2017/06/05
How to use Apache Commons CSV to Read/Write CSV file
Step 1. You need to add this dependency to your pom.xml
Step 2. Create a POJO class
Step 3. Here has an example regarding how to read/write CSV file via Apache Commons CSV
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-csv</artifactId> <version>1.4</version> </dependency>
Step 2. Create a POJO class
package albert.practice.csv; import java.io.Serializable; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.ToString; @Data @AllArgsConstructor @NoArgsConstructor @ToString public class OpcVo implements Serializable { private Integer ns; private String identifier; }
Step 3. Here has an example regarding how to read/write CSV file via Apache Commons CSV
package albert.practice.csv; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.CSVParser; import org.apache.commons.csv.CSVPrinter; import org.apache.commons.csv.CSVRecord; import lombok.extern.slf4j.Slf4j; @Slf4j public class CSVTest { // Delimiter used in CSV file private static final String NEW_LINE_SEPARATOR = "\n"; // CSV file header private static final String[] FILE_HEADER = {"ns", "identifier"}; // OpcVo attributes private static final String NS = "ns"; private static final String ID = "identifier"; public static void main(String[] args) throws IOException { String csvDirectory = "D:/work/AOCS/csv/"; String csvFileName = "test.csv"; CSVTest test = new CSVTest(); // test.writeToCSV(csvFolder.concat(csvFile)); List<OpcVo> opcs = test.readFromCsv(csvDirectory.concat(csvFileName)); opcs.forEach(opc -> log.debug(opc.toString())); } public void writeToCSV(String fileName) throws IOException { List<OpcVo> opcs = getDummyData(); // Create the CSVFormat object with "\n" as a record delimiter CSVFormat csvFileFormat = CSVFormat.DEFAULT.withRecordSeparator(NEW_LINE_SEPARATOR); try (FileWriter fileWriter = new FileWriter(fileName); CSVPrinter csvFilePrinter = new CSVPrinter(fileWriter, csvFileFormat);) { // Create CSV file header csvFilePrinter.printRecord(FILE_HEADER); // Write a new OpcVo object list to the CSV file for (OpcVo opc : opcs) { List dataRecord = new ArrayList<>(); dataRecord.add(String.valueOf(opc.getNs())); dataRecord.add(opc.getIdentifier()); csvFilePrinter.printRecord(dataRecord); } } catch (IOException e) { throw e; } } public List<OpcVo> readFromCsv(String fileName) throws IOException { // Create a new list of OpcVo to be filled by CSV file data List<OpcVo> result = new ArrayList<>(); // Create the CSVFormat object with the header mapping CSVFormat csvFileFormat = CSVFormat.DEFAULT.withHeader(FILE_HEADER); try (FileReader fileReader = new FileReader(fileName); CSVParser csvFileParser = new CSVParser(fileReader, csvFileFormat);) { List dataRecord = new ArrayList<>(); // Get a list of CSV file records List<CSVRecord> csvRecords = csvFileParser.getRecords(); for (int i = 1; i < csvRecords.size(); i++) { //Create a new OpcVo object and fill this data CSVRecord record = csvRecords.get(i); String ns = record.get(NS); String identifier = record.get(ID); result.add(new OpcVo(Integer.valueOf(ns), identifier)); } } catch (IOException e) { throw e; } return result; } private List<OpcVo> getDummyData() { OpcVo opc1 = new OpcVo(2, "Channel1.Device1.FireZone_01"); OpcVo opc2 = new OpcVo(2, "Channel1.Device1.EmergencyPushButton_01"); OpcVo opc3 = new OpcVo(2, "Channel1.Device1.EmergencyExitWindow_01"); OpcVo opc4 = new OpcVo(2, "Channel1.Device1.EmergencyExit_01"); return Arrays.asList(opc1, opc2, opc3, opc4); } }
Labels:
Apache Project
2017/06/04
[Windows 7] 如何將資料上傳到遠端桌面?
Problem
若我用 Windows 的遠端桌面連線程式連上遠端的電腦,我該如何將本機的檔案上傳到遠端的電腦?
How-to
步驟 1. 打開遠端桌面連線,點選『本機資源』,點選『其他』
步驟 2. 勾選要分享的目錄,如畫面中的隨身碟
步驟 3. 連線到遠端的電腦以後,可以在檔案總管看到 步驟 2. 勾選的磁碟機,若有檔案要從遠端複製回本機端,或者是從本機端複製到遠端,可以利用此磁碟機當作是分享的橋樑
若我用 Windows 的遠端桌面連線程式連上遠端的電腦,我該如何將本機的檔案上傳到遠端的電腦?
How-to
步驟 1. 打開遠端桌面連線,點選『本機資源』,點選『其他』
步驟 2. 勾選要分享的目錄,如畫面中的隨身碟
步驟 3. 連線到遠端的電腦以後,可以在檔案總管看到 步驟 2. 勾選的磁碟機,若有檔案要從遠端複製回本機端,或者是從本機端複製到遠端,可以利用此磁碟機當作是分享的橋樑
Labels:
MicrosoftWindows
2017/06/03
[webMethods] 如何從 Java Service 中讀取 Property File
在 Java Service 中,有些設定值我希望不要 hard code 在程式中,要搬到 property file 供日後的設定之用,該如何從 Java Service 中讀取 Property File
property file 檔名為 opc_config.properties ,內容如下:
我目前的開發的目錄是在 Acme 的 package之下:
property file 就要放在 [IntegrationServer 安裝目錄]\instances\default\packages\Acme\resources 之下
值得注意的是,當我們在 load 此 property file 時,路徑規範是 packages\\[你的 package name]\\resources\\[你的 property file name],如 packages\\Acme\\resources\\opc_config.properties ,若沒按照此規範會出現 FileNotFoundException
Sample code 如下:
相同的,如果你有一些設定用的檔案如 csv 等,也可以放在 resources 目錄下,透過相同的方式皆可讀取得到
Reference
[1] https://goo.gl/EFbLkg
property file 檔名為 opc_config.properties ,內容如下:
opc.url=opc.tcp://192.168.1.1:49320 opc.retry.interval=5 opc.max.retries=5 opc.sleep.ms=5000
我目前的開發的目錄是在 Acme 的 package之下:
property file 就要放在 [IntegrationServer 安裝目錄]\instances\default\packages\Acme\resources 之下
值得注意的是,當我們在 load 此 property file 時,路徑規範是 packages\\[你的 package name]\\resources\\[你的 property file name],如 packages\\Acme\\resources\\opc_config.properties ,若沒按照此規範會出現 FileNotFoundException
Sample code 如下:
/**
* The primary method for the Java service
*
* @param pipeline
* The IData pipeline
* @throws ServiceException
*/
public static final void PropertyFileUtils(IData pipeline) throws ServiceException {
String config_file = "packages\\Acme\\resources\\opc_config.properties";
try {
Properties properties = loadProperties(config_file);
String opcUrl = properties.getProperty("opc.url");
String retryInterval = properties.getProperty("opc.retry.interval");
String maxRetry = properties.getProperty("opc.max.retries");
String sleepMs = properties.getProperty("opc.sleep.ms");
logger("opcUrl = " + opcUrl);
logger("retryInterval = " + retryInterval);
logger("maxRetry = " + maxRetry);
logger("sleepMs = " + sleepMs);
} catch (IOException e) {
throw new ServiceException(e);
}
}
// --- <<IS-BEGIN-SHARED-SOURCE-AREA>> ---
public static Properties loadProperties(String config_file) throws ServiceException, IOException{
Properties properties = new Properties();
InputStream inputStream = null;
try {
inputStream = new FileInputStream(config_file);
properties.load(inputStream);
} catch (IOException e) {
throw new ServiceException(e);
} finally {
if (inputStream != null) {
inputStream.close();
}
}
return properties;
}
public static void logger(String message) throws ServiceException {
IData input = IDataFactory.create();
IDataCursor inputCursor = input.getCursor();
IDataUtil.put(inputCursor, "message", message);
IDataUtil.put(inputCursor, "function", "customLogger");
IDataUtil.put(inputCursor, "level", "INFO");
inputCursor.destroy();
try {
Service.doInvoke("pub.flow", "debugLog", input);
} catch (Exception e) {
throw new ServiceException(e);
}
}
// --- <<IS-END-SHARED-SOURCE-AREA>> ---
相同的,如果你有一些設定用的檔案如 csv 等,也可以放在 resources 目錄下,透過相同的方式皆可讀取得到
Reference
[1] https://goo.gl/EFbLkg
Labels:
webMethods
Subscribe to:
Posts (Atom)