在Java中实现Mixin?[关闭]

2021/01/17 10:11 · java ·  · 0评论

使用Java 6,如何实现mixin这在Ruby中非常容易并且可能。我如何在Java中获得相似之处?

您可以为此使用CGLIBMixin能够从多个接口/对象委托生成动态类:

static Mixin    create(java.lang.Class[] interfaces,
                        java.lang.Object[] delegates)
static Mixin    create(java.lang.Object[] delegates)
static Mixin    createBean(java.lang.Object[] beans) 

默认方法

我知道Java 6的问题,但是在Java 8中,我们将有一个相当不错的选择:默认方法

我们将能够添加接口方法的“默认”实现,因此我们可以添加新方法而不会破坏实现该接口的每个类。

只要您的mixin不需要状态,就可以在界面中编写代码。然后,您的类可以实现所需的任意数量的接口,并且可以实现繁荣发展,您有了mixins

这是对系统的滥用吗?一点点,但是由于没有状态,它不会陷入任何多重继承问题。

当然,这也是此方法的最大缺点。

我想说的只是使用对象合成。每次您想使用新功能时,都将另一个对象作为成员组成一个类。如果要使所有混合类都具有相同的类型,则可以将数组用作成员对象,其中每个元素与所有其他元素组成,然后可以分派到特定元素。

由于Java仅支持单一继承,所以这是不可能的。看看WP:Mixin

编辑:由于对接口的评论:关于mixin的很酷的事情是您可以在不编写组合代码的情况下组合它们。使用接口,您必须自己实现组合的功能(可以扩展的一类除外)!

最简单的方法是使用静态导入。它允许代码重用,看起来像是类的一部分,但实际上是在其他地方定义的。

优点:

  • 真的很容易
  • 您可以“混合”任意多的静态导入

缺点:

  • 静态方法将无法访问“ this”,因此您必须手动将其传递
  • 无状态:您的静态方法不能拥有自己的实例字段。他们只能定义自己的静态字段,然后任何调用static方法的对象都可以共享它们。
  • 无法在客户端类上定义公共方法(将代码混入其中的一种)。在Ruby中,导入mixin实际上会将那些公共方法定义为类上的公共方法。在Java中,在这种情况下,继承是一种更好的解决方案(假设您不需要扩展多个类)

例:

import static my.package.MyHelperUtility.methodDefinedInAnotherClass;

public class MyNormalCode {
    public void example() {
        methodDefinedInAnotherClass();
    }
}

从某种意义上说,Ruby混入等效于Java抽象类,不,您不能在Java中实现混入。您可以通过使用接口来接近,从而在混入中完全不定义任何代码,但是您不能直接实现与Ruby混入中相同的行为。

更新:Qi4j现在是Apache Polygene,https://polygene.apache.org

Qi4j对Mixins的定义可能非常独特,因为它不是从基类开始的。走向极端,就出现了关于如何构建应用程序的全新范式,我们称之为面向复合程序设计。Composite是等效的“对象”,不仅将Mixins连接在一起,而且还包括约束(验证),关注点(围绕建议)和SideEffects(不能改变方法结果)。

因此,我认为Qi4j有一个非常强烈的Mixin故事可以讲。Mixins可以是“类型化”或“泛型”的,它们可以是公共的(可在组合外部访问)或纯私有的(在组合内部)。Qi4j严格定义了什么是属性,并具有内置的持久性,不会将存储实现泄漏到您的域中(caveat; Qi4j泄漏到您的域中)。并且一旦持久性实体进入画面,就还需要对关联进行严格定义(并包含在Qi4j中)。

有关完整的概述,请参见http://www.qi4j.org/state-modeling.html

在Qi4j中,仅Mixins具有状态。约束/问题/ SideEffects不能具有状态(如果存在,则需要引用私有mixin)。

要在Qi4j中定义复合,可以在类型本身上进行结构化,也可以在创建运行时模型时在引导时进行。

结构上

@Mixins({PetrolEngfineMixin.class, FourWheelsMixin.class})
public interface Car extends HasEngine, HasWheels, EntityComposite
{}

在启动时;

public interface Car
{}

public class CarModuleAssembler implements Assembler { public void assemble( ModuleAssembly module ) { module.entities( Car.class ) .withMixins( PetronEngineMixin.class, FourWheelsMixin.class ); } }

然而,这只是在Qi4j的功能表面上。

