Desing pattern suggestions for sequential jobs which follows previous steps output - java

I want to design a subtitle-word parser. It works like that;
Check subtitle provider for availability
Fetch subtitle as inputStream
Convert inputStream to lines of text
Parse lines to sections ( A subtitle file includes 100 - 110 sections )
Parse sections' sentences to words
Save subtitle, section and word to DB
As you see every step follows previous steps output.
Which design pattern(s) I should use?

I'd consider using state design pattern, which is like strategy design pattern but contains current state in its context.
So you'd have something like this:
class ProcessingData {
private State state = new CheckAvailabilityState();
//Fill with all data related to the subtitle-word parser
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
}
}
interface State {
void next(ProcessingData processingData);
void prev(ProcessingData processingData);
void execute();
}
class CheckAvailabilityState implements State {
#Override
public void next(ProcessingData processingData) {
processingData.setState(new FetchSubtitlesState());
}
#Override
public void prev(ProcessingData processingData) {
//this is 1st step so no prev
}
#Override
public void execute() {
//Availability check goes here ..
}
}
class FetchSubtitlesState implements State {
#Override
public void next(ProcessingData processingData) {
//ConvertState
}
#Override
public void prev(ProcessingData processingData) {
processingData.setState(new CheckAvailabilityState());
}
#Override
public void execute() {
//Fetching goes here ...
}
}
But I'm not sure about complexity or the need for design patterns considering the problem.

Related

Why page cannot get bookmarked with History mechanism in GWT/MVP4G.?

I am trying to implement history mechanism with a GWT app but has problem with page bookmark i.e. in my case, I have created 3 pages where one get invoked from another. Now, the problem is if page3 is bookmarked then while invoking that bookmark it should open page3 instead now it opens Home page.
Why is it so.? What can be the issue.?
I have implemented HistoryConverter as,
#History(type=HistoryConverterType.SIMPLE)
public class MyHistoryConverter implements HistoryConverter<HistoryManagerEventBus> {
public MyHistoryConverter() {
}
#Override
public void convertFromToken(String historyName, String param,HistoryManagerEventBus eventBus) {
eventBus.dispatch(historyName);
}
public String convertToToken(String eventType){
return eventType;
}
public String convertToToken(String eventType,HistoryPageTwoView view){
return view.getClass().getName();
}
public String convertToToken(String eventType,HistoryPageThreeView view){
return view.getClass().getName();
}
#Override
public boolean isCrawlable() {
return false;
}
}
and eventBus as,
#Events(startPresenter = HistoryPageOnePresenter.class,historyOnStart=true)
public interface HistoryManagerEventBus extends EventBusWithLookup {
/**
* Start event will be fired internally
*/
#Start
#Event(handlers = HistoryPageOnePresenter.class,historyConverter=MyHistoryConverter.class)
void start();
#InitHistory
#Event(handlers = HistoryPageOnePresenter.class)
void init();
#Event(handlers = HistoryPageTwoPresenter.class,historyConverter=MyHistoryConverter.class)
void getHistoryPageTwo();
#Event(handlers=HistoryPageThreePresenter.class,historyConverter=MyHistoryConverter.class)
void getHistoryPageThree();
#Event(handlers=HistoryPageOnePresenter.class,historyConverter=MyHistoryConverter.class)
void getHistoryPageOne();
#Event(handlers=HistoryPageOnePresenter.class)
void setHistoryPageTwo(HistoryPageTwoView view);
#Event(handlers=HistoryPageOnePresenter.class)
void setHistoryPageThree(HistoryPageThreeView view);
}
Assuming that:
#Event(handlers = HistoryPageTwoPresenter.class,historyConverter=MyHistoryConverter.class)
void getHistoryPageTwo();
#Event(handlers=HistoryPageThreePresenter.class,historyConverter=MyHistoryConverter.class)
void getHistoryPageThree();
#Event(handlers=HistoryPageOnePresenter.class,historyConverter=MyHistoryConverter.class)
void getHistoryPageOne();
are your navigation events, there is no need to have the following methods inside the MyHistoryConverter class defined:
public String convertToToken(String eventType,HistoryPageTwoView view){
return view.getClass().getName();
}
public String convertToToken(String eventType,HistoryPageThreeView view){
return view.getClass().getName();
}
as they are not called to create history tokens.
If your history converter works, you should see something like that in your URL:
[myURL]#getHistoryPageOne
or
[myURL]#getHistoryPageTwo
or
[myURL]#getHistoryPageThree
If you entering:
[myURL]#getHistoryPageThree
to start your application, the tokens will be handle in the convertFromToken-method.
You can add the #Debug-annotation to your eventBus to verify that the bookmarked event is fired at the start of your application.
So everything looks good, except the fact, that the Start-event should not have a historyConverter-attribute.

