Skip to content
This repository was archived by the owner on Oct 28, 2020. It is now read-only.

Commit 7446eed

Browse files
author
Nicolai Parlog
committed
Experiment with mixins
1 parent 5ddd4a7 commit 7446eed

File tree

1 file changed

+100
-0
lines changed
  • src/main/java/org/codefx/demo/java10/lang/var

1 file changed

+100
-0
lines changed
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
package org.codefx.demo.java10.lang.var;
2+
3+
import java.math.BigDecimal;
4+
import java.util.function.Supplier;
5+
6+
public class Mixins {
7+
8+
/*
9+
* DOWNSIDES
10+
*
11+
* - requires considerable amount of boilerplate
12+
* - has a non-trivial structure
13+
* - delegating interface has less flexibility than a class
14+
* - Object's methods can not be default-implemented,
15+
* so toString, equals, hashCode, ... can never be forwarded
16+
* to existing implementation
17+
*
18+
* ALTERNATIVES
19+
*
20+
* - extension type collecting all needed methods
21+
* - utility methods
22+
*/
23+
24+
public void report(Megacorp megacorp) {
25+
// without `var` there would be no way to declare a variable
26+
// of type `IsSuccessful` and `IsEvil`
27+
var corp = (MegacorpDelegate & IsSuccessful & IsEvil) () -> megacorp;
28+
System.out.printf(
29+
"Corporation %s is %s and %s.\n",
30+
corp.name(),
31+
// relying on `IsSuccessful`
32+
corp.isSuccessful() ? "successful" : "a failure",
33+
// relying on `IsEvil`
34+
corp.isEvil() ? "evil" : "a failure"
35+
);
36+
}
37+
38+
// important domain concept, used throughout the system
39+
interface Megacorp {
40+
41+
String name();
42+
43+
BigDecimal earnings();
44+
45+
BigDecimal taxes();
46+
47+
}
48+
49+
// created right next to `Megacorp` to allow easy extension
50+
// throughout the system
51+
@FunctionalInterface
52+
interface MegacorpDelegate extends Megacorp {
53+
54+
// there can only be this one abstract method
55+
Megacorp delegate();
56+
57+
@Override
58+
default String name() {
59+
return delegate().name();
60+
}
61+
62+
@Override
63+
default BigDecimal earnings() {
64+
return delegate().earnings();
65+
}
66+
67+
@Override
68+
default BigDecimal taxes() {
69+
return delegate().taxes();
70+
}
71+
72+
// because `Object` methods can not have default implementations,
73+
// there can be no delegations for toString, equals, hashCode, ... :(
74+
75+
}
76+
77+
// these are concepts that are only useful in a very narrow part of the system
78+
// and so they are not added to the original interface to prevent polluting it
79+
// with too many methods;
80+
// these mixins must not have abstract methods
81+
82+
interface IsSuccessful extends Megacorp {
83+
84+
final BigDecimal SUCCESS_BOUNDARY = new BigDecimal("500000000");
85+
86+
default boolean isSuccessful() {
87+
return earnings().compareTo(SUCCESS_BOUNDARY) > 0;
88+
}
89+
90+
}
91+
92+
interface IsEvil extends Megacorp {
93+
94+
default boolean isEvil() {
95+
return true;
96+
}
97+
98+
}
99+
100+
}

0 commit comments

Comments
 (0)