如何推广上下文类?

时间:2012-07-14 10:51:52

标签: java oop design-patterns

我正在创建某种过滤系统,它基于不同的元素接受/产生相同类型的“上下文”。

例如,如下所示,可以对流程建模:

{generate_numbers(1..100)} --> {is_prime} --> {output}

上下文可以是一个简单的'HashMap'。 generate_numbers创建上下文,其中'x'设置为某个数字is_prime使用此上下文,查找'x'并相应地放置'prime'= true / false。

专业人士:

  • 灵活性(可以进一步扩展(HashMap))

缺点:

  • 无类型值在整个地方投放

这也是一种可行的方法,可以将所有内容声明为“上下文”中的字段,但这样可以牺牲容易扩展性(我可以忍受)


但是......情况有点复杂,因为这些transformator元素遍布整个应用程序的包:

{generate_numbers(1..100)} --> {is_prime} --> {calc(f_1)} --> {output}
{--------------- pkg_A ------------------} | {--------- pkg_B -------}

所以有些部分pkg_A可以工作,然后有些地方pkg_B部分处理上下文 - >这就是为什么我想混合两种方法


我想出了以下想法:

选项1

  • 说我已经命名了包含上下文E的基本HashMap
  • 创建E的子类,其中某些条目在字段中显示,其中getter / setter为availibe
  • 在每个处理函数中将传入的参数转换为所需的类类型

亲:

  • 相对容易实施

CON:

  • 应该使用字段
  • 同步HashMap内容
  • 访问某个值的方法不止一种可能会导致混淆

选项2

  • 创建一些执行投射的“工具”类

亲:

  • 每个函数的子类都没有运行时强制转换

CON:

  • 访问始终转换为HashMap访问
  • 每次阅读字段时都会有一个转换

选项3

我完全错了,我应该以不同的方式解决问题

更新:

有“如何推广上下文类?”我的意思是如何创建一个相对方便的上下文,它将承载应用程序正在处理的所有混乱的东西,因为在当前的工作流程中,这些信息被控制逻辑模糊了

2 个答案:

答案 0 :(得分:1)

我相信你会转到Scala:D。
Scala是一种具有OOP设计的函数式语言,它在Java虚拟机上运行,​​支持您刚刚提到的内容并具有强大的模式匹配引擎。

另一种方式可能涉及在Java中模拟功能范例,这几天前实际上已经超出了我的想法,但我做了太多工作而忘了它:D。

基本上,我在想的是你应该有一个界面

public interface Functionalizable {
    public void map(Function f);
}

其中Function也是一个可以扩展以编写自己的函数的接口。然后,一个这样的例子(可能不好,但那些是我在火车上旅行时的想法)可能是这样的:

public class FunctionList extends ArrayList implements Functionalizable {
    public void map(Function f) {
        // iterate over the elements of a list
        // applying the function f on each of them
    }
}

你可以这样称呼它:

List l = new FunctionList();
// add some data
l.map(
    new Function() {
        // some function
    }
)

当然,这些代码实际上都不是可编译的,而只是我所思考的内容。是的,在Java中引入功能范例是一种痛苦,所以再一次,我最好的建议是坚持使用真正的函数式语言,比如Scala。 :d

答案 1 :(得分:0)

尝试传递元数据会让维护成为头痛的问题。相反,您需要functional programming解决方案,但特别是您希望处理list comprehensions - 在您的示例中为generate_numbers函数。虽然你可以通过自己滚动来实现这一点 - 正如@Lopina建议的那样 - 通过创建一组function objects我认为更好的路径是使用现有的Java库。

特别是Google Guava有许多以这种方式对付Java集合的工具 - functional idioms就是你想要的。你必须编写自己的函数 - 在这种情况下是Guava Predicates - 在Guava的框架内使用,但我认为它为你描述的问题提供了正确的工具和抽象层次。 I found this question's answer particularly helpful understanding predicates

示例Guava代码

import java.util.Arrays;

import com.google.common.base.Predicate;
import com.google.common.collect.*;

public class PrimeFinder {
    static Predicate<Integer> isPrimeToTenThousand = new Predicate<Integer>() {
        private boolean[] primes = new boolean[10000];
        {
            // prime detection algorithm from
            // http://www.mkyong.com/java/how-to-determine-a-prime-number-in-java/
            // will contain true or false values for the first 10,000 integers
            Arrays.fill(primes, true); // assume all integers are prime.
            primes[0] = primes[1] = false; // we know 0 and 1 are not prime.
            for (int i = 2; i < primes.length; i++) {
                // if the number is prime,
                // then go through all its multiples and make their values false.
                if (!primes[i]) continue;
                for (int j = 2; i * j < primes.length; j++)
                    primes[i * j] = false;
            }
        }

        @Override
        public boolean apply(Integer number) {
            return primes[number];
        }
    };

    public static void main(String args[]) {
        ImmutableSortedSet<Integer> positiveIntegersTo100 = Ranges.open(1, 100).asSet(DiscreteDomains.integers());
        Iterable<Integer> primeNumbersTo100 = Iterables.filter(positiveIntegersTo100, isPrimeToTenThousand);
        // output: [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
        System.out.println(primeNumbersTo100);
    }
}

最后,关于如何模拟Python list comprehensions in Java的其他问题及其答案应该会有所帮助。