在Ruby中实现的所有设计模式的备忘单?

nev*_*ame 3 ruby design-patterns

我想知道是否有在Ruby中实现的所有设计模式的作弊cheets,这样你就不必重新发明轮子了.

Chu*_*bas 6

本文档提供了来自GoF的一些设计模式的实际实现的很好的例子.

它可能是一个"cheatsheet",但我认为它不是设计模式的银弹参考,因为它们一旦你分析了问题就会出现,并且模式符合你给出的解决方案.不是食谱,而是一个很好的参考.

当然,这是Ruby中的设计模式


Mat*_*ggs 6

设计模式对于组织大量代码非常有用.因为您不需要像在#{verbose_algol_derivitive_language}中那样编写与ruby中相同的代码来执行操作,因此它们没有相同程度的重要性.

你会看到什么用所有的时间是战略和建设者块来实现(制造商的一个例子是在的form_for轨道意见块策略的一个例子是File.open)我真的不能相信的我最后一次见到任何其他人(无论如何都是gof模式)

编辑:回应

你的意思是ruby我们在大多数情况下都不必考虑设计模式?另一个问题,如果我使用Rails,我实际上是否必须考虑设计模式?因为我不知道在哪里使用它们.它们似乎不适合MVC的任何组件.设计模式是否仅适用于构建大量库/框架的人员,例如.Rails,DataMapper,MongoID等,而不是仅使用这些框架/库的其他人?

在大多数情况下,rails会为您做出很多决定,直到您的应用程序达到相当高的复杂程度.即使你正在使用像sinatra这样的东西(它不会为你决定任何东西),你仍然不需要像在(例如)java这样的语言中那样获得那些GoF模式.

这是因为设计模式的重点是瓶装方式,以保持灵活性和可维护性.如果内置于语言中,通常甚至不需要它们.

例如,在java中实现的策略模式看起来有点像这样

//StrategyExample test application

class StrategyExample {

    public static void main(String[] args) {

        Context context;

        // Three contexts following different strategies
        context = new Context(new ConcreteStrategyAdd());
        int resultA = context.executeStrategy(3,4);

        context = new Context(new ConcreteStrategySubtract());
        int resultB = context.executeStrategy(3,4);

        context = new Context(new ConcreteStrategyMultiply());
        int resultC = context.executeStrategy(3,4);

    }

}

// The classes that implement a concrete strategy should implement this

// The context class uses this to call the concrete strategy
interface Strategy {

    int execute(int a, int b);

}

// Implements the algorithm using the strategy interface
class ConcreteStrategyAdd implements Strategy {

    public int execute(int a, int b) {
        System.out.println("Called ConcreteStrategyAdd's execute()");
        return a + b;  // Do an addition with a and b
    }

}

class ConcreteStrategySubtract implements Strategy {

    public int execute(int a, int b) {
        System.out.println("Called ConcreteStrategySubtract's execute()");
        return a - b;  // Do a subtraction with a and b
    }

}

class ConcreteStrategyMultiply implements Strategy {

    public int execute(int a, int b) {
        System.out.println("Called ConcreteStrategyMultiply's execute()");
        return a * b;   // Do a multiplication with a and b
    }

}

// Configured with a ConcreteStrategy object and maintains a reference to a Strategy object
class Context {

    private Strategy strategy;

    // Constructor
    public Context(Strategy strategy) {
        this.strategy = strategy;
    }

    public int executeStrategy(int a, int b) {
        return strategy.execute(a, b);
    }

}
Run Code Online (Sandbox Code Playgroud)

这是很多工作,但你最终得到的东西在很多时候都是值得的,并且可能是泥球之间的差异,以及有可能被维持下去的东西.现在让我们用红宝石做吧

class Context
  def initialize(&strategy)
    @strategy = strategy
  end

  def execute
    @strategy.call
  end
end



a = Context.new { puts 'Doing the task the normal way' }
a.execute #=> Doing the task the normal way

b = Context.new { puts 'Doing the task alternatively' }
b.execute #=> Doing the task alternatively

c = Context.new { puts 'Doing the task even more alternatively' }
c.execute #=> Doing the task even more alternatively
Run Code Online (Sandbox Code Playgroud)

很难甚至称之为模式,你只是使用块!当语言涵盖模式所解决的需求时,有效地使用该语言意味着在大多数情况下您并不真正需要该模式.这也意味着你可以优雅地解决这类问题,因为做一个java风格的策略会是一种可怕的过度杀伤力.