#interface chaining readability

1 messages Β· Page 1 of 1 (latest)

regal quiver
#

When u make an interface heirarchy do u include the methods inside the child interface for readability purposes or not?

public interface Validator {
    boolean isValid(String formula);
    boolean isValid(List<Token> formula);
}

public interface Tokenizer {
    List<Token> convert(String formula);
}

public interface Solver {
    String solve(List<Token> formula);
}

do u do:

public interface Calculation extends Solver, Tokenizer, Validator {

    @Override
    boolean isValid(String formula);

    @Override
    boolean isValid(List<Token> formula);

    @Override
    List<Token> convert(String formula);

    @Override
    String solve(List<Token> formula);

    String calculate(String formula);
}

or

public interface Calculation extends Solver, Tokenizer, Validator {
    String calculate(String formula);
}

and just leave it with 'hidden' functions that ppl will probably not realise are there??

ripe lintelBOT
#

βŒ› This post has been reserved for your question.

Hey @regal quiver! Please use /close or the Close Post button above when your problem is solved. Please remember to follow the help guidelines. This post will be automatically closed after 300 minutes of inactivity.

TIP: Narrow down your issue to simple and precise questions to maximize the chance that others will reply in here.

small kraken
#

I don't. I know java does it in the collection framework, but that's to update the docs for the sub interfaces more than anything else

ornate forge
#

Hm, if the signature remains the same I would use the latter one. But if you violate the liskov-substitution-principle: the first one.

regal quiver
ornate forge
#

If I look at Calculation I would NOT expect the methods to be overwritten because it will violate DRY.

#

It would be a surprise to me. (my personal opinion).

small kraken
#

Yeah, that's what I think

regal quiver
#

its an interface, not a class ...... there is no implementation

regardless of if u write implements Calculator or implements Calculator, Solver u will only have a single method available to call

#

its an interface, not a class ...... there is no implementation
which is the only reason why its legal to extend multiple interfaces but illegal to extend multiple classes

ornate forge
#

Brogrel, nice work of interface-segregation-principle, though!

regal quiver
#

i get so upset when ppl come here to ask for help with their javaFX controller
and all the program logic is inside it >.<

so i'm updating my old project from when i messed with javaFX (and adding a bit of extra functionality because why just straight update) to include more modern java

#

hopefully having an actual example program to show them will help them understand about keeping the UI seperate from the logic

#

quite proud of my obnoxious colour scheme tooo

ornate forge
#

There is a second reason I slightly mentioned. The signature can change. In example you could overwrite in the Calculation-interface using more concrete classes like AbstractList<Token> convert(String formula); (notice the Abstract that the Tokenizer-interface does not have)

#

Same belongs to parameters and exceptions.

regal quiver
#

oh i do need to add generics soon
its just int calcs atm
then i include double and float etc it will need generics

and working out how to get sealed and switch-completeness out of that without needing the calculator to have noOP calls for the inttokens when its processing doubles is half of the challenge
(should always learn something new on a new project)

small kraken
#

For a calculator I turn everything into doubles

#

if you want int support you have to design casting rules basically πŸ™‚

#

But you can def separate them out

#

It's not that hard

#

But you don't need generics, at all πŸ˜„

regal quiver
ornate forge
regal quiver
#

have to use a box anyway for the tokenizing
unfortunately u cant make Number an element of the (blank) Token interface so u can use it in List<Token> so i just have public record IntToken(int value) implements Token {} atm ..... it rly doesnt need any functionality

small kraken
#

tokens for me are always strings

#

how they're interpreted is the parsers job, not the tokenizers πŸ™‚

#

(for me at least)

#

