Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Design patterns 模板模式和策略模式有什么区别?_Design Patterns - Fatal编程技术网

Design patterns 模板模式和策略模式有什么区别?

Design patterns 模板模式和策略模式有什么区别?,design-patterns,Design Patterns,这两种模式(模板和策略)似乎相似。template方法有一个抽象基类和一个骨架方法,该骨架方法驱动需要改变的处理。处理是通过调用具体类提供的抽象方法来完成的。我们通过选择具体的类来选择所需的变体 例如,我们有一个Report类和一个继承自Report的HTMLReport类。我们的报告类可以如下所示: class Report def initialize @title = 'Monthly Report' @text = ['Things are going', 'really really

这两种模式(模板和策略)似乎相似。template方法有一个抽象基类和一个骨架方法,该骨架方法驱动需要改变的处理。处理是通过调用具体类提供的抽象方法来完成的。我们通过选择具体的类来选择所需的变体

例如,我们有一个
Report
类和一个继承自Report的
HTMLReport
类。我们的
报告
类可以如下所示:

class Report
def initialize
@title = 'Monthly Report'
@text = ['Things are going', 'really really well']
end

def output_report
output_start
output_head
output_body_start
output_body
output_body_end
output_end
end


def output_body
@text.each do |line|
output_line(line)
end

def output_start
raise StandardError
end

def output_head
raise 'This needs to be implemented by the concrete class'
end
...
end
class Report
attr_reader :title, :text
attr_accessor :formatter

def initialize(formatter)
@title = 'Monthly Report'
@text = ['Things are going', 'really, really well.']
@formatter = formatter
end

def output_report
@formatter.output_report(@title, @text)
end
end
以及我们的实际混凝土等级:

class HTMLReport < Report
def output_start
puts('<html>')
end

def output_head
puts('    <head>')
...
end

...
end
关键是抽象类为算法的可变部分调用其他方法,然后我们可以将其子类化(在本例中是通过Ruby继承),然后处理实际实现

但是,有一些缺点(根据Russ Olsen): -使用继承 -限制运行时的灵活性。。。一旦我们选择了一个特定版本的algo,改变我们的想法是很困难的

因此,战略模式: -取出令人烦恼的变化代码块,并将其隔离在自己的类中。然后创建一个完整的类族,每个类族对应一个变体

例如:

class Formatter
def output_report(title, text)
raise 'Abstract Method called'
end
end

class HTMLFormatter < Formatter
def output_report(title, text)
puts('<html>')
puts('   <head>')
puts("   <title>#{title}</title>")
puts('    </head>')
...
end
因此,如果我错了,请纠正我,因为所有策略都有相同的接口,所以我们可以在
报告
类中委托给它们。那些GOF人员将
报告
类称为
上下文

但这如何允许我们在运行时切换策略呢?我们还是这样称呼他们,对吗

report = Report.new(HTMLFormatter.new)
report.output_report

主要区别是什么?

模板模式不是一种模式。它简单地描述了我们都知道的多态性的基本原理。另一方面,Strategy模式为“函数”/“策略”定义了一个公共接口,可以在运行时进行交换。下面是Java中策略模式的一个示例(抱歉,不太熟悉Ruby):

免责声明:不是我的代码,很好的例子

public interface Strategy {
   public int doOperation(int num1, int num2);
}

public class OperationAdd implements Strategy{
   @Override
   public int doOperation(int num1, int num2) {
     return num1 + num2;
   }
}

public class OperationSubstract implements Strategy{
   @Override
   public int doOperation(int num1, int num2) {
      return num1 - num2;
   }
}

// Using this Context and common Strategy interface, we can utilize any operation
// we want.
public class Context {
   private Strategy strategy;

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

   public int executeStrategy(int num1, int num2){
      return strategy.doOperation(num1, num2);
   }
}

public class StrategyPatternDemo {

    public static void main(String[] args) {

       // Implement any Operation that implements Strategy interface
       Context context = new Context(new OperationAdd());       
       System.out.println("10 + 5 = " + context.executeStrategy(10, 5));

       context = new Context(new OperationSubstract());     
       System.out.println("10 - 5 = " + context.executeStrategy(10, 5));

       context = new Context(new OperationMultiply());      
       System.out.println("10 * 5 = " + context.executeStrategy(10, 5));
   }
}

我对Java不是很精通,介意带我看一下吗?当然,我这周刚开始学习Ruby,所以不太确定如何在Ruby中做到这一点,但我相信这是可以做到的。创建从名为“Strategy”的基类继承的类“Add”、“Subtract”,并使用名为
doOperation
的方法执行其工作。使用名为
execute
的方法创建另一个名为“Context”的类。在这个
execute
方法中,“Context”将调用这个
doOperation
方法。当创建上下文时,它将使用要执行的操作类型来创建,例如:
Context.new(new Add)
-如果这是有效的Ruby。或者我的意思是,介意通过您的Java和我谈谈吗?我的生锈了。。。这又是什么:`main(String[]args)`和
private-Strategy-Strategy
public-int-doOperation(int-num1,int-num2){return-num1-num2;}
?我刚刚做了。整个应用程序从
main(String[]args)
开始。它创建一个
新上下文
对象,并传入一个
新操作添加
对象。由于
OperationAdd
继承了
Strategy
并实现了
doOperation
,如果查看
上下文
类,它所要做的就是调用实例变量
Strategy.doOperation(num1,num2)
。这是因为可以保证所有
策略
都实现此接口。如果要更改模板方法版本中的格式,则必须创建一个全新的报表(因为需要不同的子类)。在strategy版本中,您可以只为现有报告分配一个新的格式化程序。
public interface Strategy {
   public int doOperation(int num1, int num2);
}

public class OperationAdd implements Strategy{
   @Override
   public int doOperation(int num1, int num2) {
     return num1 + num2;
   }
}

public class OperationSubstract implements Strategy{
   @Override
   public int doOperation(int num1, int num2) {
      return num1 - num2;
   }
}

// Using this Context and common Strategy interface, we can utilize any operation
// we want.
public class Context {
   private Strategy strategy;

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

   public int executeStrategy(int num1, int num2){
      return strategy.doOperation(num1, num2);
   }
}

public class StrategyPatternDemo {

    public static void main(String[] args) {

       // Implement any Operation that implements Strategy interface
       Context context = new Context(new OperationAdd());       
       System.out.println("10 + 5 = " + context.executeStrategy(10, 5));

       context = new Context(new OperationSubstract());     
       System.out.println("10 - 5 = " + context.executeStrategy(10, 5));

       context = new Context(new OperationMultiply());      
       System.out.println("10 * 5 = " + context.executeStrategy(10, 5));
   }
}