我们在哪里使用 spring 框架实现松散耦合?

Where do we achieve loose coupling using spring framework?

我正在学习spring framework.I 看了很多网站上的教程,但我无法得到他们的解释。请简单易懂地向我解释一下。

  1. 这里我放了工厂设计模式来实现松耦合以及我们如何在Spring中使用这个设计模式。

  2. 我无法理解这一点(句子)"this pattern provides one of the best ways to create an object"。

    public interface Shape {
           void draw();
        }
    
    public class Rectangle implements Shape {
    
       @Override
       public void draw() {
          System.out.println("Inside Rectangle::draw() method.");
       }
    }
    
    public class Square implements Shape {
    
       @Override
       public void draw() {
          System.out.println("Inside Square::draw() method.");
       }
    }
    
    public class Circle implements Shape {
    
       @Override
       public void draw() {
          System.out.println("Inside Circle::draw() method.");
       }
    }
    
    public class ShapeFactory {
    
       //use getShape method to get object of type shape 
       public Shape getShape(String shapeType){
          if(shapeType == null){
             return null;
          }     
          if(shapeType.equalsIgnoreCase("CIRCLE")){
             return new Circle();
    
          } else if(shapeType.equalsIgnoreCase("RECTANGLE")){
             return new Rectangle();
    
          } else if(shapeType.equalsIgnoreCase("SQUARE")){
             return new Square();
          }
    
          return null;
       }
    }
    
    public class FactoryPatternDemo {
    
       public static void main(String[] args) {
          ShapeFactory shapeFactory = new ShapeFactory();
    
          //get an object of Circle and call its draw method.
          Shape shape1 = shapeFactory.getShape("CIRCLE");
    
          //call draw method of Circle
          shape1.draw();
    
          //get an object of Rectangle and call its draw method.
          Shape shape2 = shapeFactory.getShape("RECTANGLE");
    
          //call draw method of Rectangle
          shape2.draw();
    
          //get an object of Square and call its draw method.
          Shape shape3 = shapeFactory.getShape("SQUARE");
    
          //call draw method of circle
          shape3.draw();
       }
    }
    

    输出:

    Inside Circle::draw() method.
    Inside Rectangle::draw() method.
    Inside Square::draw() method.
    

Spring: 您可以将您的工厂声明为 @Component@Bean,然后将其自动连接到代码中您需要它的任何位置。

因此您将避免调用它的构造函数,并且工厂的单例实例将在应用程序启动时加载到 applicationContext 中。

工厂: 工厂的目的是将实例创建的所有逻辑包装到工厂的方法中,以简化对象的创建。如果你在很多地方多次需要同一个对象,你可以避免调用构造函数并将值传递给 setter,而只是调用工厂的单个方法。

这里您使用了一个 classic 工厂,它在每次调用时创建新的实例。 但是工厂遗漏了两点:getShape() 应该提供一个静态方法并且工厂 class 不应该被实例化超过一次。

工厂使用单例和静态方法classes 带来了一些缺点:测试期间的模拟更复杂,工厂增加了它的责任(它是单例但它也是工厂class ),在应用程序的 classes 之间产生了高耦合:客户端 classes 和工厂。
Spring 提供的依赖注入(但它并不孤单)解决了这些问题。
Spring 确实扮演了工厂的角色,单例问题也由 Spring 处理。

在 Spring 中,您有一些方法可以完成类似的事情:

  • 使用工厂 bean 和工厂方法。您有一个 XML 和一个 Java 版本。
    XML 方式是 XML 方式:冗长且不一定适合如果您更喜欢直接注释您的 classes 而不是创建间接读取使用的 Spring 配置。
    Java 版本没有间接缺点,但它有点冗长,因为您的工厂 class 必须实现 Spring FactoryBean 接口。

  • 使用 classic Spring 用 prototype 范围注释的 bean。

Spring 中的等价物可以是:

@Bean
@Scope("prototype")
public Shape shape(String shapeType) {   
      if(shapeType == null){
         return null;
      }     
      if(shapeType.equalsIgnoreCase("CIRCLE")){
         return new Circle();

      } else if(shapeType.equalsIgnoreCase("RECTANGLE")){
         return new Rectangle();

      } else if(shapeType.equalsIgnoreCase("SQUARE")){
         return new Square();
      }

      return null;   
}

无论如何,你应该使用BeanFactoryApplicationContextObject getBean(String name, Object... args)方法来传递shapeType参数。

例如:

Shape shape = (Shape) applicationContext.getBean("shape", "CIRCLE");