我试图用“联合发现”来制作一个反对的导向例子。
所以我有一个名为UF的界面,
public interface UF {
boolean connected(int p,int q);
void printArray();
void union(int p,int q);
}
以下类实现了quickFindUF,quickUnionUF,quickWeightedUnionUF 但是它们都共享一个在实现上相同的函数(函数printArray())
用于避免printArray()代码重复的最佳模式是什么?创建一个类调用ArrayPrinter并在所有那些实现UF的类中的printArray()中将数组传递给它?
是否有任何模式可以执行此操作而不进行抽象继承并且只使用接口。因为继承限制了我的设计,如果我继承了一个我不能继承其他东西的类,我不会仅仅为printArray()方法做出这个限制......
答案 0 :(得分:2)
你可以有一个抽象类AbstractUF:
public abstract class AbstractUF implements UF{
public abstract boolean connected(int p,int q);
public void printArray() {
//implementation
}
public abstract void union(int p,int q);
}
并从AbstractUF继承你的类,所以只需(覆盖和)实现其他2个函数
答案 1 :(得分:1)
在Java 8中,您可以使用Default method
执行此操作接口方法
接口中的默认方法和抽象方法与实例方法一样是继承的。但是,当类或接口的超类型提供具有相同签名的多个默认方法时,Java编译器将遵循继承规则来解决名称冲突。这些规则由以下两个原则驱动:
实例方法优于接口默认方法。
忽略已被其他候选项覆盖的方法。当超类型共享一个共同的祖先时,就会出现这种情况。
所以你的代码将是
public interface UF {
default public void printArray() {// Provide default implementation }
}
答案 2 :(得分:1)
您正在考虑delegation。我本人不会称之为设计模式,因为它只是一种组合技术,但无论如何都有一篇维基百科的文章称之为。
在此示例中,UnionFind extends ArrayPrinter
以便ArrayPrinter
接口在整个复合中传播。委托实现了层次结构的一部分:
interface ArrayPrinter {
void printArray();
}
interface UnionFind extends ArrayPrinter {
boolean isConnected(int p, int q);
void makeUnion(int p, int q);
}
class DefaultPrinter implements ArrayPrinter {
@Override
public void printArray() {
/**
* do actual print
*/
}
}
class QuickFind implements UnionFind {
private final ArrayPrinter printDelegate = new DefaultPrinter();
@Override
public void printArray() {
printDelegate.printArray();
}
/**
* the rest
*/
}
答案 3 :(得分:1)
是否有任何模式可以在不进行抽象继承的情况下执行此操作,只需使用接口。
在Java 8中,您可以在接口中声明default methods。限制是默认方法不能依赖于实现类声明的实例变量。他们必须完全依赖类公共API来访问或更新对象状态。
对于适用默认方法的情况,它们避免了扩展公共基类的需要,同时也避免了委托的繁琐。
答案 4 :(得分:0)
接口隔离原则建议将不同的功能划分为单独的接口。在这种情况下,您的printArray()
方法是一个可以与UF接口分离的责任。
您实施了ArrayPrinter
界面,并传递数组。这也符合单一责任原则以及设施解耦架构。您的UF界面对打印知之甚少,这是一项独立的责任,因此由不同的对象处理。