2009-12-09 68 views
0

我注意到,在开始设计模式对于初学者来说相当困难。了解设计模式结构需要很多时间。将设计模式应用于练习需要很多时间。同意,如果您不熟悉这些设计模式,您将无法第一次看到各种设计模式之间的差异。如果你的类有合适的名字,这个问题就部分解决了。如果您错过了偶然编写代码的一些规则,或者您在设计模式方面经验不足,那么您也可以打破您实现的设计模式类结构。编译器可以保护你并帮助你实现接口 - 如果你没有实现接口,你不能编译你的应用程序。这是一个很好和安全的方法。如果编译器可以保护你,当你实现设计模式类呢?看,很多编程语言都支持“foreach”语句。如果编程语言可以为工厂,桥梁,代理,纪念品等提供支持?如果它可能是真实的,你可以使用类似下面的申请抽象与具体的工厂模式(我喜欢C#作为伪基本语言;它假定上下文关键字使用):语言集成的设计模式

public abstract factory class AF { 
    public product AP1 GetProduct1(); 
    public product AP2 GetProduct2(); 
}; 

public concrete factory class CF1 : AF { 
    public product CP1 GetProduct1() { ... } 
    public product CP2 GetProduct2() { ... } 
}; 

它认为它可以帮助您了解新的来源并保持应用程序源代码结构的完整性。你怎么看待这件事?

+5

我觉得你完全误解模式是什么样的设计。 – 2009-12-09 10:16:13

回答

5

如果我理解你说的话,你认为新的语言功能,应该克服通常与实现设计模式相关的样板代码的需要。

这已经发生了,这是什么新鲜事。

采取单,例如,最广为人知的模式之一。每个人都知道如何实现它:您声明构造函数private,将该对象的一个​​全局实例保存为static属性,并添加一个public方法来检索它。

它的代码是什么概念很简单不少行。

在Scala中,你不需要任何样板创建一个单例。为了补充class关键字,Scala有一个object关键字,它声明了一个单独的对象:

object MainApp { 
    def main(args: Array[String]) { 
    println("Hello, world!") 
    } 
} 

在运行时会出现一个单一的全球MainApp实例。没有必要使用new来实例化它;事实上,你根本不能使用new MainApp

+0

您仅为单身人士提供了一个样本,这是最简单的模式之一。但无论如何,我看到我对设计模式使用方法只有另一种看法。谢谢。 – 2009-12-09 10:36:14

+0

你能在Scala中使用这种方法做一个懒惰的初始化单例吗? – MHarris 2009-12-09 10:43:42

1

有一种观点认为,语言中设计模式的存在表明语言本身的设计存在弱点,下一代语言应该从上一代常见的设计模式中学习。

例如,请参阅Peter Norvigs famous presentation关于动态语言中不可见的设计模式。实际上,很容易想出已经发生的这个过程的例子 - 正如你所说,foreach循环可以说是嵌入式迭代器,Ruby有一个Singleton mixin可以继承,任何具有multimethods的语言都不需要Visitor模式。 Groovy拥有内置的构建器。

您的工厂的具体示例听起来有点像Noop将依赖注入集成到语言规范中。

当然只有这么远一个类型检查可以去保证(目前)的代码的正确性。将设计模式嵌入语言并不会消除熟悉核心概念的必要性,也不会去思考如何应用这个问题。

你举的例子很有意思,你建议增加几个关键字和规则是(和我没那么熟悉C#)语言加上没有明确的益处。 “factory”关键字告诉类型检查器(或另一个程序员)将“AF”声明为等同于Java接口并且将“product”作为其方法的返回类型时不清楚?

+0

感谢您的回复和介绍。一有足够的空闲时间,我会尽快学习。 “工厂”上下文关键字会将“产品”方法传递到类中。因此,当另一个类从类派生时,编译器可以检查是否所有产品都被正确描述。我发现它与接口方法类似,但据我所知,接口和工厂类有些不同。 – 2009-12-09 10:53:25

0

我认为你是对的东西。但是,在你错过了这一点(在我看来)是你要指定一个设计模式,其中,作为MHarris说,他们往往随着时间的推移变得过时的或过时,它们依赖的语言不是这样的好主意。

我认为那是什么,有可能是一个“复合”的语言,在这里你有两个工件:设计规范语言(耦合到实现语言,不要以为UML)和实现。所以,把你的例子,这是可以做到这样的:

设计规范:

single public Factory 
    methods: 
     T Get[T] 

请注意,如果做到这样,因为设计规范,就是要抽象(不需要指定低在那里,然后)的水平细节,它可以有便于编写规范的结构。要知道,在规范中,如果方法是公有或私有的,设计规范(不包括算法伪代码)只需关注公开可见的行为,而不关注私有实现细节。

实施:可用于

public class ConcreteFactory : Factory { 
    public Product1 GetProduct1() { ... } 
    public Product2 GetProduct2() { ... } 
}; 

下面两种方法:

  1. 编译器可以把设计当作摆设,然后检查是否实现代码是一致的吧。
  2. 编译器或运行时可以提供可以自动生成(如单实现)的实现的一部分,以及将码本身可以假定其独立的,并没有必要重新指定,例如:

    类ConcreteFactory:工厂{

    Product1 GetProduct1 { new ConcreteProduct1 } 
    
        Product2 GetProduct2 { new ConcreteProduct2 } 
    

    }

注意,实现可以忽略更高层次的东西,如知名度的类和方法的可见性,因为这已经在设计级(DRY)指定。如果你问我,这种类型的语言也必须附带一个专门的IDE,以便提供关于类型设计的上下文信息。正如Jeff Atwood所评论的那样,任何新的语言都应该包含专门的IDE。

+0

是的,时间过去了,即使对我来说现在的问题也很老旧,但是谢谢你的回复。 :)关于你称之为复合语言的问题,我对编译时宏有类似的想法,可能会扩展到目标语言。然而,我不确定那些宏可能允许自由语法(这样的宏肯定会使复合语言编译器变得更复杂):在Java中,我有时会错过像'class XDecorator装饰X {...}'的地方'装饰'可以用一个宏来定义,但解析'装饰(X,{...})'比类定义更糟糕。 – 2012-10-07 08:04:10

+0

哈哈,是的,但我想过类似于您的问题,并搜索了“集成设计”或“语言集成设计”,并且您的问题在Google搜索中排名第一,有点不爽吗? – 2012-10-07 14:42:11

+0

是的,我不时尝试谷歌的东西,我一次又一次地到这里。 :)无论如何,谢谢你的评论。 – 2012-10-07 16:51:34