简略工厂形式

运用简略工厂形式的长处包含:

简略工厂的长处

  • 它供给了一种创立目标的办法,而无需指定将要创立的目标的切当类。这在事前不知道要创立的特定目标类型或或许发生变化的情况下很有用。
  • 它为创立目标供给了单一的控制点。这可以更轻松地办理和保护代码库,因为一切目标创立都是经过工厂处理的。
  • 它促进了目标之间的松散耦合。工厂创立目标时不需求知道它们是怎样完成的详细细节,这使得代码具有更大的灵敏性和可重用性。

潜在缺陷

  • 它可以使代码库愈加杂乱。工厂的运用添加了一个额外的笼统层,这会使代码更难了解和保护。
  • 它或许违反单一职责准则。工厂担任创立目标,这是一个独立于它创立的类的其他职责的关注点。这会使了解类和工厂之间的关系变得困难。
  • 它会使单元测试愈加困难。因为工厂创立目标时未指定其切当类型,因而编写单元测试以充分包括可由工厂创立的一切或许目标类型或许具有挑战性。

代码模拟

public class Dog {
    private String name;
    public Dog(String name) {
        this.name = name;
    }
    public String speak() {
        return "Woof!";
    }
}
public class Cat {
    private String name;
    public Cat(String name) {
        this.name = name;
    }
    public String speak() {
        return "Meow!";
    }
}
public class Parrot {
    private String name;
    public Parrot(String name) {
        this.name = name;
    }
    public String speak() {
        return "Squawk!";
    }
}
public class PetFactory {
    public static Pet getPet(String petType, String name) {
        if (petType.equalsIgnoreCase("dog")) {
            return new Dog(name);
        } else if (petType.equalsIgnoreCase("cat")) {
            return new Cat(name);
        } else if (petType.equalsIgnoreCase("parrot")) {
            return new Parrot(name);
        }
        return null;
    }
}
public class Main {
    public static void main(String[] args) {
        PetFactory petFactory = new PetFactory();
        Pet pet = petFactory.getPet("dog", "Max");
        System.out.println(pet.speak());
        pet = petFactory.getPet("cat", "Fluffy");
        System.out.println(pet.speak());
        pet = petFactory.getPet("parrot", "Polly");
        System.out.println(pet.speak());
    }
}

在此示例中,PetFactory该类有一个getPet()将 apetType和 aname作为输入参数的办法。该办法运用petType来确定要创立哪种类型的宠物目标并返回相应类的实例。该类PetFactory可用于创立、 和类的实例Dog,而无需指定将创立的切当类。Cat Parrot

工厂形式

工厂形式和简略工厂形式的差异与提升

工厂模型在几个方面是对简略工厂模型的改进。一方面,它答应在不指定将要创立的目标的切当类的情况下创立目标。这在事前不知道要创立的目标的切当类型的情况下,或者在依据输入数据决议创立目标类型的情况下很有用。

此外,工厂模型在运用目标的代码和创立目标的代码之间供给了必定程度的笼统。这可以使保护和修正代码变得愈加简略,并使其愈加灵敏和可重用。

此外,工厂模型可以更轻松地完成新类型的目标,而无需更改现有代码。这可以让代码库更简略扩展和演进。

示例代码

// 形状接口
public interface Shape {
  // 制作形状
  void draw();
}
// 圆形类,完成 Shape 接口
public class Circle implements Shape {
  @Override
  public void draw() {
    System.out.println("在 Circle 类的 draw 办法内部。");
  }
}
// 矩形类,完成 Shape 接口
public class Rectangle implements Shape {
  @Override
  public void draw() {
    System.out.println("在 Rectangle 类的 draw 办法内部。");
  }
}
// 形状工厂类
public class ShapeFactory {
  // 运用 getShape 办法来获取形状类型的目标
  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();
    }
    return null;
  }
}
// 工厂形式示例
public class FactoryPatternDemo {
  public static void main(String[] args) {
    // 获取形状工厂
    ShapeFactory shapeFactory = new ShapeFactory();
    // 获取 Circle 目标,并调用它的 draw 办法
    Shape shape1 = shapeFactory.getShape("CIRCLE");
    // 调用 Circle 的 draw 办法
    shape1.draw();
    // 获取 Rectangle 目标,并调用它的 draw 办法
    Shape shape2 = shapeFactory.getShape("RECTANGLE");
    // 调用 Rectangle 的 draw 办法
    shape2.draw();
  }
}

