Шпаргалка для всех шаблонов проектирования, реализованных в Ruby? - PullRequest
3 голосов
/ 26 августа 2010

Интересно, есть ли чит-коды для всех шаблонов проектирования, реализованных в Ruby, чтобы вам не пришлось изобретать велосипед?

Ответы [ 2 ]

6 голосов
/ 26 августа 2010

Шаблоны проектирования полезны для организации огромного количества кода.поскольку вам не нужно писать столько кода для работы в ruby, как в # {verbose_algol_derivitive_language}, они не имеют такой же степени важности.

То, что вы увидите, используется все время - это стратегия, а построитель реализован с блоками (примером строителя может быть форма form_for для блоков в представлениях рельсов, примером стратегии был бы File.open). Я не могу вспомнить, когда в последний раз видел другие(в любом случае шаблоны gof)

РЕДАКТИРОВАТЬ: реагируя на

Вы имеете в виду, что с ruby ​​нам не нужно думать о шаблонах проектирования в большинстве случаев?Другой вопрос, если я использую Rails, мне действительно нужно думать о шаблонах проектирования?Потому что я не знаю, где их использовать.Они, кажется, не вписываются ни в один компонент MVC.Шаблоны проектирования предназначены только для людей, которые создают массивные библиотеки / фреймворки, например.Rails, DataMapper, MongoID и т. Д. И не для других, которые используют только эти фреймворки / библиотеки?

По большей части, rails принимает большинство ваших решений за вас, и будет, пока ваше приложение не достигнет довольновысокий уровень сложности.Даже если вы используете что-то вроде sinatra (что для вас ничего не решает), вам все равно не нужно будет тянуться к этим шаблонам GoF так же, как в языке, подобном (например) java.

Это потому, что вся суть шаблонов проектирования заключается в том, чтобы сохранить гибкость и удобство обслуживания.Если это встроено в язык, часто они даже не нужны.

Например, шаблон стратегии, реализованный в 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);
    }

}

Это многоработать, но то, что у вас получается, стоит того, что стоит много времени, и может быть разницей между большим шариком грязи и чем-то, что имеет шансы на поддержание в аду.Теперь давайте сделаем это в ruby ​​

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

, трудно даже назвать этот паттерн, вы просто используете блоки!Когда язык удовлетворяет потребностям, которые удовлетворяет шаблон, эффективное использование языка будет означать, что вам в действительности не нужен шаблон в большинстве случаев.Это также означает, что вы можете элегантно решить такую ​​проблему, когда было бы ужасно излишним делать стратегию в стиле Java.

6 голосов
/ 26 августа 2010

Этот документ содержит хорошие примеры фактической реализации некоторых шаблонов проектирования из GoF.

Это может быть «шпаргалка», но я не думаю, что это «серебряная пуля» для шаблонов проектирования, потому что они появляются после того, как вы проанализировали проблему, и шаблон соответствует вашему решению. Это не рецепт, а скорее хороший справочник.

И, конечно же, это великая книга Шаблоны проектирования в Ruby

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...