And I wrap it in ```java
import java.math.BigInteger;
import java.util.Objects;

final class StringNumber extends Number {

private final String value;

StringNumber(String value) {
    this.value = Objects.requireNonNull(value, "value");
}

@Override
public int intValue() {
    try {
        return Integer.parseInt(value);
    } catch (NumberFormatException e) {
        return (int) longValue();
    }
}

@Override
public long longValue() {
    try {
        return Long.parseLong(value);
    } catch (NumberFormatException e) {
        return new BigInteger(value).longValue();
    }
}

@Override
public float floatValue() {
    return Float.parseFloat(value);
}

@Override
public double doubleValue() {
    return Double.parseDouble(value);
}

@Override
public boolean equals(Object obj) {
    return this == obj || obj instanceof StringNumber
        && value.equals(((StringNumber) obj).value);
}

@Override
public int hashCode() {
    return value.hashCode();
}

@Override
public String toString() {
    return value;
}

}

regal quiver
#

no null check on obj?

    @Override
    public boolean equals(Object obj) {
        return this == obj || obj instanceof StringNumber
            && value.equals(((StringNumber) obj).value);
    }
small kraken
#

instanceof is a null check

regal quiver
#

oh damn, thats a cute shortcut

small kraken
#

nulls are untyped in Java, so a null instanceofs to nothing at all

#

(except maybe object?)

#

Nowadays I don't even write the this == obj anymore

regal quiver
#

well, u can include pattern matching instead of the cast now?

small kraken
#

yeah, that

#

The french Java guy did a video on it with benchmarks, it's not even faster or anything (adding the == check)

#

and less code is better code

regal quiver
#

yeah, more if-forks for the jit to worry about

ornate forge
#

StringNumber("NaN") πŸ˜„

small kraken
#

That would technically work

#

Just don't call longValue on it

ornate forge
#

And "Infinity" πŸ˜„

small kraken
#

same

ornate forge
#

And "-Infinity" πŸ˜„

small kraken
#

This class isn't public

regal quiver
#

damn

small kraken
#

All you see is a number that prints its own value

#

I used it for Json and some custom format from a video game

ornate forge
#

Try "0080"

small kraken
#

json doesn't allow leading 0

#

Json only has numbers that are parseable by default Java methods

#

If you need extra support, add extra code

#

(same with that game btw)

regal quiver
# small kraken tokens for me are always strings

i tokenise into objects because without that u have invalid tokens (because u cant test if all strings are valid without converting them)

.....plus it means my parser can use == instead of equals() because the operators are all enums so no bonus instances to deal with

regal quiver
small kraken
#

That's the lexer's job in the first place πŸ™‚

small kraken
regal quiver
# small kraken That's the lexer's job in the first place πŸ™‚

yeah, i'm skipping a lexer
i started by writing a lexer to turn the tokens into an expression tree
so i could parse that and solve based on correct order of operations

but while writing it, i realised i can just solve in place with a stack by making a tiny modification to the shunt yard algo
......so i'm just skipping the lexing and added a validator instead so the parser doesnt have to double check the tokens for understandability

small kraken
#

the lexer gives you tokens, the parser turns into an AST

#

But I understand

#

so I use that peekingreader I showed you, that's used in a lexer to read tokens, that passes them onto a parser to turn them into possible StringNumber instances if I need them

#

The full hierarchy is just more clear to me, but sometimes you don't need it

regal quiver
#

??
tokenising is breaking a string into blocks (tokens), lexing is giving those blocks meaning (comes from lexical analysis), and parsing is putting that meaning into a greater context to make the tokens as a whole meaningful
??
r u sure lexing comes before tokenising?

small kraken
#

well, lexing/tokenizing to me are the same thing

#

splitting into tokens and giving them meaning

#

there might be a slight semantic difference between them

#

yeah so I write the lexer separately, tokenizer is part of the lexer

regal quiver
#

....it might be more accurate to call mine a lexer not a tokeniser.....

small kraken
#

which I'm glad that you actually pointed that out, because I've called it a tokenizer sometimes, othertimes a lexer

#

Lexer it is πŸ˜„

regal quiver
#

but Token / Tokens is usable for the seperate instances
if its a lexer then whats the small bits? Lexes?

small kraken
#

I call them Tokens

#

but that name is eh

#

Lexical tokenization is conversion of a text into (semantically or syntactically) meaningful lexical tokens belonging to categories defined by a "lexer" program. In case of a natural language, those categories include nouns, verbs, adjectives, punctuations etc. In case of a programming language, the categories include identifiers, operators, gro...

#

There's also scanners and lexemes