动态接口模式

如何为一个类动态地增加一个接口而不需要修改这个类呢?举个简单的例子:对于书这个对象可能要实现多个接口,例如KeyWords接口用于搜索引擎进行关键字搜索,Digest接口用于显示书的摘要信息,ACL用于控制用户对书的访问权限,Persistent接口用于对象的持久化操作,TranscationResource用于事务控制等等。如果都用BookImpl来完成,可能BookImpl会变得异常复杂。如果我们可以在需要的时候声明对象实现了什么接口,问题就简单了许多,例如我们可以这样定义:
DynamicInterface.define("define BookImpl implement Digest using BookDigest");
定义BookImpl使用BookDigest类实现了Digest接口
当我使用BookManager获得Book对象后,就可以使用它的Digest接口了。例如
Digest digest=(Digest)manager.getBook(...);
System.out.println(digest.getDigest());

我们甚至可以在需要的时候取消定义,如:
DynamicInterface.define("undefine BookImpl implement Digest");

我想听听各位对该模式的看法,以及实现该模式的方案。谢谢。

我想你应该说清楚一点,到底在BookImpl的定义中有没有实现这些接口?

你的类图是什么意思,是表示你类的实现,还是表示你想要达到的
实际效果?

基本上不知道你想说什么。

哎呀,后悔了,应该删掉上面那个帖子的。
可惜这个论坛不能编辑

我想基本上只要jvm支持的话,什么想法都有可能实现。

再问一句,这个动态接口模式是哪里的?
自己想的?

To Matrix,

的确是个好想法, 不知你的bookimpl类是不是一个标识类, 也就是空接口类?

你所说的动态接口想法很好, 但能具体说说如何才能动态呢?

期待中.....

之所以需要动态接口模式,是基于下面的需求:即
同一对象具有无穷多个接口,但我们实现了现在需要的部分接口(将来可能发生变化),以及同一对象在不同状态下需要实现不同的接口(反过来说:同一对象在某些状态下不需要某些接口)。

在JAVA上实现动态接口模式并不是件困难的事情(如果感兴趣我们可以讨论),关键是该模式可能带来什么样的应用呢?请说说你想到的部分。

也许可以考虑用Visitor模式看看


这个类层次必须非常稳定,因为有跨平台的问题。但是它的设计允许你增加新的virtual function,而不必烦劳RTTI。你可以通过增加一个间接层次的办法解决这个问题。请问,Personnel::Accept是什么?”

”嗯,这个...”

“这个类实现了一个模式,可惜这个模式的名字起得不太好,是个PNP,叫Visitor模式。”

[译者注:PNP,Poor-Named Pattern, 没起好名字的模式]

“啊,我刚刚读过Visitor模式。但是那只不过是允许若干对象之间相互迭代访问的模式,不是吗?”

她叹了一口气,“这是流行的错误理解。那个V,我觉得毋宁说是Visitor,还不如说是Virtual更好。这个PNP最重要的用途是允许在不改变类层次的前提下,向已经存在的类层次中增加新的虚函数。首先来看看Personnel及其派生类的Accept实现细节。”她拿起笔写下:
......

这里是参考文章

可不可以从visitor模式,Reflection机制以及Visitable类继承角度去实现呢?

至于应用方面感觉太多了, 尽管模式强调的是对接口编程,但接口也是要根据实际情况变化的. 所以这一动态模式值得思考.

这个坛子的宗旨不就是发现新的有用的模式吗?

怎么这么好的一个贴子回复的人不多呢? 郁闷!

楼主的想法很象AOP,动态启用和注销接口在AOP里都有这样的功能。

AOP如何实现在运行时增减接口呢?
declare parents是需要静态编译的,不是吗?

可以参考一下“装饰模式”吧。

Decorator模式用于丰富对象已知行为的内容。
而DIO模式(动态接口模式)为对象增减不同的行为。

不太明白你下面这句的意思,而且就字面上理解,也不太认同你的意思:
Decorator模式用于丰富对象已知行为的内容。
而DIO模式(动态接口模式)为对象增减不同的行为。


我觉得可以借鉴装饰模式的实现方式。
你所说的动态接口模式中:不改变BookImpl类,装饰模式的实现可以满足
这点
至于动态的接口,难道你的意思是在运行期动态创建一个接口?由谁添加
这段动态的创建呢?(如果不是这样那么装饰模式也可以解决动态实现不
同接口功能的问题)而不是象一般的接口定义一样,先写java文件,运行
编译?
如果动态创建接口,效率是不是会大大降低,有其要运用的场景吗?
想你可能需要把你的想法概念化,最好能按照一般模式的定义说出来。
这样的话,我可能会跳出个人偏执的小圈子。

还是说说我的这种实现吧:


这个实现结合了适配器模式(缺省适配器模式)和装饰模式

在接口Book定义了所有要实现的接口的方法(由于我用together画类图,为了清楚起见把所有的get方法名字都改为out开头)
接下来用类BookMidImpl实现这些方法,这些方法都为空,没有具体的实现动作

类BookImpl即为楼主所定义的那个类,这里没有写具体的逻辑,如书名的获取等等。

接下来的类Digest,可以具体实现outDigest方法,通过Digest(Book book1)获取该方法处理的Book对象(也即被装饰对象)。

同理实现类ACLCode和类KeyWords

在处理客户端代码的时候有如下操作(也即楼主所定义的BookManager类里的操作):

Book theBook = new BookImpl();

//如果要进行摘要操作,则
Book digestBook = new Digest(theBook);
System.out.println(digestBook.outDigest);

当进行完相应的操作之后,会有gc来完成对对象的回收。

你的Book接口定义正是问题的所在,其outDigest,outKeyWord,outACLCode方法是事先需要确定的(在编译前),因此我说Decorator模式要求"已知行为",其次,你的BookMidImpl实现了通用Book行为,Digest实现了具体Book的行为,因此我说它“丰富了行为的内容”。
DIO(Dynamic Interface Object)模式的意图在于解决下面两个不同层次的问题:
1.某个对象所能实现的接口在需求不明朗的情况下是不能确定的,根据需求在为对象增加新接口定义时,不会影响对象的其它接口定义(静态需求)。例如我现在又想使书能够被放到购物车中,因此我定义一个接口ShoppingItem,并定义BookShoppingItem实现ShoppingItem接口,并将其加入到Book的接口定义当中。

2.在对象生命周期的不同阶段需要实现不同的接口(运行时)。一本在货架上的书,没有必要让它具有ShoppingItem的能力,而一旦用户选择购买,才让这本书实现ShoppingItem接口,从而使它能够进入购物车系统。

顺便说一下,你不觉得在Digest对象中能访问outACLCode方法是一件很不自然的事情吗?