I am dealing with the text extraction from pdf. To this end I wrote my own text extraction
strategy. I have one dynamic class and within this class i invoke text extraction strategy.
However, when i introduce some parameters to my dynamic class i cannot use them within strategy class. To be clear i am adding my code template below.
My question is briefly, is it possible to invoke parameter unq showing up in "get_intro" class, from renderText? Or other way around, can a variable or parameter created inside the "renderText" class be invoked in the "get_intro"?
public class trial {
public trial(){}
public Boolean get_intro(String pdf, String unq){
try { ....
for (int j = 1; j <= 3; j++) {
out.println(PdfTextExtractor.getTextFromPage(reader, j, semTextExtractionStrategy));
}
...} catch (Exception e) {
e.printStackTrace();
}
semTextExtractionStrategy part:
public class SemTextExtractionStrategy implements TextExtractionStrategy {
#Override
public void beginTextBlock() {
}
#Override
public void renderText(TextRenderInfo renderInfo) {
text = renderInfo.getText();...}
#Override
public void endTextBlock() {
}
#Override
public void renderImage(ImageRenderInfo renderInfo) {
}
#Override
public String getResultantText() {
//return text;
return main;
}
}
One could consider the following problematic solution:
public abstract class DefaultTextExtractionStrategy<D>
implements TextExtractionStrategy {
protected D documentInfo;
public final void setDocumentInfo(D documentInfo) {
this.documentInfo = documentInfo;
}
public class SemTextExtractionStrategy extends DefaultTextExtractionStrategy<SemDoc> {
#Override
public void beginTextBlock() {
documentInfo ...
}
public class SemDoc {
public String unq:
}
And in get_intro:
SemDoc semDoc = new SemDoc();
semDoc.unq = unq;
semTextExtractionStrategy.setDocumentInfo(semDoc);
out.println(PdfTextExtractor.getTextFromPage(reader, j, semTextExtractionStrategy));
The problem is that you want to pass some context class on calling the entry function (like ActionEvent or such). But by its name a strategy class probably is a stateless singleton. In the above solution you would need to instantiate from a Class<TextExctractionStrategy>, Class<D> a new strategy instance. Or like in the MouseAdapter class pass the same event class parameter to every method.
This smells of "over-designing" or a skewed pattern application.
As we are on the brink of Java 8 lambdas, you might even consider a "backport" of a design with lambdas.
But for the moment I would go with adding a generic D textExtractionContext to every called function, if the API is not for an external library.
Related
I am designing a validation module. It has 100 error codes(i.e. errcd_01, errcd_02,..,errcd_100) to be validated. In input I am getting a specific error code(i.e. errcd_01) out of above 100.
Module should perform validation for that specific error code.
I am using factory pattern.
/* Interface */
public interface validateErrCd {
void check_errcd();
}
/* Concrete classes implementing the same interface */
public class validateErrCd_01 implements validateErrCd {
#Override
public void check_errcd() {
//business logic related to errcd_01
}
}
public class validateErrCd_02 implements validateErrCd {
#Override
public void check_errcd() {
//business logic related to errcd_02
}
}
.
.
.
public class validateErrCd_100 implements validateErrCd {
#Override
public void check_errcd() {
//business logic related to errcd_100
}
}
/* Factory */
public class ErrorValidationFactory {
//use check_errcd method to get object of type shape
public validateErrCd getValidation(String errorCode){
if(errorCode == null){
return null;
}
if(errorCode.equalsIgnoreCase("errcd_01")){
return new validateErrCd_01();
} else if(errorCode.equalsIgnoreCase("errcd_02")){
return new validateErrCd_02();
} ..
.......
else if(errorCode.equalsIgnoreCase("errcd_100")){
return new validateErrCd_100();
}
else {
return null;
}
}
}
/* I am using the Factory to get object of concrete class by passing an specific error code to be validated (i.e. "errcd_01"). */
public class FactoryPatternDemo {
public static void main(String[] args) {
ErrorValidationFactory errorFactory = new ErrorValidationFactory();
//get an object of validateErrCd_01 and call its check_errcd method.
validateErrCd errcd01 = errorFactory.getValidation("errcd_01");
//call check_errcd method of validateErrCd_01
errcd01.check_errcd();
}
}
Now due to multiple if/else inside Factory class ErrorValidationFactory, I am getting couple of CI/CD errors while performing mvn clean install.
e.g. [MethodLength] - checkstyle, Rule:CyclomaticComplexity - PMD.
So is there a way I can replace if/else, switch case kind of decision making inside factory which does not trigger above CI/CD errors in Java?
Note : If possible I would like to avoid reflection
You could use a Map:
public class ErrorValidationFactory {
private Map<String,Supplier<validateErrCd>> creators=new HashMap<>();
public ErrorValidationFactory(){
creators.put("errcd_100",validateErrCd_100::new);
//Same for others
}
//use check_errcd method to get object of type shape
public validateErrCd getValidation(String errorCode){
if(errorCode == null){
return null;
}
return creators.getOrDefault(errorCode,()->null);
}
}
Supplier is a functional interface that contains a method returning an object. SomeClass::new or ()->new SomeClass() means that the constructor of the class will be used for that.
This allows to to create the instances later.
If you want to create the Map only once, you can make it static and populate it in a static initializer.
However, if you really want to dynamically get the constructors, you would need to use reflection.
Consider a method
public void doSomething(String actionID){
switch (actionID){
case "dance":
System.out.print("I'm dancing");
break;
case "sleep":
System.out.print("I'm sleeping");
break;
default:
System.out.print("I've no idea what I'm doing");
}
The implementation of the method depends on the value of the parameter. Is there a more elegant way to do this, or a different design pattern to replicate the behaviour?
If the caller decides what logic is executed by passing different strings, then why not just have them call different methods:
public void doSomething(String actionID) {...}
...
doSomething("dance");
doSomething("sleep");
VS.:
public void dance() {...}
public void sleep() {...}
...
dance();
sleep();
It seems like you're unnecessarily funnelling all the calls into doSomething
But the strings might not always be literals. What if you're taking them from the console?
You could provide static mappings from the strings to the corresponding functions:
class MyClass {
private static final Map<String, Consumer<MyClass>> map = new HashMap<>();
static {
map.put("sleep", MyClass::sleep);
map.put("dance", MyClass::dance);
}
public void doSomething(String actionID) {
map.getOrDefault(actionID, MyClass::doNothing).accept(this);
}
public void dance() {
System.out.print("I'm dancing");
}
public void sleep() {
System.out.print("I'm sleeping");
}
private void doNothing() {
System.out.println("I've no idea what I'm doing");
}
}
This makes scenarios where you have a lot of switch cases a lot cleaner.
Introduce an interface, e.g.
public interface HumanState {
public void tellMeWhatYouAreDoing();
}
encapsulate the logic in different implementations
public class DancingState implements HumanState {
#Override
public void tellMeWhatYouAreDoing() {
System.out.println("I'm dancing");
}
}
public class SleepingState implements HumanState {
#Override
public void tellMeWhatYouAreDoing() {
System.out.println("I'm sleeping");
}
}
public class UnknownState implements HumanState {
#Override
public void tellMeWhatYouAreDoing() {
System.out.println("I've no idea what I'm doing");
}
}
and use a map. E.g.
public class HumanStateExample {
public static void main(String[] args) {
HumanStateExample humanStateExample = new HumanStateExample();
humanStateExample.doSomething("dance");
humanStateExample.doSomething("sleep");
humanStateExample.doSomething("unknown");
}
private final HashMap<String, HumanState> humanStateMap;
public HumanStateExample(){
humanStateMap = new HashMap<String, HumanState>();
humanStateMap.put("dance", new DancingState());
humanStateMap.put("sleep", new SleepingState());
}
public void doSomething(String action) {
HumanState humanState = humanStateMap.get(action);
if(humanState == null){
humanState = new UnknownState();
}
humanState.tellMeWhatYouAreDoing();
}
}
I'm not sure how the pattern is called, but it is very useful if you need to delegate the method call based on more than one parameter:
Create a lot of handlers where each one knows when it is responsible for handling a call. Then just loop through them and invoke the first one matching the parameter.
edit: I renamed the class from FancyParameterActionFactory to FancyParameterActionUtility: it is not a factory, the name was misleading
//Your method, but this time with a complex object, not with a simple string.
public void doSomething(FancyParameterObject fpo){
FancyParameterActionUtility.invokeOn(fpo);
}
//The utility which can handle the complex object and decides what to do.
public class FancyParameterActionUtility{
public Interface FPAHandler{
void invoke(FancyParameterObject fpo);
boolean handles(FancyParameterObject fpo);
}
//Omitted: Different implementations of FPAHandler
public static List<FPAHandler> handlers = new LinkedList<>();
static{
handlers.add(new DanceHandler());
handlers.add(new SleepHandler());
//Omitted: Different implementations of FPAHandler
}
public static void invokeOn(FancyParameterObject fpo){
for(FPAHandler handler:handlers){
if (handler.handles(fpo)){
handler.invoke(fpo);
return;
}
}
//Default-Behavior
}
}
Here is a simple implementation of the command pattern based your sample problem. I define a general AbstractCommand abstract class which contains two methods. The first method, createCommand(), instantiates a command class based on an input string name. This is how you can delegate your string input to create the right type of command. The second method is doAction(), and this is left undefined, to be implemented later on by specific concrete command classes.
public abstract class AbstractCommand {
public static AbstractCommand createCommand(String name) {
try {
String clsName = name + "Command";
Class<?> cls = Class.forName(clsName);
AbstractCommand command = (AbstractCommand) cls.newInstance();
return command;
}
catch (Exception e) {
System.out.println("Something went wrong.");
}
}
public abstract void doAction();
}
public class DanceCommand extends AbstractCommand {
public void doAction() {
System.out.println("I'm dancing");
}
}
public class TestCommandPattern {
public void doSomething(String actionID) {
AbstractCommand cmd = AbstractCommand.createCommand(actionID);
cmd.doAction();
}
public static void main(String[] args) {
TestCommandPattern test = new TestCommandPattern();
test.doSomething("Dance"); // should print "I'm dancing"
}
}
Now that this framework has been setup, you could easily add other commands for the various types of actions in your original problem. For example, you could create a SleepCommand class which would output I'm sleeping, or do whatever action you wish.
I have to write a test for the login dialog that shows up on my website, but there are two, and only two access points for this login dialog. Ideally, my page objects should reflect the restricted access to this login dialog.
When you clickLogin on the Header, a LoginDialog pops up
When you postComment on an Article, and you aren't logged in (and we'll assume you aren't for simplicity), a LoginDialog pops up.
Here's what it looks like in code:
new LoginDialog().login(); // shouldn't be allowed
new Header().clickLogin().login(); // should be allowed
new Article().postComment().login() // should be allowed
I came up with a method for getting around this. LoginDialog only has two constructors, which both take in an object that can only be constructed in either Header or Article.
public class LoginDialogTest extends WebTest {
#Test
public void testLoginDialogFromHeader {
new HomePage().loadPage();
new Header().clickLogin().login();
verifyLoggedIn();
}
#Test
public void testLoginDialogFromArticleComment {
new ArticlePage(42).loadPage(); // Load an article with id=42
new Article().postComment().login();
verifyLoggedIn();
}
}
public class LoginDialog {
public LoginDialog(Article.CommentButton commentButton) {
}
public LoginDialog(Header.LoginButton loginButton) {
}
public void login() {
}
}
public class Article {
public class CommentButton {
private CommentButton() {
}
public LoginDialog click() {
return new LoginDialog(this);
}
}
public LoginDialog postComment() {
return new CommentButton().click();
}
}
public class Header {
public class LoginButton {
public LoginDialog click() {
return new LoginDialog(this);
}
}
public LoginDialog clickLogin() {
return new LoginButton().click();
}
}
My question is whether or not this is an existing pattern, and if it is, what is its name? If it isn't, what would be a good name for it?
I think this would be a foolproof way of making sure only Header or Article could create a LoginDialog:
public class LoginDialog {
private LoginDialog() {
... code to construct
}
public interface Constructor {
LoginDialog newLoginDialog();
}
private static class ConstructorImpl implements Constructor {
public LoginDialog newLoginDialog() {
return new LoginDialog();
}
}
private static ConstructorImpl constructor;
static {
constructor = new ConstructorImpl();
Header.provideLoginDialogConstructor(constructor);
Article.provideLoginDialogConstructor(constructor);
}
}
and in Header and Article, provide a public provideLoginDialogConstructor method:
private static LoginDialog.Constructor constructor;
public static void provideLoginDialogConstructor(LoginDialog.Constructor constructor) {
Header.constructor = constructor; // or Article.constructor
}
and when those classes need to construct a LoginDialog:
if (!loggedIn()) {
return constructor.newLoginDialog();
} else {
return null;
}
Since the LoginDialog class decides what classes get to have its private object to construct a LoginDialog, there should be no way for another class to obtain the ability to construct one using normal means [there might be tricky ways using reflection].
Note: I haven't tested this.
I have two classes:
DocumentState and ElectronicDocumentState.
They look like this:
public class DocumentState extends LabeledEnum {
public static final DocumentState CREATED = new DocumentState("created");
// ..... - 15 other statuses
}
ElectronicDocumentState also extends LabeledEnum and has its own statuses, some are common like created, other are unique.
Then I have plenty of methods in code that take DocumentState as a parameter or are returning DocumentState as result. Now they should work also with ElectronicDocumentState.
Also I have plenty places that do:
if (DocumentSate.CREATED.equals(doc.getState()) || DocumentState.DELETED.equals(doc.getState())) {
//do something with document
}
I want to avoid 'if' and avoid creating new methods for ElectronicDocumentState as more state can appear in future.
How would you do that ?
So using the below example, how would you refactor it so it could work with DocumentState and ElectronicDocumentState? I have plenty of such methods that now should also work with ElectronicDocumentState. Someone asks us to mix electronicDocuments with documents in business logic:
private DocumentState getDocumentStateForDetails(Document doc, DocumentState sourceState) {
if (DocumentState.CREATED.equals(doc.getDocumentState())) {
if (sourceState.equals(DocumentState.CREATED)) {
return DocumentState.CREATED;
} else {
return DocumentState.BLOCKED;
}
} else {
return sourceState.getDocumentState();
}
}
If you are worrying about further extension of your state model, I'd suggest you to think about using inheritance instead of if/switch and instanceof by splitting the document class to Value and State, for instance. If you have the same set of available actions for any state of document, just use classical State pattern, otherwise, each State may have its own set of available actions:
public class Document {
public static CreatedDocument<Document> create(String author) {
return new CreatedDocument<>(new Document(author));
}
private String author;
//...
private Document(String author) {
//...
}
}
public class ElectronicDocument extends Document {
public static CreatedElectronicDocument create(String author, String url) {
return new CreatedElectronicDocument(author, url);
}
private String url;
//...
public ElectronicDocument(String author, String url) {
//...
}
//...
}
public interface DocumentState<T extends Document> {
T getDocument();
char getCode(); // might be needed for something like logging?
}
public abstract class AbstractDocumentState<T extends Document> implements DocumentState<T> {
protected final T document;
protected AbstractDocumentState(T document) {
this.document = document;
}
#Override
public T getDocument() {
return document;
}
}
public class CreatedDocument<T extends Document> extends AbstractDocumentState<T> {
public CreatedDocument(T document) {
super(document);
}
#Override
public char getCode() {
return 'C';
}
public DocumentState<T> delete() {
return new DeletedDocument<>(document);
}
}
public class CreatedElectronicDocument extends CreatedDocument<ElectronicDocument> {
public CreatedElectronicDocument(String author, String url) {
super(new ElectronicDocument(author, url));
}
public DownloadElectronicDocument download() {
return new DownloadElectronicDocument(document);
}
}
public class DownloadElectronicDocument extends AbstractDocumentState<ElectronicDocument> {
public DownloadElectronicDocument(ElectronicDocument document) {
super(document);
// DO DOWNLOAD HERE
}
#Override
public char getCode() {
return 'L';
}
public DocumentState<ElectronicDocument> delete() {
return new DeletedDocument<>(document);
}
}
public class DeletedDocument<T extends Document> extends AbstractDocumentState<T> {
public DeletedDocument(T document) {
super(document);
// DO DELETE HERE
}
#Override
public char getCode() {
return 'D';
}
}
Not sure you need getCode() now, when you use inheritance. BTW, switch works faster than a set of if/else if.
If you'd like to stay with your enum classes, why wouldn't to extract common states to a super class?
public class CommonDocumentState extends LabeledEnum {
public static final CommonDocumentState CREATED = new CommonDocumentState ("created");
..... - n other statuses
}
public class DocumentState extends CommonDocumentState {
..... - m other statuses
}
public class ElectronicDocumentState extends CommonDocumentState {
..... - k other statuses
}
That's the only way to have such generic rules like
if (DocumentSate.CREATED.equals(doc.getState()) || DocumentState.DELETED.equals(doc.getState())) {
//do something with document
}
be working for both DocumentState and ElectronicDocumentState.
There are not enough information about your domain to provide a final answer, but I have some suggestions:
it seems that both DocumentState and ElectronicDocumentState inherit from LabeledEnum; if you want to manage both of them in your methods you can make ElectronicDocumentState inherit from DocumentState of it's feasibile merge the two classes. This will allow to pass ElectronicDocumentState or DocumentState in your methods and perhaps solve your second question.
if you want to avoid the if you can build a list of allowed method and check against the list, something like:
L
public class YourClass {
List<DocumentSate> allowedStates=//init here or in constructor
....
public void yourMethod(....) {
if (allowedStates.contains(doc.getState())) {
//do something
}
}
allowedStates may be factored out in separate class if it is a common case. If you find the refactoring feasible, may be you can check if you are dealing with a finite state machine and implement it (with the help of some exisiting libraries).
I'm working on a game engine, and the last question I had regarding this was what good way I can use to make "observers" or listeners. A user suggested that I should use Java's EventObject class to inherit from and make a Listener interface. However, this didn't provide me with good flexibility.
Here is the Handler annotation to state that a method is an event handler in a listener:
#Retention(RetentionPolicy.CLASS)
#Target(ElementType.METHOD)
public #interface Handler {}
Here is the base class for Event, which is basically the same as EventObject (but I'll add abstract methods sooner or later):
public abstract class Event {
private Object source;
public Event(Object source) {
this.source = source;
}
public Object getSource() {
return source;
}
}
Here is the Listener class, which is empty:
public interface Listener {}
Here is the ListenerHandler class, used to handle all listeners. You register and unregister them here. I'll edit the register/unregister methods later for a better use:
public class ListenerHandler {
private ArrayList<Listener> listeners;
public ListenerHandler() {
this.listeners = new ArrayList<Listener>();
}
public void registerListener(Listener l) {
listeners.add(l);
}
public void unregisterListener(Listener l) {
listeners.remove(l);
}
public void onEvent(Event event) {
for(Listener l : listeners) {
Class<?> c = l.getClass();
Method[] methods = c.getDeclaredMethods();
for(Method m : methods) {
if(m.isAccessible()) {
if(m.isAnnotationPresent(Handler.class)) {
Class<?>[] params = m.getParameterTypes();
if(params.length > 1) {
continue;
}
Class<?> par = params[0];
if(par.getSuperclass().equals(Event.class)) {
try {
m.invoke(this, event);
}catch(IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
}
}
}
}
From what I heard, it's a use of a lot of memory in order to get all methods of a class. I'm not going to assume this is the case, but I'm sure there is a better way as this will be a game engine with many components and such.
I'd like to know the best way to implement this, or if I'm doing it right. I'd also like to know if anyone can help me improve this in any way without hogging memory usage by the game (as of now it's not a big deal -- the "game engine" is not even close to rendering anything yet)
I tried to keep it a very simple example and will comment with different ideas to it:
First meet the Achievement class:
import java.util.Observable;
public class Achievement extends Observable {
public static class AchievementDetails {}
public Achievement() {
addObserver(EventsListener.getInstance());
}
public void achievementReached() {
AchievementDetails achievemetDetails = null;
setChanged();
notifyObservers(achievemetDetails);
}
}
And then the events listener class:
import com.test.Achievement.AchievementDetails;
public class EventsListener implements Observer {
private static EventsListener instance = new EventsListener();
public static EventsListener getInstance() {
return instance;
}
#Override
public void update(Observable o, Object arg) {
if(o instanceof Achievement) {
AchievementDetails achievemetDetails = (AchievementDetails) arg;
//do some logic here
}
}
}
The only one thing that is missing is to create an instance of your achievement (which register the EventsListener to itself) and handle the life cycle of it.