我正在思考这个问题:我想要做的是[希望不要重新发明轮子]并且带来了[Android] Java事件机制,它允许子类预先定义一组任意“功能”使用getter和setter来激活单个回调。
我认为我在这里融合了Command,Visitor,Decorator,Facade和Observer模式的一些组合,并且在此过程中让自己感到困惑。 我已经编程超过20年了,但我觉得这个相当简单的问题是一个n00b! :(
我搜索了SO的编译器错误并阅读了许多结果,但我仍然没有找到适合我的解决方案。 (How to make a Java class that implements one interface with two generic types?似乎是我找到的最相关的一个,但我也希望在设置时一般性地获取值和触发事件回调。)
首先,让以下大部分有效的代码说明一切......
interface IFeature
{
}
interface IFeatureCallbacks<T extends IFeature>
{
boolean onChanged(Feature<T> c);
}
public static class Feature<T extends IFeature>
{
private Set<IFeatureCallbacks<T>> listeners = new LinkedHashSet<>();
public void addListener(IFeatureCallbacks<T> listener)
{
listeners.add(listener);
}
public void removeListener(IFeatureCallbacks<T> listener)
{
listeners.remove(listener);
}
protected void onChanged()
{
for (IFeatureCallbacks<T> listener : listeners)
{
listener.onChanged(this);
}
}
}
//
interface IFeatureA
extends IFeature
{
int getA();
}
interface IFeatureACallbacks
extends IFeatureCallbacks<IFeatureA>
{
}
public static class FeatureA
extends Feature<IFeatureA>
implements IFeatureA
{
private int a;
public void setA(int value)
{
a = value;
onChanged();
}
@Override
public int getA()
{
return a;
}
}
//
interface IFeatureB
extends IFeature
{
boolean getB();
}
interface IFeatureBCallbacks
extends IFeatureCallbacks<IFeatureB>
{
}
public static class FeatureB
extends Feature<IFeatureB>
implements IFeatureB
{
private boolean b;
public void setB(boolean value)
{
b = value;
onChanged();
}
@Override
public boolean getB()
{
return b;
}
}
//
interface IDeviceWithFeatureA
extends IFeatureA
{
}
interface IDeviceWithFeatureACallbacks
extends IFeatureACallbacks
{
}
public static class DeviceWithFeatureA
extends Feature<IDeviceWithFeatureA>
implements IDeviceWithFeatureA
{
FeatureA a = new FeatureA();
public void addListener(IDeviceWithFeatureACallbacks listener)
{
a.addListener(listener);
}
public void setA(int value)
{
a.setA(value);
}
@Override
public int getA()
{
return a.getA();
}
}
//
interface IDeviceWithFeatureB
extends IFeatureB
{
}
interface IDeviceWithFeatureBCallbacks
extends IFeatureBCallbacks
{
}
public static class DeviceWithFeatureAB
extends Feature<IDeviceWithFeatureB>
implements IDeviceWithFeatureB
{
FeatureB b = new FeatureB();
public void addListener(IDeviceWithFeatureBCallbacks listener)
{
b.addListener(listener);
}
public void setB(boolean value)
{
b.setB(value);
}
@Override
public boolean getB()
{
return b.getB();
}
}
上面的代码似乎工作得很好,虽然它有些闻起来有点味道。 问题是当我尝试这样做时:
interface IDeviceWithFeatureAAndFeatureB
extends IFeatureA, IFeatureB
{
}
/*
Compiler error:
'IFeatureCallbacks' cannot be inherited with different type arguments 'IFeatureA' and 'IFeatureB'
*/
interface IDeviceWithFeatureAAndFeatureBCallbacks
extends IFeatureACallbacks, IFeatureBCallbacks
{
}
public static class DeviceWithFeatureAB
extends Feature<IDeviceWithFeatureAAndFeatureB>
implements IDeviceWithFeatureAAndFeatureB
{
FeatureA a = new FeatureA();
FeatureB b = new FeatureB();
public void addListener(IDeviceWithFeatureAAndFeatureBCallbacks listener)
{
a.addListener(listener);
b.addListener(listener);
}
public void setA(int value)
{
a.setA(value);
}
@Override
public int getA()
{
return a.getA();
}
public void setB(boolean value)
{
b.setB(value);
}
@Override
public boolean getB()
{
return b.getB();
}
}
我没有兴趣试图弄清楚如何制作我想要编译的内容,而且我更感兴趣的是我对模式的滥用是基础的,所以我可以重写它是既简单又编译。
答案 0 :(得分:0)
你正在滥用OOP的基本“模式” - 继承。谚语是“赞成作文而不是继承”。用“包含”来思考,而不是“是-a”。
以动物园为例。动物园只是一群动物,对吧?很自然地,我们可能希望将Zoo声明为Set<Animal>
的子类型。甚至可能有class Zoo extends HashSet<Animal>
。
然而,这可能是错误的设计。动物园实际上是很多东西。它包含一组动物,当然;但它也包含一组人(作为工人,而不是展品(尽管......))。
更好class Zoo
Set<Animal> animals(){ ... }
Set<Person> workers(){ ... }
我们需要将动物园视为一组动物,只需使用zoo.animals()
;将其视为类型转换或投影。我们这里不需要继承。
在您的设计中,您的类型太多;更糟糕的是,类型关系太多了。您似乎只需要一个读取/写入T
值的泛型类,并包含T
class Feature<T>
T value;
// getter
// setter
Set<ChangeListener<T>> listeners;
interface ChangeListener<T>
void onChange(T oldValue, T newValue)
设备包含许多功能
class SomeDevice
Feature<Integer> featureA = new Feature<>();
Feature<Boolean> featureB = new Feature<>();
就是这样。您可以通过操作featureA
。