是否可以使函数 return 为真、假或对象列表?

it it possible to make a function return true, false or a list of objects?

项目简介

我正在开发一个存储如下数据的程序:

- 事实: 属性列表(或仅一个)和 true/false 值(称为 "truth" 值)的组合。例如:

parent('John' , 'John jr') , true

其中 John 的 属性 是 John jr 的父级是正确的。我用来存储事实的代码:

public class Fact implements Serializable{
    private boolean truth;
    private ArrayList<Property> properties;

    public Fact(){
        truth = false;
        properties = new ArrayList<Property>();
    }

    //more constructors, getters, setters and other functions  which are not important for this question...

- 规则: 用于从事实中获取信息。他们的工作原理是让一个事实(我称之为派生事实)暗示另一个事实(我称之为隐含事实):

parent('x' , 'y') => child('y', 'x')

这意味着通过将规则应用于上述事实,我们可以确定 John jrJohn 的子代。

规则属性:

负面情绪:

规则可以是"positive"(如果导数为真,蕴含式为真):

parent('x' , 'y') => child('y', 'x')

或"negative"(如果导数为真,蕴涵式为假):

parent('x' , 'y') => not child('y', 'x')

逆反性:

它们也可以是"reversive"(如果导数为假,蕴涵式是true/false):

not parent('x' , 'y') => child('y', 'x')

或(如果也是负数):

not parent('x' , 'y') => not child('y', 'x')

或"non-reversive"(如果导数为假,蕴涵式未知):

not parent('x' , 'y') => (unknown)

我用来存储规则的代码如下所示:

public class Rule implements Serializable{
    private Property derivative;
    private Property impliant;
    private boolean negative;
    private boolean reversive;

    public Rule(Property derivative, Property impliant) throws InvalidPropertyException{
        if(!this.validRuleProperty(derivative) || !this.validRuleProperty(impliant))
            throw new InvalidPropertyException("One or more properties are invalid");
        this.derivative = derivative;
        this.impliant = impliant;
        negative = false;
        reversive = false;
    }

    //again more constructors, getters, setters and other functions  which are not important for this question...

信息集

事实和规则存储在 InformationSets 中,它将这些事实和规则捆绑在一起,因此用户可以 "question" 里面的信息。这可以通过两种不同的方式完成:

1.Fact 检查: 检查一个事实是否为真。给定一个事实,这将根据该事实的真值 return 为真或为假。例如用户可以问:

parent('John' , 'John jr')?

程序将 return true 同时:

parent('John jr' , 'John jr')?

将returnfalse

问号表示用户想问 'fact check' 问题。

1.Impliant 检查: 对于给定的事实(称为问题事实),return 每个规则的事实列表可以应用于问题事实。例如:

parent('John' , 'John jr')=>

这将 return:

child('John jr', 'John')

箭头表示用户想问 'Impliant check' 问题。

问题编码如下:

public class Question {
    Fact questionFact;
    String operator;

    public Question(Fact questionFact, String operator) throws InvalidOperatorException{
        if(!validOperator(operator))
            throw new InvalidOperatorException("The operator is invalid");
        this.questionFact = questionFact;
        this.operator = operator;
    }

Operator 字段中,我根据用户想问的问题类型存储 ?=>

问题

我目前正处于需要编写向给定信息集提问的方法的阶段。因此,我需要一种方法来给出问题和信息集 returns truefalse 或事实列表。据我所知,这在 java 中是不可能的。

我尝试为每个问题制作一个单独的方法,这有点管用,但这也会导致问题,因为我希望能够写出如下内容:

informationSet.ask(question);

并让 ask() 方法处理这两种类型的问题,这样我就不必检查用户在用户界面代码中问的是哪种问题,而是让后端程序解决了。

执行此操作的好方法是什么?

因此,最明显的解决方案是实施您的自定义响应 class。


另一个想法是考虑使用 Either from Vavr,这是一种旨在专门保存(双关语!)类型 A 或 B 的值的解决方案。

所以,它可能看起来像:

Either<Boolean, List<Fact>> result = foo();

然后,您可以利用 FP Optional/Stream API-like 来操纵结果:

如果要访问左侧:

result.left()
  .map(...)
  .filter(...)
  // ...

如果你想访问右侧:

result.right()
  .map(...)
  .filter(...)
  // ...

除了 Grzegorz 的命题外,您还应该记住 Java 是强类型的。这并不意味着你不能 return 一个 Either 对象;根据定义,它可以容纳不同的 类 (类型)。

但是在Java逻辑中,我认为最好在更窄的粒度上实现更多指定的方法(这在面向对象设计中有很多好处,比如共享代码和可伸缩性)。

所以我建议提出两种方法,一种是Boolean,另一种是array result。然后在调用函数中进行条件测试。