State pattern: Identify state class type from string

Background
I have a command that uses the state pattern. When the command state changes I am notified in the UI that for example class stageOneState is now the active state. Is it bad practice to check the state class type using a string as an identifier? Is this undoing the work of the state pattern?
What would be an alternative?
Example
if (notifiedState.type == "state1") {
// Update UI accroding to state1
} else ...
Example
Example from http://www.tutorialspoint.com/design_pattern/state_pattern.htm
public interface State {
public void doAction(Context context);
}
public class StartState implements State {
public void doAction(Context context) {
System.out.println("Player is in start state");
context.setState(this);
}
public String toString(){
return "Start State";
}
}
public class StopState implements State {
public void doAction(Context context) {
System.out.println("Player is in stop state");
context.setState(this);
}
public String toString(){
return "Stop State";
}
}
public class Context {
private State state;
public Context(){
state = null;
}
public void setState(State state){
this.state = state;
}
public State getState(){
return state;
}
}
public class StatePatternDemo {
public static void main(String[] args) {
Context context = new Context();
StartState startState = new StartState();
startState.doAction(context);
System.out.println(context.getState().toString());
StopState stopState = new StopState();
stopState.doAction(context);
System.out.println(context.getState().toString());
}
}
You undo the state pattern when you check the state of an object from the outside and then act differently depending on which state it is. If it seems more convenient, then probably state is the wrong tool for the job.
The sentence "command having a state" raises a red flag. Is this some ungodly mashup of state and command patterns?
There is a terrible error in the example: you are comparing strings using identity instead of value.
Generally, if you have any doubts about any pattern, just don't try to use it. They are poisonous animals, better studied from safe distance.
This pattern is sometimes called stringly typed (a pun on strongly typed).
The best approach is to use an enum.

Composite pattern and instanceof