在上面的代码中,咱们界说了一个 Shape 接口和两个完成了这个接口的类,CircleRectangle,用于创立不同形状的目标。咱们还界说了一个 ShapeFactory 类,用于依据用户供给的形状类

代码解说

上面的代码演示了怎样运用工厂形式来创立不同形状的目标。详细来说,它界说了一个 Shape 接口,表示形状,并界说了一个 draw 办法用于制作形状。然后界说了两个完成了 Shape 接口的类,CircleRectangle,分别表示圆形和矩形。

接着,界说了一个 ShapeFactory 类,它包含一个 getShape 办法,用于依据用户供给的形状类型(例如 “CIRCLE” 或 “RECTANGLE”)来创立相应的形状目标。终究,在 main 办法中,咱们创立了一个 ShapeFactory 目标,然后调用它的 getShape 办法来创立 CircleRectangle 目标,并调用它们的 draw 办法来制作这两个形状。

经过运用工厂形式,咱们可以将目标的创立和运用分离开来,使得代码更简略保护和扩展。例如,假如咱们想要添加新的形状,只需求完成 Shape 接口,并在 ShapeFactory 类的 getShape 办法中添加一个分支来处理新的形状类型即可。这样,就可以避免对现有代码的修正,提高代码的灵敏性和可扩展性。

笼统工厂形式

笼统工厂形式是一种规划形式,它供给了一种办法来创立相互依赖的目标,而无需指定它们详细的类。它经过将相关的目标的创立会集在一个工厂中,然后使得代码更简略保护和扩展。

笼统工厂形式是一种创立型规划形式,它供给了一种办法来创立一组相关或相互依赖的目标,无需指定他们的详细类。

下面是一个典型的笼统工厂形式模板,其中包含了笼统工厂类、详细工厂类、笼统产品类、详细产品类:

/**
 * 笼统工厂类
 */
public abstract class AbstractFactory {
    /**
     * 创立产品A
     */
    public abstract ProductA createProductA();
    /**
     * 创立产品B
     */
    public abstract ProductB createProductB();
}
/**
 * 详细工厂类
 */
public class ConcreteFactory extends AbstractFactory {
    /**
     * 创立产品A
     */
    public ProductA createProductA() {
        return new ConcreteProductA();
    }
    /**
     * 创立产品B
     */
    public ProductB createProductB() {
        return new ConcreteProductB();
    }
}
/**
 * 笼统产品类
 */
public abstract class ProductA {
    // 产品共有办法
    public void sharedMethod() {
        // ...
    }
    // 笼统办法
    public abstract void doSomething();
}
/**
 * 详细产品类
 */
public class ConcreteProductA extends ProductA {
    // 完成笼统办法
    public void doSomething() {
        // ...
    }
}
/**
 * 笼统产品类
 */
public abstract class ProductB {
    // 产品共有办法
    public void sharedMethod() {
        // ...
    }
    // 笼统办法
    public abstract void doSomething();
}
/**
 * 详细产品类
 */
public class ConcreteProductB extends ProductB {
    // 完成笼统办法
    public void doSomething() {
        // ...
    }
}

上述代码解读

上述代码界说了用于创立产品的笼统工厂形式。笼统工厂类AbstractFactory界说了两个笼统办法来创立类型ProductA和的产品ProductB。这些办法由ConcreteFactory类完成,类分别扩展AbstractFactory和创立 和 的ConcreteProductA实例ConcreteProductB

ProductA并且ProductB是笼统类,它们界说了一个通用办法sharedMethod和一个笼统办法 ,doSomething它们必须由详细的产品类来完成。在此代码中,ConcreteProductA和分别是和类ConcreteProductB的详细完成。他们都完成了这个办法。ProductA``ProductB``doSomething

要运用这种笼统工厂形式,客户可以创立一个实例ConcreteFactory并运用它来创立实例,ProductAProductB无需知道这些产品的详细完成细节。这答应客户端与产品完成解耦,然后更简略在未来添加新类型的产品。

优缺陷

笼统工厂形式的长处:

  • 将详细的创立逻辑封装在详细工厂中,对于客户端来说是通明的,客户端无需关怀详细产品是怎样创立的。
  • 可以很简略地添加新的详细工厂和详细产品,满意开闭准则。
  • 客户端与详细产品的耦合度下降,可以轻松地替换详细产品。

