Java有界泛型与策略模式之间的区别

时间:2020-06-10 16:34:28

标签: java generics design-patterns generic-programming strategy-pattern

我有一个util类,它与接口Isupplier耦合。

Util<T extends Isupplier>

它具有execute方法,其中包含实现Isupplier的对象列表。

execute(List<T extends Isupplier> objList )

有些类可以实现Isupplier中的方法。还有一个调用者类,它为每个实现类调用execute方法。

Class A implements Isupplier

Class B implements Isupplier

 Class ACaller{
 //calls Util.execute(List of Object A)`
}
 Class BCaller{
 //calls Util.execute(List of Object B)`
}

这可以称为使用策略模式吗?由于我们正在编码接口。该策略可以是Isupplier的实现。作为供应商的基本策略。上下文是否有用?

3 个答案:

答案 0 :(得分:0)

定义:“策略是一种行为设计模式,它将一组行为转变为对象,并使它们在原始上下文对象中可互换。而且,它是一种设计模式,可以在运行时选择算法的行为。”

重述..这通常是通过一个保存方法的接口来完成的,并且有一些实现类,每个类具有某种不同的风格(隐式逻辑)。然后有客户端代码可以根据实现类来驱动算法行为。

以下内容可能很小。其中

interface Printer {
    void print();
}   

class LaserPrinter implements Printer {
    void print() {
        Sysout("laser printed");
    }
}

class InkjetPrinter implements Printer {
    void print() {
        Sysout("ink printed");
    }
}

class Client {
    Printer printer;
    if laserprinter
         printer = new LaserPrinter();
    else
         printer = new InkjetPrinter();
}

注1:这只是一个片段,而不是具体的示例。通常,即使使用setter时也无需执行if-else或切换操作,也可以实现策略,从而改变算法行为。

现在回答您的问题:,例如使用策略模式。

您的A类和B类实现了ISupplier,因此它们将为方法“ execute”添加自己的风格,而类Util只是一个包装,因此您将在运行时更改execute方法的行为。

注2:如jaco0646所述,Util类不是面向对象的,因此您可以使用带有setter的类来接受ISupplier的具体对象,并且可以使用该类来确定必须执行什么。

参考:

  1. https://www.geeksforgeeks.org/strategy-pattern-set-1/

  2. https://refactoring.guru/design-patterns/strategy/java/example

关于, 萨巴雷什M

答案 1 :(得分:0)

回答第一个问题“ java限定泛型与策略模式之间的差异”

每个概念的定义:

  • Java有界泛型:是一种工具,用于限制可以在参数化类或方法中用作类型实参的类型,以确保在编译时安全地执行类型。对于您而言,您是在强制将参数从Isupplier扩展。
  • 策略模式:是一种行为设计模式,它将一组行为转变为实现相同接口(依赖于多态性,但这并不意味着它们是同一事物)的类,并且使它们在运行时benefiting the composition over inheritance可以在原始上下文类中互换。

因此,现在很清楚Java bounded generics是获取parametric polymorphism的工具,可确保参数实现或扩展具体的类/接口,而该类/接口与Strategy pattern无关,这对于在运行时选择要执行的行为/类是一项有用的技术。

回答第二个问题 “该策略可以是Isupplier的实现。基本策略是Isupplier。上下文是Util?”

使用策略模式(依赖于多态性)。 我知道您可以使用多态性来实现相同的Isupplier接口的类,但是策略模式与您在方法中所执行的操作之间的主要区别在于:

execute(List<T extends Isupplier> objList)

该策略模式是否会在运行时基于相同条件在objList对象之间进行选择,并且它将执行所选择的一个,但仅执行一个,而不执行对象的完整列表。

答案 2 :(得分:0)

在示例中,您的案例看起来比策略模式更像Decorator Pattern案例。

为了确定两者之间的区别,我请您参考一个好的信息源(不要以为我自己也不知道,但是维基百科是一个很好的声望来源);

我实际上已将您的情况变成了下面的实际运行代码。 我还将尝试阐明为什么这不是一种策略模式。

ISupplier.java:
public interface ISupplier {
  void supply() ;
}

A.java
public class A implements ISupplier {

    private String name = null ;
    public A(String supplierName) {
         name = supplierName;
     }
    public  void supply() {
        System.out.println( name+ " Supplies from China!" );
     }
}


Util.java
import java.util.*;
public class Util <T extends ISupplier> {

 public  void supply() {
    System.out.println( " Util Context!" );
 }
 
 public void execute(List<ISupplier> objList ) {
     for (ISupplier supplier : objList) {
         supplier.supply();
     }
 }
}

ACaller.java
import java.util.*;

public class ACaller {

    Util util =  null;

    List<A> listOfA = null;
    
    public ACaller(Util ut) {
        util = ut;
    }
    
    public void fillListA() {
        listOfA = new ArrayList<A>();
        
        listOfA.add(new A("A-1"));
        listOfA.add(new A("A-2"));
    }
    public void run()  {

        util.execute(listOfA);
    }
    
    public static void main(String[] args) {

        Util strategy1 = new Util();
        ACaller ac = new ACaller(strategy1);
        
        ac.fillListA();
        
        ac.run();
        
    }
}

运行此代码时;您将得到:

 $ java ACaller 
 A-1 Supplies from China!
 A-2 Supplies from China!

Util类并没有提供任何有益的东西,而是充当了调用者和供应商之间的另一个静态中介。

在一个真正起作用的策略模式中,我们希望上下文(Util)为解决方案动态提供不同的supply()方法。

换句话说,我们没有办法从Util类提供动态实现supply()方法 的方法。

简而言之,您的案例似乎更接近于装饰器模式,而不是策略模式,因此不是策略模式。

请注意,这两种模式都使用接口,所以仅仅因为您正在写接口,并不意味着那样。

欢呼