根据Java中对象的类型选择实现

根据Java中对象的类型选择实现,java,design-patterns,genetic-algorithm,strategy-pattern,visitor-pattern,Java,Design Patterns,Genetic Algorithm,Strategy Pattern,Visitor Pattern,我有一个父母类型 public class IObject{} 并且可以有很多子类(将来甚至是新的子类) 然后根据这些对象的类型,我必须执行不同的操作 public class StrategyForObject1(){void do{}} public class StrategyForObject2(){void do{}} public class StrategyForObject3(){void do{}} ... public class StrategyForObjectN(){

我有一个父母类型

public class IObject{}
并且可以有很多子类(将来甚至是新的子类)

然后根据这些对象的类型,我必须执行不同的操作

public class StrategyForObject1(){void do{}}
public class StrategyForObject2(){void do{}}
public class StrategyForObject3(){void do{}}
...
public class StrategyForObjectN(){void do{}}
所以我想从我的上下文类:

   public Conext {
    IObject o;

    public void setObject(IObject o) {
        this.o = o;
    }

    void logic() {
        if (o instanceOf Object1) {
            new StrategyForObject1().do();
        }
        if (o instanceOf Object2) {
            new StrategyForObject2().do();
        }
        if (o instanceOf Object3) {
            new StrategyForObject3().do();
        }
        ...
        if (o instanceOf ObjectN) {
            new StrategyForObjectN().do();
        }
    }
}
因此,根据类型来执行不同的算法,但是如果我需要添加
ioobject
的新子类,只是为了添加新的
StrategyForObject**N**
类,而不是为了更改
Conext
类,那么我希望像在Strategy模式中一样具有可扩展性。 在策略模式中,我们必须指定策略,但这里我们必须做相反的事情:根据对象的类型选择策略。如何以最佳方式在Java中实现这一点

编辑: 无法更改
IObject
以添加其他方法。
我必须将逻辑与数据分开,因此不希望在
Object1
类中添加逻辑的实现。

首先,您的
ioobject
类应该是抽象的,因为它只能由其他类扩展。然后可以在其中声明一个方法,该方法必须由继承自该方法的类重写,如下所示:

public abstract class IObject {
    abstract void do();
}
interface IObjectVisitor {
    void visit(IObject1 obj1);
    void visit(IObject2 obj2);
    ...
    void visit(IObjectN objN);
}    
interface IObjectVisitable {
    void accept(IObjectVisitor visitor);
}
public abstract class IObject implements IObjectVisitable {
   ...
}
public class IObject1 extends IObject {
    public void accept(IObjectVisitor visitor) {
        visitor.visit(this);
    }
}
public class IObject2 extends IObject {
    public void accept(IObjectVisitor visitor) {
        visitor.visit(this);
    }
}
...
public class IObjectN extends IObject {
    public void accept(IObjectVisitor visitor) {
        visitor.visit(this);
    }
}
public class SomeLogicIObjectVisitor implements IObjectVisitor {
    void visit(IObject1 obj1) {
        //something with obj1
    }
    void visit(IObject2 obj2) {
        //something with obj2
    }
    ...
    void visit(IObjectN objN) {
        //something with objN
    }
}
public void someLogic(IObject obj) {
    SomeLogicIObjectVisitor visitor = new SomeLogicIObjectVisitor():
    visitor.visit(obj);
}
public void someLogic2(IObject obj) {
    Logic2IObjectVisitor visitor = new Logic2IObjectVisitor():
    visitor.visit(obj);
}
然后,实现该方法的所有类都必须使用自定义逻辑重写该方法:

public class Object1 extends IObject {
  @Override
  void do() {
    //custom logic
  }
}
换句话说,您应该将
do()
放入
Object1
中,而不是
StrategyForObject1

此结构允许您对类型为
IObject
的泛型对象调用do(),因为
IObject
的所有子对象都将实现
do()
方法。因此,在逻辑方法中,您可以这样做:

void logic(){
 o.do();
}

IObject
可以有一个抽象方法,
do()

然后上下文的
logic()
方法只调用
o.do()


这是多态性的一个经典示例。

看看访问者模式。我想这正是你要找的

编辑:澄清:

import java.util.Arrays;
import java.util.List;

public class Test {
    public static abstract class IObject {
        public abstract void doSomeWork(StrategyVisitor strat);
    }

    public static class Object1 extends IObject {
        @Override
        public void doSomeWork(StrategyVisitor strat) {
            strat.doWork(this);
        }
    }

    public static class Object2 extends IObject {
        @Override
        public void doSomeWork(StrategyVisitor strat) {
            strat.doWork(this);
        }
    }

    public static class Object3 extends IObject {
        @Override
        public void doSomeWork(StrategyVisitor strat) {
            strat.doWork(this);
        }
    }

    public static interface StrategyVisitor {
        void doWork(Object1 o);

        void doWork(Object2 o);

        void doWork(Object3 o);
    }

    public static void main(String[] args) {
        List<IObject> objs = Arrays.asList(new Object1(), new Object2(), new Object3());

        StrategyVisitor visitor = new StrategyVisitor() {
            @Override
            public void doWork(Object1 o) {
                System.out.println("Object1");
            }

            @Override
            public void doWork(Object2 o) {
                System.out.println("Object2");
            }

            @Override
            public void doWork(Object3 o) {
                System.out.println("Object3");
            }
        };

        objs.stream().forEach(o -> o.doSomeWork(visitor));
    }
}
导入java.util.array;
导入java.util.List;
公开课考试{
公共静态抽象类IOObject{
公共抽象无效文件管理工作(战略);
}
公共静态类Object1扩展了IOObject{
@凌驾
公共无效文件管理(策略){
层道尔克(本);
}
}
公共静态类Object2扩展了IOObject{
@凌驾
公共无效文件管理(策略){
层道尔克(本);
}
}
公共静态类Object3扩展了IOObject{
@凌驾
公共无效文件管理(策略){
层道尔克(本);
}
}
公共静态接口策略{
无效销钉(目标1 o);
无效销钉(目标2 o);
无效销钉(目标3 o);
}
公共静态void main(字符串[]args){
List objs=Arrays.asList(new Object1(),new Object2(),new Object3());
StrategyVisitor=新StrategyVisitor(){
@凌驾
公共无效工作(对象1 o){
System.out.println(“Object1”);
}
@凌驾
公共无效工作(对象2 o){
System.out.println(“Object2”);
}
@凌驾
公共无效工作(对象3 o){
System.out.println(“Object3”);
}
};
objs.stream().forEach(o->o.doSomeWork(visitor));
}
}

(请参阅)

我认为您需要实现访问者模式。基本上,对于你所拥有的,它看起来是这样的:

public abstract class IObject {
    abstract void do();
}
interface IObjectVisitor {
    void visit(IObject1 obj1);
    void visit(IObject2 obj2);
    ...
    void visit(IObjectN objN);
}    
interface IObjectVisitable {
    void accept(IObjectVisitor visitor);
}
public abstract class IObject implements IObjectVisitable {
   ...
}
public class IObject1 extends IObject {
    public void accept(IObjectVisitor visitor) {
        visitor.visit(this);
    }
}
public class IObject2 extends IObject {
    public void accept(IObjectVisitor visitor) {
        visitor.visit(this);
    }
}
...
public class IObjectN extends IObject {
    public void accept(IObjectVisitor visitor) {
        visitor.visit(this);
    }
}
public class SomeLogicIObjectVisitor implements IObjectVisitor {
    void visit(IObject1 obj1) {
        //something with obj1
    }
    void visit(IObject2 obj2) {
        //something with obj2
    }
    ...
    void visit(IObjectN objN) {
        //something with objN
    }
}
public void someLogic(IObject obj) {
    SomeLogicIObjectVisitor visitor = new SomeLogicIObjectVisitor():
    visitor.visit(obj);
}
public void someLogic2(IObject obj) {
    Logic2IObjectVisitor visitor = new Logic2IObjectVisitor():
    visitor.visit(obj);
}
那么您就没有一些逻辑可以应用于某些IOObject,比如:

public abstract class IObject {
    abstract void do();
}
interface IObjectVisitor {
    void visit(IObject1 obj1);
    void visit(IObject2 obj2);
    ...
    void visit(IObjectN objN);
}    
interface IObjectVisitable {
    void accept(IObjectVisitor visitor);
}
public abstract class IObject implements IObjectVisitable {
   ...
}
public class IObject1 extends IObject {
    public void accept(IObjectVisitor visitor) {
        visitor.visit(this);
    }
}
public class IObject2 extends IObject {
    public void accept(IObjectVisitor visitor) {
        visitor.visit(this);
    }
}
...
public class IObjectN extends IObject {
    public void accept(IObjectVisitor visitor) {
        visitor.visit(this);
    }
}
public class SomeLogicIObjectVisitor implements IObjectVisitor {
    void visit(IObject1 obj1) {
        //something with obj1
    }
    void visit(IObject2 obj2) {
        //something with obj2
    }
    ...
    void visit(IObjectN objN) {
        //something with objN
    }
}
public void someLogic(IObject obj) {
    SomeLogicIObjectVisitor visitor = new SomeLogicIObjectVisitor():
    visitor.visit(obj);
}
public void someLogic2(IObject obj) {
    Logic2IObjectVisitor visitor = new Logic2IObjectVisitor():
    visitor.visit(obj);
}
从面向对象的角度来看,这是您可以实现的最佳模式。原因是它允许您使用模块化和可扩展的方法,应用正确的关注点分离。例如,看看@nhouser9提供的答案。定义
抽象void do()时在IOObject中乍一看似乎是可行的,您将在域对象中嵌入业务逻辑,而域对象很可能不属于域对象。此外,如果现在考虑其他逻辑,我们称之为“LogIC2”,现在您除了创建代码>抽象空do2()之外别无选择;在每个IOObject实现上,继续嵌入业务逻辑。使用visitor模式,IOObject实现不会改变,也不会在IOObject中嵌入任何逻辑,只需创建一个新的visitor,
Logic2ObjectVisitor
,并在那里实现每个IOObject实现的逻辑。你会这样称呼它:

public abstract class IObject {
    abstract void do();
}
interface IObjectVisitor {
    void visit(IObject1 obj1);
    void visit(IObject2 obj2);
    ...
    void visit(IObjectN objN);
}    
interface IObjectVisitable {
    void accept(IObjectVisitor visitor);
}
public abstract class IObject implements IObjectVisitable {
   ...
}
public class IObject1 extends IObject {
    public void accept(IObjectVisitor visitor) {
        visitor.visit(this);
    }
}
public class IObject2 extends IObject {
    public void accept(IObjectVisitor visitor) {
        visitor.visit(this);
    }
}
...
public class IObjectN extends IObject {
    public void accept(IObjectVisitor visitor) {
        visitor.visit(this);
    }
}
public class SomeLogicIObjectVisitor implements IObjectVisitor {
    void visit(IObject1 obj1) {
        //something with obj1
    }
    void visit(IObject2 obj2) {
        //something with obj2
    }
    ...
    void visit(IObjectN objN) {
        //something with objN
    }
}
public void someLogic(IObject obj) {
    SomeLogicIObjectVisitor visitor = new SomeLogicIObjectVisitor():
    visitor.visit(obj);
}
public void someLogic2(IObject obj) {
    Logic2IObjectVisitor visitor = new Logic2IObjectVisitor():
    visitor.visit(obj);
}

你只是抄了我的答案,但解释得更少了。@nhouser9不要争吵。你们两个都可以投赞成票:)我的手机打字速度很慢,有时候短一点比较好@nhouser9,你的答案会因为提到(可能还有链接到)“多态性”而有所改进。解释一下什么时候你会使用访问者模式而不是简单的多态性,这对回答会有很大帮助。虽然这是有效的,但对于一个简单的例子来说,它也有它的缺点。我看到两个主要的问题。首先,您必须在对象中嵌入业务逻辑。其次,您只能实现一种逻辑。访问者模式允许您实现模块化和可扩展的approach@Ulises我同意,根据作者的需要,你或我的解决方案可能是最好的。两者都有时间和地点。访客模式的答案得到了我的支持。这篇文章可能对你有用: