策略模式中的上下文类


10

我试图理解策略模式并问自己:上下文类是必须具备的,还是可以在不损害模式目的的情况下将其省略?

我给我的印象是我需要某种开关来读取不同类型的文件,但不想仅仅破解某些东西,以后再进行重构(尽管当然总是可以对代码进行重构,但是想法是:尝试事先在设计中尽可能地聪明...):

在此处输入图片说明

图片取自Wikimedia

客户可以直接委派给Strategy界面吗?或者我只是想了解有关上下文类的内容?

interface Reader {
    // read information from file and fill data list field of Client
    readFile();
}
class ExcelReader implements Reader{ /* */ }
class PdfReader implements Reader{ /* */}

class Client{
    // strategic choice
    Reader r;

    // data list field
    List<Data> data;

    // Client Constructor
    public Client(){
        if(<file ends in .xls>)
            r = new ExcelReader();
        else
            r = new PdfReader();
        r.readFile();
    }
}

因此,上面描绘的是上下文类丢失。代码是否遵守策略模式?


1
作为另一个有趣/重要的观点,我想提醒您注意,功能语言中的类型类的概念“简单地”是种类为en.wikipedia.org/wiki/Kind_(type_theory)的策略模式。两者只是临时多态性的一种实现机制。
AndreasScheinert

这(或多或少)与Java 8 Project Lambda有关吗?Wikipedia的文章对我来说太密集了,无法立即理解,但是如果这些是有效使用Java即将出现的功能(或一般而言编程)的理论背景的一部分,我将很乐意在其中花费更多的时间。
panny

1
很远,但我会说是的,类型类需要。一种支持更高种类的编程语言。scala和Haskell就是这种情况。我的意思是,(即席)多态性的实现方式有所不同,如果您退后一步,通常可以了解一些有关多态性的见解。
AndreasScheinert

Answers:


13

在您的示例中,代码调用readFile是Client构造函数的一部分。该方法就是您要查找的“上下文”。策略模式从字面上不需要“上下文类”,并且在代码的第一个版本中,策略对象(在您的情况下为“ Reader”)可以仅驻留在局部变量中。尤其是只有一种“策略方法”(“ readFile”)要调用时。

但是,如果您的代码库从一个版本升级到另一个版本,则不太可能会越来越多地调用“战略”方法,并且决定采用哪种策略以及执行“战略方法”的决定将在不同的时间发生。以及代码中的不同位置 因此,您开始重构它们以将逻辑保持在一个地方。这将直接导致实现类似于您的问题图中的实现。


5

当然。模式只是准则。您仍然需要调整和正确应用它们以解决当前的问题。我个人很少允许在运行时设置策略。通常是在建筑上指定或在工厂中批量生产。

虽然也可以说setStrategy是私有的,但我的注射只是使用所示的模式。


这是否意味着可以在不损害模式的情况下忽略所描述的Context类?或者换种说法,当我的客户类所描述的上下文类时可以吗?
panny

6
@panny-我犹豫要回答这个问题,因为它表明您错过了答案的要点,甚至完全错过了答案。策略模式允许您通过在界面后面提供不同的具体实现来改变行为。这是一个概念,而不是一个公式
Telastyn
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.