设计模式之工厂模式

Posted ProChick

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式之工厂模式相关的知识,希望对你有一定的参考价值。

一、简单工厂模式

1.简要概述

  • 简单工厂模式就是在创建一个对象时,不向客户端暴露内部创建细节,而是提供一个创建对象的通用接口。
  • 简单工厂模式也叫静态工厂模式,就是工厂类一般是使用静态方法, 通过接收参数的不同来返回不同的对象实例 。
  • 简单工厂模式中,可以根据参数的不同返回不同类的实例。因为简单工厂模式会专门定义一个类来负责创建其它继承类的实例,这个类被称为简单工厂类,所以可以让简单工厂类根据参数来决定应该用哪个具体子类来实例化。

2.模式结构

👉通常由一个工厂类( 负责实现创建所有子类实例的内部逻辑 ),多个具体产品类( 也就是具有不同实现的工厂子类 ),一个产品接口类( 是所有具体产品类的父类,提供描述所有产品类的公共接口 ),一个客户类( 负责调用来创建指定的某种产品 )共同组成。

3.实现代码

举例 💡 :假设一个玩具工厂可以创建小猫玩具和小狗玩具,而我们想通过指定的参数来让工厂创建指定类型的玩具,那么这个实现过程就可以采用简单工厂模式来实现。

不使用简单工厂

// 玩具接口
public interface Toy{
    void printName();
}

// 小猫玩具实现类
public class CatToy implements Toy{
    public void printName(){
        System.out.println("这是小猫玩具");
    }
}

// 小狗玩具实现类
public class DogToy implements Toy{
    public void printName(){
        System.out.println("这是小狗玩具");
    }
}

// 测试客户端
public class ToyClient{
    public static void main(String[] args) {
        Toy cat = new CatToy();
        cat.printName();

        Toy dog = new DogToy();
        dog.printName();
    }
}

使用简单工厂

// 玩具接口
public interface Toy{
    void printName();
}

// 小猫玩具实现类
public class CatToy implements Toy{
    public void printName(){
        System.out.println("这是小猫玩具");
    }
}

// 小狗玩具实现类
public class DogToy implements Toy{
    public void printName(){
        System.out.println("这是小狗玩具");
    }
}

// 玩具工厂
public class ToyFactory{
    public static Toy createToy(String type){
        Toy toy = null;
        
        if(type == "cat"){
            toy = new CatToy();
        }else if(type == "dog"){
            toy = new DogToy();
        }
        
        return toy;
    }
}

// 测试客户端
public class ToyClient{
    public static void main(String[] args) {
        Toy cat = ToyFactory.createToy("小猫");
        cat.printName();

        Toy dog = ToyFactory.createToy("小狗");
        dog.printName();
    }
}

4.优点好处

  • 可以使代码之间进行解耦,这里就将客户类和具体子类进行了解耦,客户类不再需要知道有哪些子类以及它们各自的实现细节。
  • 可以使代码更加易于维护,当某些子类发生改变时,客户类不需要进行修改。

5.缺点弊端

  • 增加新的产品子类的时候,需要修改原有工厂类的判断逻辑代码,不满足OCP原则
  • 具体产品子类较多的时侯,工厂类的判断逻辑代码将会非常复杂

6.应用场景

  • 工厂类负责创建的对象种类比较少时使用
  • 对于不考虑创建一个对象有多复杂时使用

7.应用示例

JDK源码中的Calendar类

二、工厂方法模式

1.简要概述

  • 工厂方法模式就是定义一个创建对象工厂接口,但不是由工厂类决定要实例化哪个具体子类,而是由具体的工厂子类去实例化对应的子类。
  • 工厂方法模式也叫多态工厂模式,就是工厂类一般会有多个具体的工厂实现子类, 然后通过不同的工厂子类来创建不同的对象实例。
  • 工厂方法模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品的对象实例,比简单工厂多了工厂子类。

2.模式结构

👉通常由一个工厂父类( 负责定义创建所有工厂子类实例的接口 ),多个具体工厂子类( 负责实现创建具体子类实例的内部逻辑 ),多个具体产品类( 具有不同实现的工厂子类 ),一个产品接口类( 是所有具体产品类的父类,提供描述所有产品类的公共接口 ),一个客户类( 负责调用来创建指定的某种产品 )共同组成。

3.实现代码

举例 💡 :假设一个玩具工厂可以创建小猫玩具和小狗玩具,而我们想通过指定类型的玩具工厂来创建这种类型的玩具,那么这个实现过程就可以采用工厂方法模式来实现。

不使用工厂方法

// 玩具接口
public interface Toy{
    void printName();
}

// 小猫玩具实现类
public class CatToy implements Toy{
    public void printName(){
        System.out.println("这是小猫玩具");
    }
}

// 小狗玩具实现类
public class DogToy implements Toy{
    public void printName(){
        System.out.println("这是小狗玩具");
    }
}

// 玩具工厂
public class ToyFactory{
    public static Toy createToy(String type){
        Toy toy = null;
        
        if(type == "cat"){
            toy = new CatToy();
        }else if(type == "dog"){
            toy = new DogToy();
        }
        
        return toy;
    }
}

// 测试客户端
public class ToyClient{
    public static void main(String[] args) {
        Toy cat = ToyFactory.createToy("小猫");
        cat.printName();

        Toy dog = ToyFactory.createToy("小狗");
        dog.printName();
    }
}

使用工厂方法

// 玩具接口
public interface Toy{
    void printName();
}

// 小猫玩具实现类
public class CatToy implements Toy{
    public void printName(){
        System.out.println("这是小猫玩具");
    }
}

// 小狗玩具实现类
public class DogToy implements Toy{
    public void printName(){
        System.out.println("这是小狗玩具");
    }
}

// 玩具工厂父类
public abstract class ToyFactory{
    public abstract Toy createToy();
}

// 小猫玩具工厂子类
public class CatToyFactory extends ToyFactory{
    public Toy createToy(){
        return new CatToy();
    }
}

// 小狗玩具工厂子类
public class DogToyFactory extends ToyFactory{
    public Toy createToy(){
        return new DogToy();
    }
}

// 测试客户端
public class ToyClient{
    public static void main(String[] args) {
        ToyFactory catFactory = new CatToyFactory();
        Toy cat = catFactory.createToy();
        cat.printName();
        
        ToyFactory dogFactory = new DogToyFactory();
        Toy dog = dogFactory.createToy();
        dog.printName();
    }
}

4.优点好处

  • 可以使代码之间进行解耦,这里就将客户类和具体子类进行了解耦,客户类不再需要知道有哪些子类以及它们各自的实现细节。
  • 可以使代码更加易于维护,当某些子类发生改变时,客户类不需要进行修改。
  • 增加新产品的时候,也不需要修改原有工厂子类的逻辑代码,只需增加对应的产品子类和创建该产品对象实例的工厂子类即可,满足OCP原则。

5.缺点弊端

具体产品子类较多的时侯,工厂子类也会跟着增加,所以增加了系统的复杂程度。

6.应用场景

  • 当一个类需要通过其子类来决定创建哪个对象的时候使用。
  • 当客户端需要动态指定创建哪一个具体对象实例的时候使用。

7.应用示例

JDK源码中的Charset类

工厂父类:

工厂子类:


以上是关于设计模式之工厂模式的主要内容,如果未能解决你的问题,请参考以下文章

Delphi 设计模式:《HeadFirst设计模式》Delphi7代码---工厂模式之简单工厂

设计模式之简单工厂模式

设计模式之简单工厂模式

Java代码实现设计模式之工厂模式

设计模式之简单工厂模式

设计模式之工厂模式