我正面临一个代码设计挑战,不太确定如何解决它。我试着在网上查了一下,但这让我更困惑了。
InterfaceI1→父级接口(单方法)
interface I1 {
print(String a);
}
C1 ->C1实现了I1 (C1覆盖了I1没有自己的方法的方法)
public class C1 implements I1 {
@Override
print(String a){
//some code
}
}
分类CC1、CC2、CC3、CC4、CC5 ->所有这些都扩展了C1(覆盖C1中的方法,并且也有自己的方法)。它们不是春豆。
public class CC1 extends C1 {
@Override
print(String a) {
//Some Code
}
//Need to execute common code on initiation of this method/
//Similar methods are in CC2, CC3 etc
scan() {
//Some Code
}
}
我需要在CC1, CC2, CC3, CC4, CC5类中执行某些方法(如scan())时执行一段代码。这些方法没有任何共同之处,当然也不是一个被重写的方法。
是否有一种方法可以在中心位置编写这段通用代码,并使其在相关方法的执行时执行?
同样,这段公共代码的执行也依赖于另一个环境条件。例如:
If the method scan() in CC1 is executed && its a weekend
{
Execute the common code
}
因为我不想用相同的样板代码弄乱所有的方法,我做了一些研究,遇到了AOP。它看起来很适合需求,尽管我不确定是否可以用AOP来管理条件执行。在阅读过程中,我了解了远距离操作反模式,以及它对代码可维护性的不利之处。
任何线索或建议都很有帮助。
我将提供一个粗略的实现(根据我的理解)!
基于以下结构:
interface I1 {
void print(String a);
}
class C1 implements I1 {
@Override
public void print(String a) {
//some code
}
}
class CC1 extends C1 {
public void scan_CC1() {
System.out.println("the scan method of CC1");
}
}
class CC2 extends C1 {
public void scan_CC2() {
System.out.println("the scan method of CC2");
}
}
class CCN extends C1 {
public void scan_CCN() {
System.out.println("the scan method of CCN");
}
}
首先,写一个Cell类,它是方法的容器:
class Cell {
public I1 obj;
public Method method;
public Function<String, Boolean> priorityCall;
public String param;
public Cell(I1 obj, Method method, Function<String, Boolean> priorityCall, String param) {
this.obj = obj;
this.method = method;
this.priorityCall = priorityCall;
this.param = param;
}
public Cell(I1 obj, Method method) {
this.obj = obj;
this.method = method;
}
}
包含两个构造方法:
- 四个参数的构造方法,用于处理有特殊需要的方法调用,例如您提到的CC1的scan方法,需要在周末执行。
- 另一个构造方法,包含两个参数,调用没有特殊要求的方法
接下来提供一个类来注册方法(您可以在run方法中找到一个合适的位置来添加公共执行方法):
class Register {
List<Cell> registerCells = new ArrayList<>();
public void reg(Cell cell) {
registerCells.add(cell);
}
public void run() throws InvocationTargetException, IllegalAccessException {
for (int i = 0; i < registerCells.size(); i++) {
Cell c = registerCells.get(i);
// todo::
// here you can execute that piece of code
if (c.priorityCall == null) {
c.method.invoke(c.obj);
} else {
boolean flag = c.priorityCall.apply(c.param);
if (flag) {
c.method.invoke(c.obj);
}
}
}
}
}
通过reg
方法注册需要调用的方法,然后通过run
方法执行。
然后注册并运行
public static void main(String[] args) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException, ClassNotFoundException {
Register register = new Register();
// scan_CC1 can only be called on weekends
Cell cell_CC1 = new Cell(new CC1(), CC1.class.getMethod("scan_CC1"), "weekend"::equals, "weekend");
// scan_CC1 can only be called on monday
Cell cell_CC2 = new Cell(new CC2(), CC2.class.getMethod("scan_CC2"), "monday"::equals, "sunday");
// scan_CCN no limit
Cell cell_CCN = new Cell(new CCN(), CCN.class.getMethod("scan_CCN"));
register.reg(cell_CC1);
register.reg(cell_CC2);
register.reg(cell_CCN);
register.run();
}
据我所知,Spring AOP非常适合您的问题。实际上,AOP就是为了解决这个问题而设计的,AOP是Spring的一个重要特性。我强烈建议你学习Spring,因为Spring/Spring Boot是一个非常常用的框架。
如果你没有时间或者对它不感兴趣,你可以在这个类中创建一个新类和一个新方法。在这个方法中,您将编写通用代码。然后在你的类中,你创建那个类的对象,然后在你的类CC1, CC2等中调用那个方法。