java接⼝枚举_使⽤函数接⼝和枚举实现配置式编程(Java与
Scala实现)
概述###
做报表时,有时需要根据不同的业务⽣成不同的报表。这样,需要能够动态地配置列字段,并根据列字段来输出对应的报表。使⽤函数接⼝结合枚举可以⽐较优雅地实现配置式编程。
问题描述如下:
假设有对象 Student, Teacher ,它们均有属性 Id, Name, Able 。 要求:(1) 打印这些 Student, Teacher 的字段 (Id, Name) 的内容 ; (2) 打印这些 Student, Teacher 的字段 (Name, Able) 的内容。
Java代码⽰例###
直接上代码。应该能看懂。 需要 Java1.8 才能正常运⾏。
接⼝定义####
package zzz.study.function;
/**
* Created by shuqin on 17/3/30.
*/
public interface Person {
String getId();
String getName();
String able();
}
对象定义####
类 Student :
package zzz.study.function;
/
**
* Created by shuqin on 17/3/30.
*/
public class Student implements Person {
private String studentId;
private String name;
private String able;
public Student(String studentId, String name, String able) {
this.studentId = studentId;
this.name = name;
this.able = able;
}
@Override
public String getId() {
return studentId;
}
@Override
public String getName() {
return name;
}
@Override
public String able() {
return able;
}
}
类 Teacher :
package zzz.study.function;
/**
* Created by shuqin on 17/3/30.
*/
public class Teacher implements Person {
private String teacherId;
private String name;
private String able;
public Teacher(String teacherId, String name, String able) { acherId = teacherId;
this.name = name;
this.able = able;
}
@Override
public String getId() {
return teacherId;
}
@Override
public String getName() {
@Override
public String able() {
return able;
}
}
字段定义配置####
字段定义配置是核⼼。 这⾥结合了枚举和函数式接⼝。这⾥之所以写成 FieldEnum(fieldName, fieldTitle, fieldValueGetMethod) 的定义⽅式,是为了便于管理。同样可以采⽤两个 Map 来实现:Map, Map,这样更适⽤于 Java1.6 , 不过要把两个 Map 拼起来才是完整的字段定义视图。 Person::getName 是⽅法引⽤,(Person p) -> p.getName() 的简写形式。
package zzz.study.function;
import java.util.function.Function;
/
**
* Created by shuqin on 17/3/30.
*/
public enum FieldConf {
Id("Id", "编号", Person::getId),
Name("Name", "姓名", Person::getName),
Able("Able", "能⼒", Person::able);
private String name;
private String title;
private Function method;
FieldConf(String name, String title, Function method) {
this.name = name;
this.title = title;
}
public String getName() {
return name;
}
public String getTitle() {
return title;
}
public Function getMethod() {
}
字段定义伴⽣类####
FieldConfAccompany 是 FieldConf 的伴⽣类, 从 Scala 的伴⽣对象借鉴⽽来,体现了 类变量、⽅法 与 实例变量、⽅法 分离的设计思想,使得两者各司其责, 都⽐较简洁。
package zzz.study.function;
import java.util.*;
/**
* Created by shuqin on 17/3/30.
* FieldConf 的伴⽣对象, 从Scala借鉴⽽来
*/
lambda编程public class FieldConfAccompany {
private static Map fieldConfMap = new HashMap();
private static List allFields = new ArrayList<>();
static {
for (FieldConf fc: FieldConf.values()) {
fieldConfMap.put(fc.name(), fc);
allFields.Name());
}
}
public static FieldConf getInstance(String name) {
(name);
}
public static List getAllFields() {
return Collections.unmodifiableList(allFields);
}
}
客户端使⽤####
这⾥使⽤了 java8 Stream api 。 并没有什么特别的,只是针对列表的批量流式处理,具备延迟计算特性。
package zzz.study.function;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* Created by shuqin on 17/3/30.
*/
public class Report {
public static void main(String[] args) {
report(Arrays.asList(new String[] {"Id", "Name"}), getPersons()); report(Arrays.asList(new String[] {"Name", "Able"}), getPersons());
}
public static void report(List fields, List persons) {
String reportTitles = fields.stream().map(
field -> Instance(field).getTitle()
).collect(Collectors.joining(","));
List rows = persons.stream().map(
p -> fields.stream().map(
field -> Instance(field).getMethod().apply(p) ).collect(Collectors.joining(","))
).List());
System.out.println(reportTitles);
System.out.println(String.join("\n",rows));
}
private static List getPersons() {
Person s1 = new Student("s1", "liming", "Study");
Person s2 = new Student("s2", "xueying", "Piano");
Person t1 = new Teacher("t1", "Mr.Q", "Swim");
Person t2 = new Teacher("t2", "Mrs.L", "Dance");
return Arrays.asList(new Person[] {s1, s2, t1, t2});
}
}
输出:
编号,姓名
s1,liming
s2,xueying
t1,Mr.Q
t2,Mrs.L
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论