必要时如何垂头丧气?
How to downcast when it's necessary?
我在公司软件中遇到了一个令人沮丧的问题,我找不到解决方法。 (这是既定的事情,我无法改变整个构想)
我将尝试通过示例向您提供整个上下文:基本上,我们有 2 个软件组件,比方说 BrickHigh、BrickLow。 BrickLow 可以使用 BrickHigh 的所有内容,但 BrickHigh 看不到 Bricklow。
在 BrickHigh 中有一个 Animal class(许多属性)及其 DAO :
public class Animal .. {
//attributes...
}
在 BrickLow 中,我创建了一个 Cat class(还有许多未映射的属性),它扩展了 Animal。
public class Cat extends Animal {
//attributes
}
我们打算做的是让每个映射属性都有一个超级 class(Animal)。但是我不能在我的应用程序中使用我的动物 class,因为它会因为整个应用程序使用 Cat.
而改变太多
但很明显,我无法在从 DAO 获取 Animal 后将其转换为 Cat,因为 Java 不允许,我需要 Animal 的所有信息。
因为我的 BrickHigh 看不到我的 BrickLow,所以没有像 Animal animal = new Cat(); 这样的东西。可能。
我的第一个想法是在 Cat 中创建一个将 Animal 作为参数的构造函数
public Cat(Animal a) {
super(a);
}
但是我的 Animal 中的构造函数必须是什么 class?好像不行。
But what my constructor must be in my Animal class? It doesn't seem to work.
像这样:
public Animal(Animal other) {
this.field1 = other.field1;
this.field2 = other.field2;
// etc
}
但是,我认为使用对象工厂模式可能会更好;即让你的 DAO class 接受一个参数,它是一个 factory 对象,可以创建 Animal
个实例。当您在使用 BrickLow API 的代码中使用 DAO(来自 BrickHigh)时,您可以使用生成 Cat
个实例而不是 Animal
个实例的工厂实例化 if。
我不确定我是否完全理解你的问题,但如果你想从 BrickHigh 的代码中创建某种动物的实例 class,但不了解 BrickLow,你可以使用工厂或 Class 对象,它们将由 DAO 的一个或多个属性标识。
例如:
public interface AnimalFactory {
boolean canInstanciate(AnimalDAO dao);
Animal instanciate(AnimalDAO dao);
}
您的 BrickHigh 将拥有一组工厂,并提供注册新工厂的机制。
例如:
public enum AnimalFactories implements AnimalFactory {
INSTANCE;
private List<AnimalFactory> factories = new ArrayList<>();
public void registerFactory(AnimalFactory factory) {
factories.add(factory);
}
@Override
public boolean canInstanciate(AnimalDAO dao) {
for (AnimalFactory fac: factories) {
if (fac.canInstanciate(dao)) {
return true;
}
}
return false;
}
@Override
public Animal instanciate(AnimalDAO dao) {
for (AnimalFactory fac: factories) {
if (fac.canInstanciate(dao)) {
return fac.instanciate(dao);
}
}
throw new InstanciationException("No factory for that animal");
}
}
我在公司软件中遇到了一个令人沮丧的问题,我找不到解决方法。 (这是既定的事情,我无法改变整个构想)
我将尝试通过示例向您提供整个上下文:基本上,我们有 2 个软件组件,比方说 BrickHigh、BrickLow。 BrickLow 可以使用 BrickHigh 的所有内容,但 BrickHigh 看不到 Bricklow。
在 BrickHigh 中有一个 Animal class(许多属性)及其 DAO :
public class Animal .. {
//attributes...
}
在 BrickLow 中,我创建了一个 Cat class(还有许多未映射的属性),它扩展了 Animal。
public class Cat extends Animal {
//attributes
}
我们打算做的是让每个映射属性都有一个超级 class(Animal)。但是我不能在我的应用程序中使用我的动物 class,因为它会因为整个应用程序使用 Cat.
而改变太多但很明显,我无法在从 DAO 获取 Animal 后将其转换为 Cat,因为 Java 不允许,我需要 Animal 的所有信息。
因为我的 BrickHigh 看不到我的 BrickLow,所以没有像 Animal animal = new Cat(); 这样的东西。可能。
我的第一个想法是在 Cat 中创建一个将 Animal 作为参数的构造函数
public Cat(Animal a) {
super(a);
}
但是我的 Animal 中的构造函数必须是什么 class?好像不行。
But what my constructor must be in my Animal class? It doesn't seem to work.
像这样:
public Animal(Animal other) {
this.field1 = other.field1;
this.field2 = other.field2;
// etc
}
但是,我认为使用对象工厂模式可能会更好;即让你的 DAO class 接受一个参数,它是一个 factory 对象,可以创建 Animal
个实例。当您在使用 BrickLow API 的代码中使用 DAO(来自 BrickHigh)时,您可以使用生成 Cat
个实例而不是 Animal
个实例的工厂实例化 if。
我不确定我是否完全理解你的问题,但如果你想从 BrickHigh 的代码中创建某种动物的实例 class,但不了解 BrickLow,你可以使用工厂或 Class 对象,它们将由 DAO 的一个或多个属性标识。
例如:
public interface AnimalFactory {
boolean canInstanciate(AnimalDAO dao);
Animal instanciate(AnimalDAO dao);
}
您的 BrickHigh 将拥有一组工厂,并提供注册新工厂的机制。
例如:
public enum AnimalFactories implements AnimalFactory {
INSTANCE;
private List<AnimalFactory> factories = new ArrayList<>();
public void registerFactory(AnimalFactory factory) {
factories.add(factory);
}
@Override
public boolean canInstanciate(AnimalDAO dao) {
for (AnimalFactory fac: factories) {
if (fac.canInstanciate(dao)) {
return true;
}
}
return false;
}
@Override
public Animal instanciate(AnimalDAO dao) {
for (AnimalFactory fac: factories) {
if (fac.canInstanciate(dao)) {
return fac.instanciate(dao);
}
}
throw new InstanciationException("No factory for that animal");
}
}