缺陷:

  • 笼统工厂类需求针对每一种详细产品都进行扩展,添加体系的杂乱度。
  • 当需求更换详细工厂时,需求修正客户端代码,不满意开闭准则。

需求留意,笼统工厂形式不同于工厂办法形式,工厂办法形式只要一个笼统工厂类和多个详细工厂类,每个详细工厂类只能创立一种详细产品。而笼统工厂形式有多个笼统工厂类和多个详细工厂类,每个笼统工厂类可以创立多种不同的详细产品。

笼统工厂形式适用于创立一组相关或相互依赖的产品目标,且客户端无需关怀详细产品目标的创立进程。例如,一个电商网站供给了多种不同的付出办法,如付出宝、微信付出等,可以运用笼统工厂形式来创立不同付出办法对应的产品目标,客户端可以依据需求挑选不同的付出办法,无需关怀付出办法的详细完成细节。

总结

常见的工厂形式有三种:简略工厂形式、工厂办法形式和笼统工厂形式。

简略工厂形式:

  • 简略工厂形式由一个工厂类来担任一切产品的创立。
  • 客户端需求经过工厂类供给的静态办法来创立产品,无需关怀产品的创立进程。
  • 简略工厂形式完成简略,易于了解和运用,但不满意开闭准则,一旦添加新的产品需求修正工厂类的代码。

工厂办法形式:

  • 工厂办法形式由笼统工厂类和多个详细工厂类组成。
  • 笼统工厂类界说了产品的创立办法,而详细工厂类则完成了创立详细产品的办法。
  • 客户端经过指定详细工厂类来创立产品,工厂办法形式可以让客户端与详细产品的完成解耦,满意开闭准则。
  • 工厂办法形式的缺陷是添加新的产品需求修正笼统工厂类及一切的详细工厂类,会添加体系的杂乱度。

笼统工厂形式:

  • 笼统工厂形式由多个笼统工厂类和多个详细工厂类组成。
  • 笼统工厂类界说了多种产品的创立办法,而详细工厂类则完成了创立不同类型产品的办法。
  • 客户端经过指定详细工厂类来创立产品,笼统工厂形式可以让客户端与详细产品的完成解耦,满意开闭准则。
  • 笼统工厂形式的长处是可以很简略地添加新的产品,但缺陷是笼统工厂类需求针对每一种详细产品都进行扩展,添加体系的杂乱度。

总结来说,简略工厂形式完成简略,但不满意开闭准则;工厂办法形式满意开闭准则,但添加新产品需求修正笼统工厂类及一切的详细工厂类;笼统工厂形式能很简略地添加新产品,但需求针对每一种详细产品都进行扩展,添加体系的杂乱度。应用时需求依据实际情况挑选适宜的工厂形式。

弥补

什么时候可以考虑运用工厂形式

当满意以下条件时,可以考虑运用工厂形式:

  1. 体系需求创立不同类型的目标,但详细要创立的目标类型在编译时是未知的。
  2. 目标的创立触及一组杂乱的步骤,例如初始化目标、设置其特点和执行其他操作。
  3. 客户端代码需求与正在创立的目标的完成细节分离。
  4. 体系需求可以在不修正现有代码的情况下轻松添加新类型的目标。

一般来说,工厂形式可以帮助下降目标创立的杂乱性,并供给一种灵敏的办法来办理体系中不同组件之间的依赖关系。

怎样去挑选不同工厂形式

  1. 产品创立进程的杂乱性:假如产品创立进程很简略,只触及几个步骤,一个简略的工厂形式或许就足够了。假如产品创立进程杂乱且触及多个步骤,工厂办法或笼统工厂形式或许更适宜。
  2. 产品数量:假如只要一种产品,简略的工厂形式或许就足够了。假如有多种类型的产品,工厂办法或笼统工厂形式或许更适宜。
  3. 可扩展性的需求:假如体系需求可以方便地添加新产品,笼统工厂形式或许是最好的挑选。
  4. 客户端与产品之间的耦合程度:假如客户端需求与产品紧密耦合,一个简略的工厂形式或许就足够了。假如客户端需求与产品松散耦合,工厂办法或笼统工厂形式或许更适宜。

终究,工厂形式的挑选取决于体系的详细要求和不同要素之间的权衡。

本文正在参与「金石计划 . 分割6万现金大奖」