let's imagine the following situation: I want to design a bidding application (like ebay) with the composite design pattern
I create an abstract superclass like "BidComponent" (which has getName()) and two subclasses "Article" and "Category".
Category has a List which can contain other BidComponents, Article does not implement a List but a getPrice() method.
If I want to iterate through this structure and I want to print out the Category-Article-Structure I need instanceof:
if(element instanceof Article){
Article article = (Article)element;
System.out.println(article.getName() + ":" + article.getPrice());
}else{
Category category = (Category)element;
System.out.println(category.getName());
}
This seems pretty wrong to me. Is there a better way to realise this (So without always checking the type via instanceof)? I ask this question because I read several times that using instanceof is bad design...
//Edit to mention my problem with Visitors:
Ok. But let's imagine I want to search the highest bid to all products. So I have
public class HighestBidVisitor implements BidComponentVisitor{
private double highestBid = 0d;
public HighestBidVisitor(Category category){
visitCategory(category);
}
#Override
public void visitCategory(Category category){
Iterator<BidComponent> elementsIterator = category.iterator();
while(elementsIterator.hasNext()){
BidComponent bidComponent = elementsIterator.next();
//Now I have again the problem: I have to check if a component in the Categorylist is an article or a category
if(bidComponent instanceof Article) visitArticle((Article)bidComponent);
else visitCategory((Category)bidComponent);
}
}
#Override
public void visitArticle(Article article){
if(article.getPrice() > highestBid) highestBid = article.getPrice();
}
}
But now I have the same problem again (See comment in visitCategory). Or am I doing this wrong?
You want to use the visitor pattern.
public interface BidComponentVisitor {
void visitArticle(Article article);
void visitCategory(Category category);
}
Then your BidComponent class would have a visit method:
public abstract void visitChildren(BidComponentVisitor visitor);
The Composite and Visitor patterns often work together.
Edit: The key to avoiding instanceof when using the vistor pattern is how you implement the visitChildren method. In Category you would implement it like this:
#Override
public void visitChildren(BidComponentVisitor visitor) {
vistor.visitCategory(this);
for (BidComponent child : children) {
child.visitChidren(visitor);
}
}
Since Article has no children, it's implementation is simpler:
#Override
public void visitChildren(BidComponentVisitor visitor) {
vistor.visitArticle(this);
}
They key is each concrete class in the composite pattern knows it's own type, so it can call the specific visitor method that has a parameter with it's specific type.
One variation is to have enter and exit methods in the visitor for any class with children:
public interface BidComponentVisitor {
void visitArticle(Article article);
void enterCategory(Category category);
void exitCategory(Category category);
}
With the above interface, Category.visitChildren() would look like this:
#Override
public void visitChildren(BidComponentVisitor visitor) {
vistor.enterCategory(this);
for (BidComponent child : children) {
child.visitChidren(visitor);
}
vistor.exitCategory(this);
}
To print the tree, you could do something like this:
public class PrintingVisitor implements BidComponentVisitor {
private int depth = 0;
private void printIndent() {
for (int i = 0; i < depth; i++) {
System.out.print(" ");
}
}
public void visitArticle(Article article) {
printIndent();
System.out.println(article.toString());
}
public void enterCategory(Category category);
printIndent();
System.out.println(category.toString());
depth++;
}
public void exitCategory(Category category) {
depth--;
}
}
The disadvantage of the visitor patter is your visitor class needs to either hardcode every possible subclass, or have a generic visitOther() method.
You are doing the visitor implementation wrong. The different Components handle their own dispatching of elements. They know what type they are so you don't need to do any instanceof checks.
public interface Visitor{
void visit(Article a);
void visit(Category c);
}
abstract class BidComponent{
...
abstract void accept(Visitor v);
}
public class Category{
....
public void accept(Visitor v){
v.visit(this); // visit Category
for(Article a : getArticles()){
v.visit(a); //visit each article
}
}
}
Then a visitor to find the highest bid
public class HigestBidVisitor implements Visitor{
private final double highest;
void visit(Category c){
//no-op don't care
//or we could track which Category we have visited last
//to keep track of highest bid per category etc
}
void visit(Article a){
highest= Math.max(highest, a.getPrice());
}
}
Then to search all:
HigestBidVisitor visitor = new HighestBidVisitor();
BidComponent root = ...
root.accept(visitor);
double highest = visitor.getHighestPrice();
I can't think of any clean solution right now. You might have to update your implementation to either store Article and Category instances separately.
With your current implementation where a List<BidComponent> needs to be traversed and each element needs to be processed based on it's type, this approach can be a bit better:
abstract class BidComponent {
public abstract String process();
}
class Category extends BidComponent {
#Override
public String process() {
return getName();
}
}
class Article extends BidComponent {
#Override
public String process() {
return getName() + " " + getPrice();
}
}
List<BidComponent> list = ..;
for (BidComponent c : list) {
System.out.println(c.process());
}
Another way to decouple the processing logic from the classes/objects is:
Map<Class<?>, Function<BidComponent, String>> processors = new HashMap<>();
processors.put(Category.class, Category::getName());
processors.put(Article.class, a -> a.getName() + " " + a.getPrice());
List<BidComponent> list = ..;
for (BidComponent c : list) {
System.out.println(processors.get(c.getClass()).apply(c));
}
Note that this uses Java 8 lambdas but the same can be implemented with Java 7 or lower by using your own interface (similar to Function) or the ones provided by Guava or Apache Commons.

