Last active
June 27, 2017 16:10
-
-
Save matsubara0507/e380825e953832282612b3bded798d91 to your computer and use it in GitHub Desktop.
ジェネリクス勉強会(https://connpass.com/event/56773/) の Haochen の発表ネタの実装をしてみた(合ってないかも)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.BufferedReader; | |
import java.io.InputStreamReader; | |
import java.util.ArrayList; | |
import java.util.function.Consumer; | |
public class Main { | |
public static void main(String[] args) throws Exception { | |
System.out.println("hello!!!"); | |
CanvasObj obj = Graphics.builder() | |
.newGroup() | |
.newCircle().x(10).y(10).radius(10).circle() | |
.newCircle().x(10).y(20).radius(30).circle() | |
.end() | |
.newGroup() | |
.newCircle().x(30).y(10).radius(10).circle() | |
.end() | |
.build(); | |
System.out.println(obj); | |
// CanvasObj[CanvasObj[CircleObj(x=10.0, y=10.0, radius=10.0), CircleObj(x=10.0, y=20.0, radius=30.0), ], CanvasObj[CircleObj(x=30.0, y=10.0, radius=10.0), ], ] | |
} | |
} | |
abstract class CanvasObj { | |
double x, y; | |
public void setX(double x) { | |
this.x = x; | |
} | |
public void setY(double y) { | |
this.y = y; | |
} | |
public double getX() { | |
return this.x; | |
} | |
public double getY() { | |
return this.y; | |
} | |
public String toString() { | |
return "x=" + this.x + ", y=" + this.y; | |
} | |
} | |
class GroupObj extends CanvasObj { | |
ArrayList<CanvasObj> groups = new ArrayList<CanvasObj>(); | |
public void add(CanvasObj obj) { | |
groups.add(obj); | |
} | |
public String toString() { | |
String str = "CanvasObj["; | |
for(CanvasObj obj : this.groups) { | |
str += (obj.toString() + ", "); | |
} | |
return str + "]"; | |
} | |
} | |
class CircleObj extends CanvasObj { | |
double radius; | |
public void setRadius(double radius) { | |
this.radius = radius; | |
} | |
public double getRadius() { | |
return this.radius; | |
} | |
@Override | |
public String toString() { | |
return "CircleObj(" + super.toString() + ", radius=" + this.radius + ")"; | |
} | |
} | |
class GroupObjBuilder<ContT> { | |
interface GroupObjHarvester<ContT> { | |
ContT harvest(GroupObj group); | |
} | |
GroupObj state = new GroupObj(); | |
GroupObjHarvester<ContT> harvester; | |
GroupObjBuilder(GroupObjHarvester<ContT> harvester) { | |
this.harvester = harvester; | |
} | |
GroupObj build() { return state; } | |
GroupObjBuilder<ContT> add(CanvasObj obj) { | |
this.state.add(obj); | |
return this; | |
} | |
ContT end() { return harvester.harvest(build()); } | |
GroupObjBuilder<GroupObjBuilder<ContT>> newGroup() { | |
return new GroupObjBuilder<GroupObjBuilder<ContT>>(obj -> { | |
return add(obj); | |
}); | |
} | |
CircleObjBuilder<GroupObjBuilder<ContT>> newCircle() { | |
return new CircleObjBuilder<GroupObjBuilder<ContT>>(obj -> { | |
return add(obj); | |
}); | |
} | |
} | |
abstract class CanvasObjBuilder<StateT extends CanvasObj, Self extends CanvasObjBuilder<StateT, Self>> { | |
Self x(double x) { | |
return self(obj -> obj.setX(x)); | |
} | |
Self y(double y) { | |
return self(obj -> obj.setY(y)); | |
} | |
abstract StateT getState(); | |
@SuppressWarnings("unchecked") // black magic! XD | |
Self self(Consumer<StateT> action) { | |
action.accept(getState()); | |
return (Self)this; | |
} | |
} | |
class CircleObjBuilder<ContT> extends CanvasObjBuilder<CircleObj, CircleObjBuilder<ContT>> { | |
interface CircleObjHarvester<ContT> { | |
ContT harvest(CircleObj circle); | |
} | |
CircleObj state = new CircleObj(); | |
CircleObjHarvester<ContT> harvester; | |
CircleObjBuilder(CircleObjHarvester<ContT> harvester) { | |
this.harvester = harvester; | |
} | |
CircleObj getState() { | |
return this.state; | |
} | |
CircleObjBuilder<ContT> radius(double radius) { | |
return self(obj -> obj.setRadius(radius)); | |
} | |
CircleObj build() { | |
return this.state; | |
} | |
ContT circle() { | |
return harvester.harvest(build()); | |
} | |
} | |
class Graphics { | |
static GroupObjBuilder<GroupObj> builder() { | |
return new GroupObjBuilder<GroupObj>(obj -> { return obj; }); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
を
としてしまって,なかなかデバッグが大変だった。