This is kind of a design-patterns question in Java.
I am designing a java .jar file to act as a frameworks for managing and processing a certain form of data. I want the end user to be able to dictate the "plumbing" configuration, within certain constraints, in a certain way. The pieces are producers and/or consumers, and I know how to implement them, but the connections are confusing to me... here's a nonsense example that sort of parallels my application.
Suppose I have implemented these elements:
AppleTree => produces apples
ApplePieMaker => consumes apples,
produces apple pies
ApplePress =>
consumes apples, produces apple cider
AppleSave => stores apples,
apple pies, or apple cider into a
file
AppleLoad => "reconstitutes" apples, apple pies, or apple cider from a file that was produced by AppleSave
ApplePieMonitor => displays apple pies on the screen in a GUI format, as they are produced
Now I want the user to be able to specify things like:
AppleTree | ApplePress | AppleSave cider1.sav (produce apples, make them into cider, save them to a file)
AppleTree | AppleSave apple1.sav (produce apples, save them to a file)
AppleLoad apple1.sav | ApplePieMaker | ApplePieMonitor (take saved apples, make them into pies, display the results on the screen in a GUI)
(not sure how to illustrate this, but might be specified as follows)
AppleTree tree1, ApplePieMaker piemaker1 < tree1, AppleSave apples.sav < tree1, AppleSave #select(*.sav) < piemaker1, ApplePress press1 < tree1, AppleSave cider.sav < press1, ApplePieMonitor piemon1 < piemaker1
(produce apples, make them into pies and cider, save the apples, pies and cider to separate files, with the pies going to a file selected by the user at runtime and the others going to predetermine files, and also display the pies on the screen in a GUI)
So I have a rough idea of how to architect a configuration file: namely to structure the thing into elements that have at most 1 input and at most 1 output, and then for each instantiated element, name it, and if it has an input, specify the name of the element providing the input.
What I'm unclear is how to go about coupling the elements of the program when they run. Maybe the way to go is to have a number of interfaces, like AppleConsumer, ApplePieConsumer, etc. so an ApplePieMaker would implement the AppleConsumer interface (incl. method consumeApple()), and an AppleTree would implement an AppleProducer interface which can register consumers at startup, so that every time the AppleTree produces an apple, it has a list of its consumers and calls consumeApple() on each of them, which then does the right thing without the AppleTree having to know what they are doing with the apples....
Any suggestions? Does this sort of thing have a name? I'm not really that experienced in design patterns.
edit: my end users don't know and don't care about Java. They just need to be able to set up a config file (which I'm trying to make as simple as possible so I can give them some good examples) and run my program which will read the config file, construct the elements, hook them together, and go. All the elements are under my control, I don't need to support plugins, so I don't have to be super-general.
I had that problem a while ago, and it was a bit hard to specify cleanly in Java, since my input and output could be plural. However, when you are sure to have a single input and output (since a file is a specific kind of output, right?), you could try to use checked generics.
A processing step implementation (I will call that a filter) has two checked type arguments: input and output (lets for instance suppose they all extend a common interface, and for every new type you inject in the system, you will subclass that interface).
public interface Filter<Input extends Type, Output extends Type> {
public Class<Input> getInputType();
public Class<Output> getOutputType();
public void process(Input in, Output out);
}
A filter chain is then just an array of (compatible) Filters. By compatible, I intend that for each filter, its Output is the same type as its follower Input, the first filter has an Input that match your overall input type, and the last filter has an Output that matches the expected result type. This is easy to validate, in practice, since we are using checked generics.
A filter chain is thus an other (compound) filter. The compatibility of compounded filters should be checked in the constructor, and the array of compounds final. There is no accurate way to express the "chaining" property (compatibility) of the arguments of that constructors with generics, so you are going to have to do that with bare types, which is a bit unclean.
An other way to do it that gets around this limitation, at the cost of more cumbersome writing, is to change the definition of a filter like this:
public interface Filter<Input extends Type, Output extends Type> {
public Class<Input> getInputType();
public Class<Output> getOutputType();
public Output out process(Input in);
}
We will then have to define a compound filter as an imbrication of filter pairs, thus defined:
public class CompoundFilter<Input extends Type, Output extends Type>
implements Filter<Input extends Type, Output extends Type> {
private final Filter<Input extends Type, ? extends Type> l;
private final Filter<Input extends Type, ? extends Type> r;
public <Median extends Type> CompoundFilter(
Filter<Input, Median> r,
Filter<Median, Output> l
) {
this.l = l;
this.r = r;
}
#SuppressWarnings("unchecked")
public Output out process(Input in) {
// Compute l(r(in)) = (l o r) (in)
return ((Output<Input,Type>) l).process(r.process(in));
}
}
Thus, composing filters is just a matter of writing:
Filter<A,B> f1 = new FilterImpl<A,B>;;
Filter<B,C> f2 = new FilterImpl<B,C>;
// this is mathematically f2 o f1
Filter<A,C> comp = new CompoundFilter<A,C>(f1,f2);
I could not help it, I have to workout something for this.
So here it is.
You already have the idea about the apple producer/consumer so this is how I would do it.
Create three interfaces and implement as follows:
Product - Either Apple, AppleCider, ApplePie,
Producer - AppleTree, ApplePress, ApplePieMaker, AppleLoad,
Consumer - ApplePress ( consumes Apples ), ApplePieMaker ( consumes Apples ) , AppleMonitor, AppleSave.
The idea is to have a generic Product, produced by generic Producers and consumed by generic Consumers.
Once you have that, you can create the configuration file pretty much the way you describe it, and parse it to create a new instance for each element.
element1 | element2 | element3 <parameters> | element 4
In a map you create the element name and map it to the class that will create the new instance.
Let's say
map.put( "AppleTree", YouAppleTreeClass.class );
So each time you read an element in the configuration you create the instance:
for( String item: line ) {
Object o = map.get( item ).newInstance();
}
Finally you have to validate the structure of your configuration, but basically it could be like this:
The first element should be a producer
The last should be a consumer
Any intermediate should be producer-consumers
You can parse arguments needed ( file to save data for instance )
Once you have all your objects created and chained, you start producing.
There are some thing you have to workout but they're pretty easy:
Argument passing ( the file where they will be saved/loaded from)
Object re-use in different configurations ( use the same AppleTree always )
Final notes: The following code, is just an scratch, you may really consider a dependency injector to do the job, but of course it will take you a little while to learn it.
The configuration parsing should be made by hand, for the format you're using will be unique for the end-user and should be pretty simple. Still you can deliver as much complexity you want inside your jar ( using any number of frameworks you need ).
You can also take a look to the following design patterns:
Composite
Observer
Interpreter
The implementation below, is a kind of monster the these three ( I didn't compile it, just throw some code to show how the idea would look like )
I hope this helps.
/**
* Anything. An apple, cider, pie, whatever.
*/
interface Product{}
// The kinds of products.
class Apple implements Product{}
class ApplePies implements Product{}
class AppleCider implements Product{}
/**
* This indicates the class will do something.
**/
interface Producer {
// adds a consumer to the list.
public void addConsumer( Consumer c );
// removes the consumer from the list.
public void removeConsumer( Consumer c );
// let know eveytone a product has been created.
public void notifyProductCreation( Product someProduct );
// You're producer? Produce then...
public void startProduction();
}
// To avoid copy/paste all around
class AbstractProducer implements Producer {
private List<Consumer> consumers = new ArrayList<Consumer>();
// adds a consumer to the list.
public void addConsumer( Consumer c ) {
consumers.add( c );
}
// removes the consumer from the list.
public void removeConsumer( Consumer c ) {
consumers.remove( c );
}
public void notifyProductCreation( Product someProduct ) {
for( Consumer c : list ) {
c.productCreated( someProduct );
}
}
}
interface Consumer {
// Callback to know a product was created
public void productCreated( Product p );
}
class AppleTree extends AbstractProducer {
public void startProduction() {
// do something with earh, sun, water..
// and from time to time:
Product ofThisNewApple = new Apple();
notifyProductCreation( ofThisNewApple );
}
}
class ApplePieMaker extends AbstractProducer implements Consumer {
// Ok, a product was created, but
// is it the product I care?
// check first and consume after.
public void productCreated( Product p ){
// Is this the kind of product I can handle..
// well do handle
if( p instanceof Apple ) {
/// start producing pies..
}
}
public void startProduction() {
// collect the needed number of apples and then...
Product ofPie = new ApplePie();
notifyProductCreation( ofPie );
}
}
class ApplePress extends AbstractProducer implements Consumer {
// Yeap, something gots produced.
// Just handle if it is an apple
public void productCreated( Product p ) {
if( p instanceof Apple ) {
// start producing cider
}
}
public void startProduction() {
// collect the needed number of apples and then...
Product ofCiderBottle = new AppleCider();
notifyProductCreation( ofCiderBottle );
}
}
class AppleSave implements Consumer {
public void productCreated( Product p ) {
file.append( p );// any one will do.
}
}
class AppleLoad extends AbstractProducer {
public void startProduction() {
readFromFile();
}
private readFromFile() {
for( Product p : file ) {
notifyProductCreation( p );
}
}
}
class Main {
public static void main( String [] args ) {
Configuration conf = new Configuration();
List<Producer> producers conf.read();
for( Producer p : producers ) {
// fasten your seat belts....
p.startProduction();
}
}
}
/// Ahhh, pretty ugly code below this line.
// the idea is:
// Read the configuration file
// for each line split in the "|"
// for each element create a new instance
// and chain it with the next.
// producer | consumer | etc...
// Becomes....
// new Producer().addConsumer( new Consumer() );
// Return the list of create producers.
class Configuration {
List<Producer> producers
// read the file
// create the instances
// let them run.
public List<Producer> read() {
File file = new File(....
// The format is:
// producer | consumer-producer <params> | consumer
String line = uniqueLineFrom( file );
String [] parts = line.split("|");
if( parts.length == 1 ) {
System.err.println("Invalid configuration. use element | element | etc. Only one element was....");
System.exit( 1 );
}
int length = parts.length;
for( int i = 0 ; i < parts.length ; i++ ) {
Object theInstance = implementationMap.get( parts[i] ).newInstance();
validatePosition( i, length, theInstance , parts[i] );
}
List<Producer> producers = new ArrayList<Producer>();
for( int i = 0 ; i < parts.length ; i++ ) {
Object theInstance = getInstance( parts[i] );
if( not( isLast( i, length ) && isProducer( theInstance ) ) {
// the next is its consumer
Producer producer = ( Producer ) theInstance;
producer.addConsumer( ( Consumer ) getInstance( parts[i+1] ));
producers.add( producer );
}
}
return producers;
}
// creates a new instance from the implementation map.
private Object getInstance( String key ) {
return implementationMap.get( part[i] ).newInstance();
}
// validates if an element at the given position is valid or not.
// if not, prints the message and exit.
// the first element most be a producer
// the last one a consumer
// all the middle elements producer-consumer
//
private void validatePosition( int i, int length, Object theInstance, String element ) {
if( isFirst( i ) && not(isProducer(( theInstance ) ))) {
System.err.println( "Invalid configuration: " + element + " most be a producer ( either Ap...");
System.exit( 2 );
} else if ( isLast( i, length ) && not( isConsumer( theInstance ))) {
System.err.println( "Invalid configuration: " + element + " most be a consumer ( either Ap...");
System.exit( 3 );
} else if ( isMiddleAndInvalid( i, length , instance ) ) {
System.err.println( "Invalid configuration: " + element + " most be a producer-consumer ( either Ap...");
System.exit( 4 );
}
}
private static Map<String,Class> implementationMap = new HashMap<String,Class>() static {
implementationMap.put( "AppleTree", AppleTree.class );
implementationMap.put( "ApplePieMaker ", ApplePieMaker .class );
implementationMap.put( "ApplePress", ApplePress.class );
implementationMap.put( "AppleSave", AppleSave.class );
implementationMap.put( "AppleLoad", AppleLoad.class );
implementationMap.put( "ApplePieMonitor", ApplePieMonitor.class );
};
// Utility methods to read better ( hopefully ) the statements
// If you could read the validations above you may ignore these functions.
private boolean not( boolean value ) {
return !value;
}
private boolean isFirst( int i ) {
return i == 0;
}
private boolean isLast( int i, int l ) {
return i == l -1 ;
}
private boolean isProducer( Object o ) {
return o instanceof Producer;
}
private boolean isConsumer( Object o ) {
return o instanceof Consumer;
}
private boolean isMiddleAndInvalid( int index, int length, Object instance ) {
return not( isFirst( index ) ) && not( isLast( index, length ) ) && not( isProducer( instance ) && isConsumer( instance ));
}
}
I believe what you are trying to do can be done within the Spring framework. It uses dependency injection to say "In order to create X I need Y, so find something that produces Y and see what you need in order to create it".
I may be wrong, but I suggest you have a look.
You would need some sort of Registry where producers could register (Hi, I'm an apple tree and I produce apples) and then the consumers could look up whom ever produces apples. This could also be done in reverse where the consumers register interest and the producers look up. I did something similar using JMX where an Object could query the JMX Server for an Object that produced a certain type of Message and then register with that Object (Publish/Subscribe). I am now porting that app to use OSGi which has a similar capability
Try the Java Beanshell.
BeanShell is a small, free, embeddable Java source interpreter with object scripting language features, written in Java. BeanShell dynamically executes standard Java syntax and extends it with common scripting conveniences such as loose types, commands, and method closures like those in Perl and JavaScript.
Related
I have created an object ArrayList,
private ArrayList<Object> objects;
and I am initializing it in a constructor.
public ObjectManager(Handler handler) {
this.handler = handler;
objects = new ArrayList<>();
}
This ArrayList is then painted/added it to a canvas.
public void renderObjects(Graphics g) {
handler.getObjectManager().addObject(new InstanceOfObject(handler, 1000, 1000, g));
}
The method addObject(), adds an object to the ArrayList.
public void addObject(Object e) {
objects.add(e);
}
I would like to remove this object later, by using a similar line of code,
public void removeObject(Object e) {
objects.remove(e);
}
however I do not know how to do that because I do not know how to pass in the object that is being removed. The only way I can think of passing in the object is by doing the following:
handler.getObjectManager().removeObject(new InstanceOfObject(handler, 1000, 1000, g));
I don't even know if this would work because it's removing an "new" object. And even if it does, "g" is not defined. If I define it in the constructor, I have to change many different things which results in an error (usually a NullPointerException), but even then I cannot figure out how to call this method by passing in the Graphics g parameters.
Your Question is not clear, but this might help.
The List interface implemented by ArrayList already offers a remove method. No need for you to re-invent that.
Object reference
To remove an object, keep and pass a reference to the particular object.
Dog alice = new Dog( "Alice" , "Labrador" ) ;
Dog bob = new Dog( "Bob" , "Chihuahua" ) ;
List< Dog > dogs = new ArrayList<>() ;
dogs.add( alice ) ;
dogs.add( bob ) ;
…
dogs.remove( bob ) ;
Index number
Alternatively, remember the slot (index) of the list containing the object you want to remove. Pass that zero-based index number to the remove method.
You can actually find Java's source code on the web (like https://github.com/AdoptOpenJDK/openjdk-jdk11/blob/master/src/java.base/share/classes/java/util/ArrayList.java#L644), or even as src.zip in the JDK itself. So this is how remove() looks like:
public boolean remove(Object o) {
final Object[] es = elementData;
final int size = this.size;
int i = 0;
found: {
if (o == null) {
for (; i < size; i++)
if (es[i] == null)
break found;
} else {
for (; i < size; i++)
if (o.equals(es[i]))
break found;
}
return false;
}
fastRemove(es, i);
return true;
}
and while the loops with the labeled breaks may look a bit esoteric, the important part is the o.equals(): if your "InstanceOfObject" class implements its own equals(), you can make the comparison work with freshly made throwaway instances too.
Hi everyone I have the following code in my .jjt file for my abstract syntax tree for checking track if where the nodes are made within the file that is passed to it but I cannot access this variable from my semantic checker class.
The code is bellow and any help would be appreciated! I've tried everything and I'm losing hope at this stage.
This is the integer in the .jjt file i'd like to access
TOKEN_MGR_DECLS :
{
static int commentNesting = 0;
public static int linenumber = 0;
}
SKIP : /*STRUCTURES AND CHARACTERS TO SCAPE*/
{
" "
| "\t"
| "\n" {linenumber++;}
| "\r"
| "\f"
}
An example of one of my nodes
void VariableDeclaration() #VariableDeclaration : {Token t; String id; String type;}
{
t = <VARIABLE> id = Identifier() <COLON> type = Type()
}
My semantic checker class
public class SemanticCheckVisitor implements "My jjt file visitor" {
public Object visit(VariableDeclaration node, Object data) {
node.childrenAccept(this, data);
return data;
}
How would it be possible to get the linenumber which this node was declared?
Thanks everyone.
}
You can see an example of this in the Teaching Machine's Java parser, which is here.
First you need to modify your SimpleNode type to include a field for the line number. In the TM I added a declaration
private SourceCoords myCoords ;
where SourceCoords is a type that includes not only the line number, but also information about what file the line was in. You can just use an int field. Also in SimpleNode you need to declare some methods like this
public void setCoords( SourceCoords toSet ) { myCoords = toSet ; }
public SourceCoords getCoords() { return myCoords ; }
You might want to declare them in the Node interface too.
Over in your .jjt file, use the option
NODE_SCOPE_HOOK=true;
And declare two methods in your parser class
void jjtreeOpenNodeScope(Node n) {
((SimpleNode)n).setCoords( new SourceCoords( file, getToken(1).beginLine ) ) ;
}
void jjtreeCloseNodeScope(Node n) {
}
Hmm. I probably should have declared the methods in Node to avoid that ugly cast.
One more thing, you are keeping count of the lines yourself. It's better the get the line number from the token, like I did. Your counter will generally by one token ahead. But when the parser looks ahead, it could be several tokens ahead.
If the token manager isn't keeping count of the lines correctly, then use your own count, but communicate it to the parser through an extra added field in the Token class.
Generally it's a bad idea to compute anything in the token manager and then use it in the parser unless its information you store in the tokens.
Imagine a Person class with a boolean flag indicating whether or not the person is employable - set to false by default.
public class Person{
boolean employable = false;
...
}
Now imagine having some external boolean methods which act on Person objects. For example, consider static boolean methods in a utility class.
public class PersonUtil{
public static boolean ofWorkingAge(Person p){
if(p.getAge() > 16) return true;
return false;
}
...
}
Boolean static methods are in essence analogous to boolean valued functions i.e. predicates.
We can construct a 2^(#predicates)-by-#predicates truth table out of predicates. For example, given three predicates: ofWorkingAge, ofGoodCharacter, isQualified we can construct the following 8-by-3 truth table:
T T T
T T F
T F T
T F F
F T T
F T F
F F T
F F F
We now want to employ people with desirable qualities. Let + indicate that we wish to consider somebody employable (i.e. set their employability flag to true) and - the opposite.
T T T | +
T T F | +
T F T | +
T F F | -
F T T | +
F T F | -
F F T | -
F F F | -
Now imagine having a collection of Person objects. For each person we adjust their employability flag according to the three predicates. We also update a count (this forces us to use the entire truth table instead of just the positives), so that given 1,000 people we want to end up with something like:
T T T | + 100
T T F | + 200
T F T | + 50
T F F | - 450
F T T | + 50
F T F | - 50
F F T | - 50
F F F | - 50
Presumably this can be thought of as filtering with truth tables. Setting employability flags and updating counts is a rather contrived example but you can easily see how we might instead want to set and update much more complicated things.
QUESTION
Is there a way of elegantly doing this? I can think of two solutions:
Clunky solution
Have a giant hand coded if, else if, else chain.
if(ofWorkingAge && ofGoodCharacter && isQualified){
c1++;
p.setEmployable(true)
}
else if(ofWorkingAge && ofGoodCharacter && !isQualified){
c2++;
p.setEmployable(true)
}
...
else if(!ofWorkingAge && !ofGoodCharacter && isQualified){
c7++;
}
else{
c8++;
}
This is just bad.
Slightly smarter solution
Pass predicates (perhaps in an array) and a collection of sentences to a method. Let the method generate the corresponding truth table. Loop over the people, set their employability, and return an array of counts.
I can see how things could be done with functional interfaces. This SO answer is potentially relevant. You could change PrintCommand to IsQualified and pass callCommand a Person instead of a string. But this also seems kindah clunky because we'd then have to have a new interface file for every predicate we come up with.
Is there any other Java 8-ish way of doing this?
Let's start with the list of predicates you have:
List<Predicate<Person>> predicates = Arrays.<Predicate<Person>> asList(
PersonUtil::ofWorkingAge, PersonUtil::ofGoodCharacter,
PersonUtil::isQualified);
To track which predicate is true or false, let's attach names to them creating NamedPredicate class:
public static class NamedPredicate<T> implements Predicate<T> {
final Predicate<T> predicate;
final String name;
public NamedPredicate(Predicate<T> predicate, String name) {
this.predicate = predicate;
this.name = name;
}
#Override
public String toString() {
return name;
}
#Override
public boolean test(T t) {
return predicate.test(t);
}
}
(one may attach BitSet or something like this for efficiency, but String names are also fine).
Now we need to generate a truth table which is a new list of predicates having names like "T T F" and able to apply the given combination of source predicates, negated or not. This can be generated easily with a bit of functional programming magic:
Supplier<Stream<NamedPredicate<Person>>> truthTable
= predicates.stream() // start with plain predicates
.<Supplier<Stream<NamedPredicate<Person>>>>map(
// generate a supplier which creates a stream of
// true-predicate and false-predicate
p -> () -> Stream.of(
new NamedPredicate<>(p, "T"),
new NamedPredicate<>(p.negate(), "F")))
.reduce(
// reduce each pair of suppliers to the single supplier
// which produces a Cartesian product stream
(s1, s2) -> () -> s1.get().flatMap(np1 -> s2.get()
.map(np2 -> new NamedPredicate<>(np1.and(np2), np1+" "+np2))))
// no input predicates? Fine, produce empty stream then
.orElse(Stream::empty);
as truthTable is a Supplier<Stream>, you can reuse it as many times as you want. Also note that all the NamedPredicate objects are generated on the fly by demand, we don't store them anywhere. Let's try to use this supplier:
truthTable.get().forEach(System.out::println);
The output is:
T T T
T T F
T F T
T F F
F T T
F T F
F F T
F F F
Now you can classify the persons collection by the truth table, for example, in the following way:
Map<String,List<Person>> map = truthTable.get().collect(
Collectors.toMap(np -> np.toString(), // Key is string like "T T F"
// Value is the list of persons for which given combination is true
np -> persons.stream().filter(np).collect(Collectors.toList()),
// Merge function: actually should never happen;
// you may throw assertion error here instead
(a, b) -> a,
// Use LinkedHashMap to preserve an order
LinkedHashMap::new));
Now you can easily get the counts:
map.forEach((k, v) -> System.out.println(k+" | "+v.size()));
To update the employable field we need to know how the desired truth table is specified. Let it be the collection of truth strings like this:
Collection<String> desired = Arrays.asList("T T T", "T T F", "T F T", "F T T");
In this case you may use the previously generated map:
desired.stream()
.flatMap(k -> map.get(k).stream())
.forEach(person -> person.setEmployable(true));
Basically, a truth value is a single bit and you can always use an integer value of n bits to encode n truth value. Then, interpreting the integer value as a number allows you to associate values with the combination of truth values using a linear table.
So using an int a encoded truth value/ table index, a generic truth table class may look like this:
public class TruthTable<O,V> {
final List<? extends Predicate<? super O>> predicates;
final ArrayList<V> values;
#SafeVarargs
public TruthTable(Predicate<? super O>... predicates) {
int size=predicates.length;
if(size==0 || size>31) throw new UnsupportedOperationException();
this.predicates=Arrays.stream(predicates)
.map(Objects::requireNonNull).collect(Collectors.toList());
values=new ArrayList<>(Collections.nCopies(1<<size, null));
}
public V get(O testable) {
return values.get(index(testable, predicates));
}
public V get(boolean... constant) {
if(constant.length!=predicates.size())
throw new IllegalArgumentException();
return values.get(index(constant));
}
public V set(V value, boolean... constant) {
if(constant.length!=predicates.size())
throw new IllegalArgumentException();
return values.set(index(constant), value);
}
public static <T> int index(T object, List<? extends Predicate<? super T>> p) {
int size=p.size();
if(size==0 || size>31) throw new UnsupportedOperationException();
return IntStream.range(0, size).map(i->p.get(i).test(object)? 1<<i: 0)
.reduce((a,b) -> a|b).getAsInt();
}
public static <T> int index(boolean... values) {
int size=values.length;
if(size==0 || size>31) throw new UnsupportedOperationException();
return IntStream.range(0, size).map(i->values[i]? 1<<i: 0)
.reduce((a,b) -> a|b).getAsInt();
}
}
The key point is the calculation of the int index from truth values. There are two versions. First, calculate from explicit boolean values for initializing the table or querying its state, second, for an actual test object and the list of applicable predicates. Note that these two methods are factored out into public static methods so that they can be used for alternative table types, e.g. an array of primitive values. The only thing to do is to create a linear storage for 2ⁿ values when you have n predicates, e.g. new int[1<<n] and then using these index methods for determining the entry to access for given values or an actual test candidate.
Instances of the generic TruthTable can be used as follows:
TruthTable<Person,Integer> scoreTable=new TruthTable<>(
PersonUtil::ofWorkingAge, PersonUtil::ofGoodCharacter, PersonUtil::isQualified);
scoreTable.set(+100, true, true, true);
scoreTable.set(+200, true, true, false);
scoreTable.set(+50, true, false, true);
scoreTable.set(-450, true, false, false);
scoreTable.set(+50, false, true, true);
scoreTable.set(-50, false, true, false);
scoreTable.set(-50, false, false, true);
scoreTable.set(-50, false, false, false);
Person p = …
int score = scoreTable.get(p);
I'm not sure if this is what you're looking for, but you could use a bitwise operators on your variables..
if(ofWorkingAge && ofGoodCharacter && isQualified){
c1++;
p.setEmployable(true)
}
might become
int combined = 0b00000000;
combined |= ofWorkingAge ? 0b00000100 : 0b00000000;
combined |= ofGoodCharacter ? 0b00000010 : 0b00000000;
combined |= isQualified ? 0b00000001 : 0b00000000;
switch (combined){
case 0b00000111:
c1++;
p.setEmployable(true)
break;
case 0b00000110:
// etc
where the last bits represent ofWorkingAge/ofGoodCharacter/isQualified.
I'm writing a program to simulate an artificial neural network. I have the following classes and interfaces set up:
public interface Neuron
{
}
// Input neuron
public class INeuron implements Neuron
{
}
// Output and hidden neuron
public class ONeuron implements Neuron
{
}
public interface Layer
{
public ArrayList<Neuron> getNeurons();
}
// Input layer
public class ILayer implements Layer
{
ArrayList<INeuron> neurons = new ArrayList<INeuron>();
public ArrayList<Neuron> getNeurons()
{
return neurons;
}
// other stuff appropriate to the input layer
}
The compiler reports "cannot convert from ArrayList<INeuron> to ArrayList<Neuron>."
I've tried switching things around. For example: ArrayList<Neuron> neurons = new ArrayList<INeuron>(). But that just seems to shift the same error to different parts of the class.
I don't understand why INeuron can't be implicitly cast to Neuron since INeuron is a subtype of Neuron.
You need to use:
public interface Layer
{
public ArrayList<? extends Neuron> getNeurons();
}
because of lack of covariance and contravariance in generics. If you return an ArrayList < INeuron > as an ArrayList < Neuron > then you would potentially be able to add an element that is not a INeuron (like another child of Neuron) to an ArrayList < INeuron >
Simply change:
ArrayList<INeuron> neurons = new ArrayList<INeuron>();
to:
ArrayList<Neuron> neurons = new ArrayList<Neuron>();
to be able to serve both types.
This is an example of a bad thing that could happen.
void mymethod ( ILayer l )
{
List<Neuron> neurons = l . getNeurons ( ) ;
neurons . add ( new ONeuron ( ) ) ; // bad thing
}
My method mymethod just contaminated that ILayer's neurons list with a non INeuron.
I recommend Luciano's solution.
public Layer <?> getNeurons();
This is another way to write subtype,right?
I'm having a problem in relation to using super and overriding. Basically, class B which extends A has a setter for the current state of the class. Inside the setter, depending on the value of the current state, a different event can be executed.
In the setter for B the first thing that happens is that it called super so that the setter for A can go launch general events. Then the control returns to the setter of B where I can execute specific events if needed.
The problem comes when A executes events that call the setter and so it can go multiple depths before returning back to to B.
The following code illustrates what I'm talking about (it's groovy, but that's irrelevant):
class A
{
public int num = 0;
public void setFoo( int i )
{
println "A: $i";
num = i + 1;
// what's actually happening, is that in the setter, depending
// on the value, an event can be executed, which will in turn
// call setFoo() on the class. this is just the equivalet
if( i < 3 )
this.setFoo( num );
}
}
class B extends A
{
public void setFoo( int i )
{
println "B: $i - num $num";
super.setFoo( i );
println "After super for $i - num: $num";
}
}
def B = new B();
B.foo = 0;
This results in an output of:
B: 0 - num 0
A: 0
B: 1 - num 1
A: 1
B: 2 - num 2
A: 2
B: 3 - num 3
A: 3
After super for 3 - num: 4
After super for 2 - num: 4
After super for 1 - num: 4
After super for 0 - num: 4
When I come back to B after the call to super ("After super for...") the value of num is always the same, meaning that it screws with what I'm trying to do in B (i.e. launch specific events).
Some points on the architecture to begin with:
"Why not use i instead of num in the setter for B"? - This is just the easiest example to show the problem - what's actually happening in my code is different, just the same problem. In my case, I have access to num, not i. Even if I rewrote part of it to pass i, the state of the class will have moved on (due to the base class)
It's a server environment, so I don't have access to a frame loop or something similar. It's event based.
It should be possible to async execute the event, or set the event up to schedule later, but that requires a lot of advance knowledge of where and when the event is going to be used, which breaks the whole point of events in the first place
What I'm looking for is a way to launch events based on the state of the class, but have it happen after the return from super (while still working for the base class) if that makes any sense.
Ideas?
EDIT
To give a better idea of the code I'm using (based on Don's suggestion to use a callback), here is a simplified version of what I have. (If you want to run it, you can just copy it into http://groovyconsole.appspot.com/):
// A is our base class
class A{
public int currentState= 0;
public void setCurrentState( int i )
{
this.currentState = i;
this._onStateChanged();
}
protected void _onStateChanged()
{
println "The state in A is $currentState";
// depending on the state launch some events.
// these can changed the current state of
// B
if( this.currentState == 0 )
{
def event = new MyEvent( this );
event.execute();
}
}
}
// B is a more specific version of A
class B extends A
{
protected void _onStateChanged()
{
println "The state in B is $currentState";
super._onStateChanged();
println "The state in B afterwards is $currentState";
// launch specific events based on the current state
if( this.currentState == 0 )
println "Launch a specific event!";
}
}
// simple event class that can change the status of B
class MyEvent
{
private B b = null;
public MyEvent( B b )
{
this.b = b;
}
public void execute()
{
// do some stuff
b.currentState++;
}
}
// program start
def b = new B();
b.currentState = 0;
B has to call super as there are some states where I want a basic plus a specific event. Basic events are normally used to set the program state, while specific ones are there to react.
In this example, my output is:
The state in B is 0
The state in A is 0
The state in B is 1
The state in A is 1
The state in B afterwards is 1
The state in B afterwards is 1
i.e. B never gets to react to the state being 0
Edit
If I change the super() call in B to the end of _onStateChanged() rather than the start, this will give the chance for it to react to the state before it gets changed. Is this a simple solution to this problem, or just wrong?
Edit
So I came up with this (again, you can copy it into the groovy console appspot site):
// A is our base class
class A{
public int currentState = 0;
public int nextState = 0;
public boolean canChange = true;
public void setCurrentState( int i )
{
if( this.canChange )
{
this.currentState = i;
this._onStateChanged();
}
else
this.nextState = i;
}
protected void _onStateChanged()
{
println "The state in A is $currentState";
// depending on the state launch some events.
// these can changed the current state of
// B
if( this.currentState == 0 )
{
def event = new MyEvent( this );
event.execute();
}
}
}
// B is a more specific version of A
class B extends A
{
protected void _onStateChanged()
{
this.canChange = false;
println "The state in B is $currentState";
super._onStateChanged();
println "The state in B afterwards is $currentState";
// launch specific events based on the current state
if( this.currentState == 0 )
println "Launch a specific event!";
this.canChange = true;
if( this.nextState != 0 )
{
int state = this.nextState;
this.nextState = 0;
this.currentState = state;
}
}
}
// simple event class that can change the status of B
class MyEvent
{
private B b = null;
public MyEvent( B b )
{
this.b = b;
}
public void execute()
{
// do some stuff
b.currentState++;
}
}
// program start
def b = new B();
b.currentState = 0;
It gives me the desired output:
The state in B is 0
The state in A is 0
The state in B afterwards is 0
Launch a specific event!
The state in B is 1
The state in A is 1
The state in B afterwards is 1
but is kind of ugly. Better way?
Fundamentally, A.setFoo is broken
class A
{
public int num = 0;
public void setFoo( int i )
{
println "A: $i";
num = i + 1;
// what's actually happening, is that in the setter, depending
// on the value, an event can be executed, which will in turn
// call setFoo() on the class. this is just the equivalet
if( i < 3 )
this.setFoo( num );
}
}
Because new A().setFoo(2) (for example) will cause a stack overflow. Something like the following might be a better design
abstract class A
{
public int num = 0;
abstract void setFooCallback(int i)
public final void setFoo( int i )
{
println "A: $i";
num = i + 1;
// what's actually happening, is that in the setter, depending
// on the value, an event can be executed, which will in turn
// call setFoo() on the class. this is just the equivalet
if( i < 3 )
this.setFooCallback( num );
}
}
class B extends A
{
public void setFooCallback( int i )
{
// Implement me to launch custom events or whatever
// If you call setFoo in here you'll get a stack overflow
}
}
If you need to instantiate instances of A, just remove the abstract modifiers and change setFooCallback to:
void setFooCallback(int i) { // default implementation does nothing }
FYI, I think the above is an example of the Template (Method) pattern
The actual problem is that Java copies and passes all arguments by value. With primitives (like the int i), this results in each method getting it's own copy of the value. Usually, this is to protect against what you're actually trying to do, as method side-effects can otherwise surprise people.
A quick and easy way to fix this is to return the modified value of i - so, your call looks like this: i = super.foo(i);. This has two benefits - 1) it lets people know that you expect that the value of i may change, and 2) you're not depending on a side-effect to change the value.
Otherwise, you could change i to be some sort of object wrapper (I hesitate to say Integer, because there are some under-the-cover optimization things that could mess this design up). But if you do that, document the desired behaviour out the wazoo, or developers who use the method may be surprised at changing values (or future maintainers may not correctly adjust the values).
EDIT:
Okay, from the sound of it, you want to react to both the current and a previous state, but you never store the previous state...
Clearly, you're going to have to store off the previous state somehow - a local variable inside b._onStateChanged() is probably your best bet. Otherwise, your program will continue to react to the current state (just, the current state isn't what you were expecting).
Also, you may want to change up your architecture a little - as it is, you never know if your default behaviour (inside of A) will still be carried out. Look at #Don's recommendation again, as I suspect this will be more in the direction your architecture needs to go (you always want the generic, right?). In other words, don't call the specific behaviour first - call the generic, have it perform its modifications, and have it call the specific behaviour when it's done. If necessary, you can then also have the setFoo() method call itself recursively, allowing it to call setFooCallback() for each mutated state.
I think a better way to solve this is using the Template Method design pattern.
Ok, so I have two solutions to this. This first one is the last code sample provided. It adds another parameters to check if we can change, and if so, does, otherwise it waits:
// A is our base class
class A{
public int currentState = 0;
public int nextState = 0;
public boolean canChange = true;
public void setCurrentState( int i )
{
if( this.canChange )
{
this.currentState = i;
this._onStateChanged();
}
else
this.nextState = i;
}
protected void _onStateChanged()
{
println "The state in A is $currentState";
// depending on the state launch some events.
// these can changed the current state of
// B
if( this.currentState == 0 )
{
def event = new MyEvent( this );
event.execute();
}
}
}
// B is a more specific version of A
class B extends A
{
protected void _onStateChanged()
{
this.canChange = false;
println "The state in B is $currentState";
super._onStateChanged();
println "The state in B afterwards is $currentState";
// launch specific events based on the current state
if( this.currentState == 0 )
println "Launch a specific event!";
this.canChange = true;
if( this.nextState != 0 )
{
int state = this.nextState;
this.nextState = 0;
this.currentState = state;
}
}
}
// simple event class that can change the status of B
class MyEvent
{
private B b = null;
public MyEvent( B b )
{
this.b = b;
}
public void execute()
{
// do some stuff
b.currentState++;
}
}
// program start
def b = new B();
b.currentState = 0;
The second solution takes a more listener like approach. Both the base and the extending class register functions to call when the state changes:
// A is our base class
class A{
public int currentState = 0;
public def listeners = [];
public void setCurrentState( int i )
{
// call each of our listeners with the current state
this.currentState = i;
listeners.each { it( i ); }
}
public A()
{
this.addListener( this.&_onStateChanged );
}
public void addListener( def callback )
{
this.listeners.add( 0, callback );
}
protected void _onStateChanged( int state )
{
println "The state in A is $state";
// depending on the state launch some events.
// these can changed the current state of
// B
if( state == 0 || state == 1 )
{
def event = new MyEvent( this );
event.execute();
}
}
}
// B is a more specific version of A
class B extends A
{
public B()
{
super();
this.addListener( this.&_onBStateChanged );
}
protected void _onBStateChanged( int state )
{
println "The state in B is $state";
// launch specific events based on the current state
if( state == 0 )
println "Launch a specific event!";
}
}
// simple event class that can change the status of B
class MyEvent
{
private B b = null;
public MyEvent( B b )
{
this.b = b;
}
public void execute()
{
// do some stuff
b.currentState++;
}
}
// program start
def b = new B();
b.currentState = 0;
Both give me the output I'm looking for, though the second one is slightly broken, as it breaks the normal convention of adding listeners. Listeners are added to the start of the list, rather than the end. That'll give me an output like:
The state in B is 0
Launch a specific event!
The state in A is 0
The state in B is 1
The state in A is 1
The state in B is 2
The state in A is 2
So B gets called first, but at least they're in a good order. If I just push listeners to the list, I get:
The state in A is 0
The state in A is 1
The state in A is 2
The state in B is 2
The state in B is 1
The state in B is 0
Launch a specific event!
So B will get to react to the state being 0, but the order is reversed and by that stage, the state has changed to something else. It also breaks a bit in that it requires knowledge that B will never launch an event that will change the state, as otherwise we still have the same problem.
Out of the two, I think the first one is the best (assuming a non-rewrite of the architecture/problem). It's a bit more complicated, but doesn't require prior knowledge anywhere and the events get called in the right order.
Unless someone can suggest a better architecture for the problem, I'll go with that.
For me it looks like you are trying to execute specific B events before 'default' A events. In this case most appropriate approach for me would be executing B events first, then calling super to trigger A events.
UPDATE:
Use Template Method pattern:
class A{
public int currentState= 0;
public void setCurrentState( int i )
{
this.currentState = i;
println "The state in A is $currentState";
// Maybe you need to split your MyEvent into two events.
// MyEventA - Does whatever required before executing special events.
def eventA = new MyEventA( this );
eventA.execute();
this._invokeSpecialEvents();
// depending on the state launch some events.
if( this.currentState == 0 )
{
// MyEventB - Does whatever required after executing special events (do actual currentState change).
def event = new MyEventB( this );
event.execute();
}
}
protected void _invokeSpecialEvents()
{
// You mentioned that cannot make A class abstract.
// This method is empty rather than abstract only for that reason.
}
}