面向对象代码
代码生成是减少无聊任务的不健康负担的一种常用方法,这些任务常常使我们急切地对代码苦恼。 我见过的许多代码生成框架都使用模板替换重复方法,在该模板中,您编写了模板,以了解生成的代码文件的外观,然后替换某些关键字并重复其他部分以生成所需的特定文件。
这种让我烦恼的方法的问题是,要编译生成的代码真的很难知道生成的代码是否可以工作。 您可能已经更改了一个类的名称,并且突然生成的代码无法构建。 为了解决此问题, 我启动了一个名为CodeGen的项目 , 该项目旨在完全面向对象,以便您可以从模板到可执行代码的所有过程中受益于类型安全。 生成器的主要用例是Speedment软件 ,但它可以用于各种项目。
考虑以下代码:
final Generator generator = new JavaGenerator();
final File file = File.of("org/example/Foo.java")
.add(Class.of("Foo").public_()
.add(Field.of("x", DOUBLE_PRIMITIVE).final_())
.add(Field.of("y", DOUBLE_PRIMITIVE).final_())
.add(Field.of("z", DOUBLE_PRIMITIVE).final_())
.call(new AutoConstructor())
.call(new AutoSetGetAdd())
.call(new AutoEquals())
)
.call(new AutoJavadoc())
.call(new AutoImports(generator))
;
应用程序的模型树是使用bean构建的。 可以将新方法和成员变量添加到树中,以创建同一类的变体。
当要呈现代码时,可以轻松地将其传递给生成器类。
String code = generator.on(file).get();
生成的代码如下所示:
/**
* Write some documentation here.
*/
package org.example;
import java.util.Optional;
/**
* @author You name here
*/
public class Foo {
private final double x;
private final double y;
private final double z;
/**
* Initializes the Foo component.
*
* @param x the x
* @param y the y
* @param z the z
*/
public Foo(double x, double y, double z) {
this.x = x;
this.y = y;
this.z = z;
}
/**
* Returns the value of x.
*
* @return the value of x
*/
public double getX() {
return x;
}
/**
* Sets a new value for x.
*
* @param x the new value of x
*/
public void setX(double x) {
this.x = x;
}
/**
* Returns the value of y.
*
* @return the value of y
*/
public double getY() {
return y;
}
/**
* Sets a new value for y.
*
* @param y the new value of y
*/
public void setY(double y) {
this.y = y;
}
/**
* Returns the value of z.
*
* @return the value of z
*/
public double getZ() {
return z;
}
/**
* Sets a new value for z.
*
* @param z the new value of z
*/
public void setZ(double z) {
this.z = z;
}
/**
* Generates a hashCode for this object. If any field is
* changed to another value, the hashCode may be different.
* Two objects with the same values are guaranteed to have
* the same hashCode. Two objects with the same hashCode are
* not guaranteed to have the same hashCode."
*
* @return the hash code
*/
@Override
public int hashCode() {
int hash = 7;
hash = 31 * hash + (Double.hashCode(this.x));
hash = 31 * hash + (Double.hashCode(this.y));
hash = 31 * hash + (Double.hashCode(this.z));
return hash;
}
/**
* Compares this object with the specified one for equality.
* The other object must be of the same type and not null for
* the method to return true.
*
* @param other the object to compare with
* @return {@code true} if the objects are equal
*/
@Override
public boolean equals(Object other) {
return Optional.ofNullable(other)
.filter(o -> getClass().equals(o.getClass()))
.map(o -> (Foo) o)
.filter(o -> this.x == o.x)
.filter(o -> this.y == o.y)
.filter(o -> this.z == o.z)
.isPresent();
}
}
每个组件都是作为接口类对实现的,因此您可以动态更改实现,而无需重写系统的其他部分。
希望这对其他人有帮助!
翻译自: https://www.javacodegeeks.com/2016/02/object-oriented-approach-code-generation.html
面向对象代码