Merge pull request #42 from joshzambales/master

Updated pull request
This commit is contained in:
Ilkka Seppälä 2015-04-04 20:59:23 +03:00
commit 477d622d04
15 changed files with 382 additions and 2 deletions

View File

@ -1,4 +1,3 @@
# Design pattern samples in Java. # Design pattern samples in Java.
## Build status: ## Build status:
@ -62,6 +61,13 @@ Behavioral patterns are concerned with algorithms and the assignment of responsi
* [Callback](#callback) * [Callback](#callback)
* [Execute Around](#execute-around) * [Execute Around](#execute-around)
### Presentation Tier Patterns
Presentation Tier patterns are the top-most level of the application, this is concerned with translating tasks and results to something the user can understand.
* [Intercepting Filter](#intercepting-filter)
## <a name="abstract-factory">Abstract Factory</a> [&#8593;](#list-of-design-patterns) ## <a name="abstract-factory">Abstract Factory</a> [&#8593;](#list-of-design-patterns)
**Intent:** Provide an interface for creating families of related or dependent objects without specifying their concrete classes. **Intent:** Provide an interface for creating families of related or dependent objects without specifying their concrete classes.
@ -431,6 +437,17 @@ Behavioral patterns are concerned with algorithms and the assignment of responsi
**Applicability:** Use the Callback pattern when **Applicability:** Use the Callback pattern when
* When some arbitrary synchronous or asynchronous action must be performed after execution of some defined activity. * When some arbitrary synchronous or asynchronous action must be performed after execution of some defined activity.
## <a name="intercepting-filter">Intercepting Filter</a> [&#8593;](#list-of-design-patterns)
**Intent:** Provide pluggable filters to conduct necessary pre-processing and post-processing to requests from a client to a target
![alt text](https://github.com/iluwatar/java-design-patterns/blob/master/intercepting-filter/etc/Intercepting-filter.png "Intercepting Filter")
**Applicability:** Use the Intercepting Filter pattern when
* a system uses pre-processing or post-processing requests
* a system should do the authentication/ authorization/ logging or tracking of request and then pass the requests to corresponding handlers
* you want a modular approach to configuring pre-processing and post-processing schemes
**Real world examples:** **Real world examples:**
* [CyclicBarrier] (http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CyclicBarrier.html#CyclicBarrier%28int,%20java.lang.Runnable%29) constructor can accept callback that will be triggered every time when barrier is tripped. * [CyclicBarrier] (http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CyclicBarrier.html#CyclicBarrier%28int,%20java.lang.Runnable%29) constructor can accept callback that will be triggered every time when barrier is tripped.
@ -453,6 +470,7 @@ Behavioral patterns are concerned with algorithms and the assignment of responsi
**Real world examples:** **Real world examples:**
* [JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain) prototype inheritance * [JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain) prototype inheritance
# Frequently asked questions # Frequently asked questions
**<a id="Q1">Q: What is the difference between State and Strategy patterns?</a>** **<a id="Q1">Q: What is the difference between State and Strategy patterns?</a>**
@ -476,7 +494,7 @@ The difference is the intent of the patterns. While Proxy controls access to the
1. Fork the repository. 1. Fork the repository.
2. Implement the code changes in your fork. Remember to add sufficient comments documenting the implementation. 2. Implement the code changes in your fork. Remember to add sufficient comments documenting the implementation.
3. Create a simple class diagram from your example code. 3. Create a simple class diagram from your example code.
4. Add description of the pattern in README.md and link to the class diagram. 4. Add description of the pattern in README.md and link to the class diagram.
5. Create a pull request. 5. Create a pull request.
**For creating/editing UML diagrams** you need one of the following: **For creating/editing UML diagrams** you need one of the following:
@ -497,10 +515,13 @@ The difference is the intent of the patterns. While Proxy controls access to the
* [Lets Modify the Objects-First Approach into Design-Patterns-First](http://edu.pecinovsky.cz/papers/2006_ITiCSE_Design_Patterns_First.pdf) * [Lets Modify the Objects-First Approach into Design-Patterns-First](http://edu.pecinovsky.cz/papers/2006_ITiCSE_Design_Patterns_First.pdf)
* [Pattern Languages of Program Design](http://www.amazon.com/Pattern-Languages-Program-Design-Coplien/dp/0201607344/ref=sr_1_1) * [Pattern Languages of Program Design](http://www.amazon.com/Pattern-Languages-Program-Design-Coplien/dp/0201607344/ref=sr_1_1)
* [Martin Fowler - Event Aggregator](http://martinfowler.com/eaaDev/EventAggregator.html) * [Martin Fowler - Event Aggregator](http://martinfowler.com/eaaDev/EventAggregator.html)
* [TutorialsPoint - Intercepting Filter](http://www.tutorialspoint.com/design_pattern/intercepting_filter_pattern.htm)
* [Presentation Tier Pattern](http://www.javagyan.com/tutorials/corej2eepatterns/presentation-tier-patterns)
* [Functional Programming in Java: Harnessing the Power of Java 8 Lambda Expressions](http://www.amazon.com/Functional-Programming-Java-Harnessing-Expressions/dp/1937785467/ref=sr_1_1) * [Functional Programming in Java: Harnessing the Power of Java 8 Lambda Expressions](http://www.amazon.com/Functional-Programming-Java-Harnessing-Expressions/dp/1937785467/ref=sr_1_1)
# License # License
This project is licensed under the terms of the MIT license. This project is licensed under the terms of the MIT license.

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

View File

@ -0,0 +1,18 @@
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.iluwatar</groupId>
<artifactId>java-design-patterns</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>intercepting-filter</artifactId>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,14 @@
package com.iluwatar;
/**
* Concrete implementation of filter
* This filter is responsible for checking/filtering the input in the address field, returns null if field is empty
* @author joshzambales
*
*/
public class AddressFilter implements Filter{
public String execute(String[] request){
if(request[2].equals("")){
return null;
}else return request[2];
}
}

View File

@ -0,0 +1,35 @@
package com.iluwatar;
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.*;
/**
*
* This is an app that checks whether the order request is valid through pre-processing done via Filters
* Each field has its own corresponding Filter
* @author joshzambales
*
*/
public class App{
public static void main(String[] args){
FilterManager filterManager = new FilterManager(new Target());
filterManager.setFilter(new NameFilter());
filterManager.setFilter(new ContactFilter());
filterManager.setFilter(new AddressFilter());
filterManager.setFilter(new DepositFilter());
filterManager.setFilter(new OrderFilter());
Client client = new Client();
client.setFilterManager(filterManager);
}
}

View File

@ -0,0 +1,90 @@
package com.iluwatar;
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.*;
/**
* The Client class is responsible for handling the input and running them through filters inside the filterManager
*
* This is where Filters come to play as the client pre-processes the request before being displayed in the Target
*
* @author joshzambales
*
*/
public class Client extends JFrame{
private FilterManager filterManager;
private JLabel jl;
private JTextField[] jtFields;
private JTextArea[] jtAreas;
private JButton clearButton, processButton;
public Client(){
super("Client System");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(300,300);
jl = new JLabel("RUNNING...");
jtFields = new JTextField[3];
for(int i = 0; i < 3; i++){
jtFields[i] = new JTextField();
}
jtAreas = new JTextArea[2];
for(int i = 0; i < 2; i++){
jtAreas[i] = new JTextArea();
}
clearButton = new JButton("Clear");
processButton = new JButton("Process");
setup();
}
private void setup(){
setLayout(new BorderLayout());
JPanel panel = new JPanel();
add(jl,BorderLayout.SOUTH);
add(panel, BorderLayout.CENTER);
panel.setLayout(new GridLayout(6,2));
panel.add(new JLabel("Name"));
panel.add(jtFields[0]);
panel.add(new JLabel("Contact Number"));
panel.add(jtFields[1]);
panel.add(new JLabel("Address"));
panel.add(jtAreas[0]);
panel.add(new JLabel("Deposit Number"));
panel.add(jtFields[2]);
panel.add(new JLabel("Order"));
panel.add(jtAreas[1]);
panel.add(clearButton);
panel.add(processButton);
clearButton.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e){
for(JTextArea i : jtAreas){
i.setText("");
}
for(JTextField i : jtFields){
i.setText("");
}
}
});
processButton.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e){
String request = String.format("%s&%s&%s&%s&%s",jtFields[0].getText(),jtFields[1].getText(),jtAreas[0].getText(),jtFields[2].getText(),jtAreas[1].getText());
jl.setText(sendRequest(request));
}
});
JRootPane rootPane = SwingUtilities.getRootPane(processButton);
rootPane.setDefaultButton(processButton);
setVisible(true);
}
public void setFilterManager(FilterManager filterManager){
this.filterManager = filterManager;
}
public String sendRequest(String request){
return filterManager.filterRequest(request);
}
}

View File

@ -0,0 +1,14 @@
package com.iluwatar;
/**
* Concrete implementation of filter
* This filter checks for the contact field in which it checks if the input consist of numbers and it also checks if the input follows the length constraint (11 digits)
* @author joshzambales
*
*/
public class ContactFilter implements Filter{
public String execute(String[] request){
if(request[1].equals("") || request[1].matches(".*[^\\d]+.*") || request[1].length() != 11){
return null;
}else return request[1];
}
}

View File

@ -0,0 +1,15 @@
package com.iluwatar;
/**
* Concrete implementation of filter
*
* This checks for the deposit code, returns null when deposit field is empty
* @author joshzambales
*
*/
public class DepositFilter implements Filter{
public String execute(String[] request){
if(request[3].equals("")){
return null;
}else return request[3];
}
}

View File

@ -0,0 +1,11 @@
package com.iluwatar;
/**
* Filter interface
* Filters perform certain tasks prior or after execution of request by request handler.
* In this case, before the request is handled by the target, the request undergoes through each Filter
* @author joshzambales
*
*/
public interface Filter{
public String execute(String[] request);
}

View File

@ -0,0 +1,49 @@
package com.iluwatar;
import java.util.*;
/**
* Filter Chain carries multiple filters and help to execute them in defined order on target.
*
* @author joshzambales
*/
public class FilterChain{
private ArrayList<Filter> filters = new ArrayList<Filter>();
private final Target target;
public FilterChain(Target target){
this.target = target;
}
public void addFilter(Filter filter){
filters.add(filter);
}
public String execute(String request){
String tempout[] = new String[filters.size()];
String tempin[] = request.split("&");
int i = 0;
try{
for(Filter filter:filters){
tempout[i] = null;
tempout[i++] = filter.execute(tempin);
}
}catch(Exception e){
return "NOT ENOUGHT INPUT";
}
if(tempout[4] == null){
return "INVALID ORDER!";
}else if(tempout[3] == null){
return "INVALID DEPOSIT NUMBER!";
}else if(tempout[2] == null){
return "INVALID ADRDESS!";
}else if(tempout[1] == null){
return "INVALID Contact Number!";
}else if(tempout[0] == null){
return "INVALID Name!";
}else{
target.execute(tempout);
return "RUNNING...";
}
}
}

View File

@ -0,0 +1,24 @@
package com.iluwatar;
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.*;
/**
* Filter Manager manages the filters and Filter Chain.
* @author joshzambales
*
*/
public class FilterManager{
private FilterChain filterChain;
public FilterManager(Target target){
filterChain = new FilterChain(target);
}
public void setFilter(Filter filter){
filterChain.addFilter(filter);
}
public String filterRequest(String request){
return filterChain.execute(request);
}
}

View File

@ -0,0 +1,14 @@
package com.iluwatar;
/**
* Concrete implementation of filter
* This filter checks if the input in the Name field is valid. (alphanumeric)
* @author joshzambales
*
*/
public class NameFilter implements Filter{
public String execute(String[] request){
if(request[0].equals("") || request[0].matches(".*[^\\w|\\s]+.*")){
return null;
}else return request[0];
}
}

View File

@ -0,0 +1,15 @@
package com.iluwatar;
/**
* Concrete implementation of filter
* This checks for the order field, returns null when order field is empty
*
* @author joshzambales
*
*/
public class OrderFilter implements Filter{
public String execute(String[] request){
if(request[4].equals("")){
return null;
}else return request[4];
}
}

View File

@ -0,0 +1,59 @@
package com.iluwatar;
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.*;
/**
* This is where the requests are displayed after being validated by filters.
*
* @author mjoshzambales
*
*/
public class Target extends JFrame{
private JTable jt;
private JScrollPane jsp;
private DefaultTableModel dtm;
private JButton del;
public Target(){
super("Order System");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(640,480);
dtm = new DefaultTableModel(new Object[]{"Name", "Contact Number", "Address", "Deposit Number", "Order"},0);
jt = new JTable(dtm);
del = new JButton("Delete");
setup();
}
private void setup(){
setLayout(new BorderLayout());
JPanel bot = new JPanel();
add(jt.getTableHeader(), BorderLayout.NORTH);
bot.setLayout(new BorderLayout());
bot.add(del, BorderLayout.EAST);
add(bot, BorderLayout.SOUTH);
jsp = new JScrollPane(jt);
jsp.setPreferredSize(new Dimension(500,250));
add(jsp, BorderLayout.CENTER);
del.addActionListener(new DListener());
JRootPane rootPane = SwingUtilities.getRootPane(del);
rootPane.setDefaultButton(del);
setVisible(true);
}
public void execute(String[] request){
dtm.addRow(new Object[]{request[0],request[1],request[2],request[3],request[4]});
}
class DListener implements ActionListener{
@Override
public void actionPerformed(ActionEvent e){
int temp = jt.getSelectedRow();
if(temp == -1) return;
int temp2 = jt.getSelectedRowCount();
for(int i = 0; i < temp2; i++){
dtm.removeRow(temp);
}
}
}
}

View File

@ -43,6 +43,7 @@
<module>callback</module> <module>callback</module>
<module>execute-around</module> <module>execute-around</module>
<module>property</module> <module>property</module>
<module>intercepting-filter</module>
</modules> </modules>
<dependencyManagement> <dependencyManagement>