刚刚遇到:https ://blog.berniesumption.com/software/mixins-for-java/(更新了错误链接)

看看http://code.google.com/p/javadude/wiki/AnnotationsMixinExample

它使用了我创建的一组注释。

注意:我正在对批注进行重大更新,其中包括一些API损坏。我计划在未来几周内发布一个新版本。

用Java伪造mixins:http : //jonaquino.blogspot.com/2005/07/java-mixin-pattern-or-faking-multiple.html

您现在可以使用AspectJ ITD与Java(即5,6,7)一起使用MixinsJava 8当然会通过其防御者方法添加更好的功能。

不确定要从mixin中找到什么功能,但是可以使用装饰器模式完成很多功能。

http://en.wikipedia.org/wiki/Decorator_pattern#Java

是的,在Java中实现mixins方法的最简单,最方便的方法是-从某些包含静态方法的类中使用静态导入。

我正在探索为Java 7提供此功能。我的第一步是使用本文中显示的示例:

它应该与Java 6一起使用,类似于上面的其他注入选项。根据我在C#和Ruby中使用Mixins的经验,您应该致力于实现mixins,而不仅仅是模拟或伪造它。

另一种模型是与Jackson一起使用的模型

如果可以使用新的Java 8版本,请说您处于预发布模式,这可能会有所帮助。

使用虚拟扩展方法,这需要“ Be -a ”混合。因此,在我看来,现在还处于初期,我更喜欢第一个链接提供的更简洁的方法(或类似方法)。

在面向方面的编程运动中,术语“ Mixin”是否不等同于Java术语“ aspect”?AspectJ可能值得一看。

一个老问题的答案。

我看了一下Apache Zest。也许只是我一个人,但我发现这些示例有点麻烦。而且我不太明白这一点。另一种选择是对象团队。

但是我建议您可以看一下这个仓库:

https://github.com/Mashashi/javaroles/

它可能会部分涵盖您要执行的操作。看起来很简单。

这是一个例子:

定义角色的接口:

public interface Human {
String hello(); 
String die(String age);  
String eat();
String dance();
}

public interface Monkey {String hello(); String eat();}

定义刚性型AnimalRoles ...

public class AnimalRoles implements Human, Monkey{

public static final String HALLO = "Default hallo";
public static final String DIE = "Default they kill me...";
public static final String EAT = "Default eat...";

@ObjectForRole public Human human;

@ObjectForRole public Monkey monkey;

public AnimalRoles(Human human, Monkey monkey){
    this.human = human;
    this.monkey = monkey;
    if(this.human!=null){
        ((Portuguese)this.human).core = this;
    }
}

@Override
public String hello() {
    return HALLO;
}

@Override
public String die(String age) {
    return DIE+age;
}

@Override
@TurnOffRole
public String eat() {
    return EAT;
}

@Override
public String dance() {
    return "Just dance";
}

public String notInRole(){
    return "Oh oh";
}
}

定义班级角色Bo黑猩猩...

public class Bonobo implements Monkey{
public Bonobo() {}

@Override
public String hello(){
    return "Ugauga";
}

@Override
public String eat() {
    return "Nhamnham";
}

}

定义班级角色葡萄牙语...

@RoleObject(types = { AnimalRoles.class })
public class Portuguese implements Human{

public static final String HALLO = "Hey there";
public static final String DIE = "They killed me";
public static final String EAT = "Eating boiled pork now";

public AnimalRoles core;

public Portuguese() {}

@Override
public String hello() {
    return HALLO;
}

@Override
public String die(String age) {
    return DIE+age;
}

@Override
public String eat() {
    return EAT;
}

@Override
public String dance() {
    return core.dance()+" modified!";
}

}

正在运行测试...

new RoleRegisterComposition().registerRools();
AnimalRoles a = new AnimalRoles(new Portuguese(), new Bonobo());
System.out.println(a.hello());
System.out.println(a.dance());

会打印...

"Hey there"
"Dance modified!"

请看一下我的小型演示项目,了解如何使用cglib在纯Java中创建mixins。主要只是对代理生成器的调用。这是盟友。该示例包含一个junit测试用例,演示了如何实例化代理。

https://github.com/literadix/JavaMixins

本文地址:http://java.askforanswer.com/zaijavazhongshixianmixinguanbi.html
文章标签: ,  
版权声明:本文为原创文章,版权归 admin 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!