java events and listeners, bad implementation?

I am currently implementing custom events and listeners according to the code posted below. I have been told that this is a very dirty implementation and that this needs to be changed. However, i am very new to java and android and do not see what is wrong with the current implementation. The way i have it below works and seems to be doing everything i needed it too. I was wondering if some people could please take a look at my code and make some suggestions on what i should change and what i am doing wrong. Taking my example and modifying it so that i can see what your talking about would be greatly appreciated.
Thanks in advance!
/* SmartApp.java */
public class SmartApp extends Activity
{
private ConnectDevice cD = new ConnectDevice();
private DataRobot dR = new DataRobot();
private DataBuilder dB = new DataBuilder();
private DataSender dS = new DataSender();
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.intro);
cD.addDataReceivedListener(new DataReceivedListener() {
#Override
public void dataReceivedReceived(DataReceivedEvent event) {
// TODO Auto-generated method stub
dR.analyzeData(event.getData());
}
});
dR.addDataAnalyzedListener(new DataAnalyzedListener() {
#Override
public void dataAnalyzedReceived(DataAnalyzedEvent event) {
// TODO Auto-generated method stub
dB.submitData(event.getData());
}
});
dB.addDataBuilderListener(new DataBuilderListener() {
#Override
public void dataBuilderReceived(DataBuilderEvent event) {
// TODO Auto-generated method stub
dS.sendData(event.getData());
}
});
}
}
/* ConnectDevice.java
* This class is implementing runnable because i have a thread running that is checking
* the contents of a socket. Irrelevant to events. */
public class ConnectDevice implements Runnable {
private List _listeners = new ArrayList();
private String data;
/* Constructor */
public ConnectDevice() {// does some socket stuff here, irrelevant to the events}
public void run() {// does some socket stuff here, irrelevant to the events}
public synchronized void addDataReceivedListener(DataReceivedListener listener) {
_listeners.add(listener);
}
public synchronized void removeDataReceivedListener(DataReceivedListener listener) {
_listeners.remove(listener);
}
private synchronized void fireDataReceivedEvent(String temp) {
DataReceivedEvent dRE = new DataReceivedEvent(this, temp);
Iterator listeners = _listeners.iterator();
while(listeners.hasNext()) {
((DataReceivedListener)listeners.next()).dataReceivedReceived(dRE);
}
}
public interface DataReceivedListener {
public void dataReceivedReceived(DataReceivedEvent event);
}
}
/* DataRobot.java */
public class DataRobot {
/* This class is for analyzing the data */
private List _listeners = new ArrayList();
private String data;
public boolean analyzeData(String temp) {
/* Analyze the data
* This function analyzes the data, as explained in the OP
* This function fires the analyzed data event when finished
* analyzing the data.
*/
data = temp;
fireDataAnalyzedEvent(data); // this fires the dataanalyzedevent
return true; //for now this will always return true
}
public synchronized void addDataAnalyzedListener(DataAnalyzedListener listener) {
_listeners.add(listener);
}
public synchronized void removeDataAnalyzedListener(DataAnalyzedListener listener) {
_listeners.remove(listener);
}
private synchronized void fireDataAnalyzedEvent(String temp) {
DataAnalyzedEvent dRE = new DataAnalyzedEvent(this, temp);
Iterator listeners = _listeners.iterator();
while(listeners.hasNext()) {
((DataAnalyzedListener)listeners.next()).dataAnalyzedReceived(dRE);
}
}
public interface DataAnalyzedListener {
public void dataAnalyzedReceived(DataAnalyzedEvent event);
}
}
/* DataBuilder.java */
public class DataBuilder {
private List _listeners = new ArrayList();
private String data;
public boolean submitData(String temp) {
/* Builds the data
* This function builds the data, as explained in the OP
* This function fires the databuilder data event when finished
* building the data.
*/
data = temp;
fireDataBuilderEvent(data); //firing the databuilder event when finished
return true;
}
public synchronized void addDataBuilderListener(DataBuilderListener listener) {
_listeners.add(listener);
}
public synchronized void removeDataBuilderListener(DataBuilderListener listener) {
_listeners.remove(listener);
}
private synchronized void fireDataBuilderEvent(String temp) {
DataBuilderEvent dRE = new DataBuilderEvent(this, temp);
Iterator listeners = _listeners.iterator();
while(listeners.hasNext()) {
((DataBuilderListener)listeners.next()).dataBuilderReceived(dRE);
}
}
public interface DataBuilderListener {
public void dataBuilderReceived(DataBuilderEvent event);
}
}
/* DataSender.java */
/* this class has no event, because it is done firing events at this point */
public class DataSender {
private String data;
public boolean sendData(String temp) {
data = temp;
return true;
}
}
Below here are the event objects for each event. I Have each of this defined in a separate file, not sure if that is good procedure or not.
/* DataReceivedEvent.java */
public class DataReceivedEvent extends EventObject{
private String data;
public DataReceivedEvent(Object source, String temp) {
super(source);
// TODO Auto-generated constructor stub
data = temp;
}
public String getData() {
// this function is just an accessor function
return data;
}
}
/* DataAnalyzedEvent.java */
public class DataAnalyzedEvent extends EventObject{
private String data;
public DataAnalyzedEvent(Object source, String temp) {
super(source);
// TODO Auto-generated constructor stub
data = temp;
}
public String getData() {
// this function is just an accessor function
return data;
}
}
/* DataBuilderEvent.java */
public class DataBuilderEvent extends EventObject {
private String data;
public DataBuilderEvent(Object source, String temp) {
super(source);
// TODO Auto-generated constructor stub
data = temp;
}
public String getData() {
// this function is just an accessor function
return data;
}
}
I would not say it is a "very dirty implementation". Using callbacks/observers/listeners is a good practice in my opinion.
When I write Android applications I like to layer it such that the "application" is plain old Java with no Android imports and could theoretically be used in a Swing app, a Java EE-based web site, etc. The "Android" part is strictly user interface.
What I use callbacks for is to allow the Android code to register interest in events that take place in the application. For example, in a Blackjack game, an Activity might call game.getDealer().playHand() to tell the application to perform the dealer hand play logic. As that logic executes in the application, events are fired like cardDrawn(card), cardFlipped(card), handTotalChanged(handTotal), etc. The Android part of the app listens to these and redraws things on the screen accordingly (but it knows nothing about Blackjack).
I actually just have my activities implement interfaces like CardListener, HandListener, etc. so they can receive the event directly (unlike how you do it), but your style isn't necessarily a bad way.
I agree with #SingleShot in theory, for the parts of your Android application that can be Android-agnostic, and so long as the overhead introduced by all the indirection layers does not slow the app down too much. IMHO, in many apps, there is relatively little that fits this description.
In another post, you proposed your above solution for one activity to communicate to another activity. In Android, activities aren't just some Java objects you can toss around willy-nilly. They are managed by the OS and have particular lifecycles. While the observer/observable pattern is quite delightful in some places, it is unsuitable where the observer/observable connection will create garbage collection problems. In particular, one activity cannot, and should not, be trying to hold some sort of listener interface on another activity.
Similarly, a clean observer/observable pattern may break down in the face of databases, threads, services, and other bits of Android reality.
So, in pure Java code, isolated from Android, what you have is probably OK. However, do not go around recommending it as solutions for Android-specific problems unless you know it will work for those Android-specific problems. And, when you start trying to make your code work in an Android app, please do not be shocked if you run into problems trying to make your textbook pattern implementation work within the constraints placed upon Android apps.

How to implement the state design pattern in a JPA domain model

I want to implement the state design pattern in JPA. The way I am currently doing this is outlined in this blog post.
The author uses an enum containing all available state implementations instead of creating abstract class/interface for state abstraction and writing implementation for each state. I find this approach very useful, since enums can be easily serialized in JPA and you can store the current state of your object without additional effort. I also nested the state interface and all state classes into the enum making them private, since they are implementation specific and should not be visible to any client. Here's a code example of the enum:
public enum State {
STATE_A(new StateA()),
STATE_B(new StateB());
private final StateTransition state;
private State(StateTransition state) {
this.state = state;
}
void transitionA(Context ctx) {
state.transitionA(ctx);
}
void transitionB(Context ctx) {
state.transitionB(ctx);
}
private interface StateTransition {
void transitionA(Context ctx);
void transitionB(Context ctx);
}
private static class StateA implements StateTransition {
#Override
public void transitionA(Context ctx) {
// do something
ctx.setState(STATE_B);
}
#Override
public void transitionB(Context ctx) {
// do something
ctx.setState(STATE_A);
}
}
private static class StateB implements StateTransition {
#Override
public void transitionA(Context ctx) {
throw new IllegalStateException("transition not allowed");
}
#Override
public void transitionB(Context ctx) {
// do something
ctx.setState(STATE_A);
}
}
}
I'd like to and share this with you and get your thoughts on it. Do you find this useful? How would you implement the state design pattern in a JPA domain model?
Well it's an old question, but for the sake of those who might search archives - I have used spring state machine with enums (instead Strings).
Regarding handling transitions, there are annotations that allow your functions to be called when transition happens.
1.1.0.RELEASE gives a default mechanism to persist a state by persisting StateMachineContext, and an alternative using persist recipe.
Now refering to JPA - it's possible to have Entity Listener that will initialize statemachine on postload (#Postload), I think it's not good path to go.
As a corollary this AspectJ pattern combined with constant-specific Enum classes is also useful. I am not showing Spring integration here as this focuses only on AspectJ. But I guess we can use Spring with AspectJ too.
One more point is that OO patterns can be powerful for this usecase. I show this pattern only because the question points to the blog post which has a link to a Spring and AspectJ example.
And I also have a need to use good OO patterns with JPA.
public interface StateTransition {
StateTransition activate();
StateTransition deActivate();
}
public enum AStateTransition implements StateTransition{
ACTIVATE(new Activation()),
DEACTIVATE(new DeActivation());
private final StateTransition stateTransition;
private AStateTransition(StateTransition stateTransition) {
this.stateTransition = stateTransition;
}
#Override
public StateTransition activate() {
return stateTransition.activate();
}
#Override
public StateTransition deActivate() {
return stateTransition.deActivate();
}
}
public class Activation implements StateTransition {
#Override
public StateTransition activate() {
return AStateTransition.ACTIVATE;
}
#Override
public StateTransition deActivate() {
return AStateTransition.DEACTIVATE;
}
}
public class DeActivation implements StateTransition {
#Override
public StateTransition deActivate() {
return AStateTransition.DEACTIVATE;
}
#Override
public StateTransition activate() {
return AStateTransition.ACTIVATE;
}
}
#Aspect()
public class StateChangeAspect {
//Could be more generic so that all implemented methods
//are covered
#Pointcut("execution(* AStateTransition.activate()) && target(stateTransition) && if()")
public static boolean stateChangePointcut( AStateTransition stateTransition ){
return AStateTransition.ACTIVATE == stateTransition;
}
#Before("stateChangePointcut(stateTransition)")
public void test1( AStateTransition stateTransition ) {
System.out.println( " aspect " );
}
#Before("stateChangePointcut(stateTransition)")
public void test1(JoinPoint joinPoint, AStateTransition stateTransition) {
System.out.println(joinPoint + " -> " + stateTransition);
}
}
Test code :
System.out.println(AStateTransition.ACTIVATE.activate());
System.out.println(AStateTransition.DEACTIVATE.deActivate());

Categories

Resources