专业的JAVA编程教程与资源

网站首页 > java教程 正文

彻底理解java设计模式之工厂模式(java工厂类设计模式)

temp10 2024-10-23 15:12:48 java教程 15 ℃ 0 评论

前言

工厂模式是最常用的一类创建型设计模式,主要是简单工厂模式、抽象工厂模式,工厂方法模式 这三种。后续详细介绍每一种工厂模式。

彻底理解java设计模式之工厂模式(java工厂类设计模式)

简单工厂模式

定义

简单工厂模式是指由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式中用于创建实 例的方法是静态的,因此简单工厂模式又被称为静态工厂方法模式。

简单工厂模式不属于GOF 23种设计模式

示例

模拟电脑产品

首先定义一个电脑产品接口

   public interface Computer {
     public void show();
}

定义华硕品牌电脑

/**
 * 华硕
 */
public class ASUS implements Computer {
    @Override
    public void show() {
        System.out.println("this is ASUS computer");
    }
}

定义联想品牌电脑

/**
 * 联想
 */
public class Lenovo implements Computer {
    @Override
    public void show() {
        System.out.println("this is lenovo computer");
    }
}

定义惠普品牌电脑

/**
 * 惠普
 */
public class HP implements Computer {
    @Override
    public void show() {
       System.out.println("this is HP computer");
    }
}

定义工厂

public class ComputerFactory {
    /**
     * 通过条件判断 new 对象
     * @param name
     * @return
     */
    static Computer createComputer(String name) {
        switch (name) {
            case "Lenovo":
                return new Lenovo();
            case "ASUS":
                return new ASUS();
            case "HP":
                return new HP();
            default:
                return null;
        }
    }

    /**
     * 通过反射,传递类的全路径名
     * @param className
     * @return
     */
    static Computer createComputerReflect(String className) {
        try {
            Computer computer = (Computer) Class.forName(className).newInstance();
            return computer;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 通过反射,限定class类
     * @param clazz
     * @return
     */
    static Computer createComputer(Class<? extends Computer> clazz) {
        try {
            Computer computer = (Computer) clazz.newInstance();
            return computer;
        } catch (Exception e) {
        }
        return null;
    }
}

测试类代码

public class Main {
    public static void main(String[] args) {
        Computer lenovo = ComputerFactory.createComputer("Lenovo");
        lenovo.show();
        Computer HP = ComputerFactory.createComputerReflect
        ("com.chao.design.pattern.factory.model.HP");
        HP.show();
        Computer asus = ComputerFactory.createComputer(ASUS.class);
        asus.show();
    }
}

执行结果如下图

适用场景

  • 工厂类负责创建的对象比较少;
  • 客户端只需要传入工厂类的参数,对于如何创建对象的逻辑不需要关心;

优点

只需要传入一个正确的参数就可以获取所需要的对象,无须关心创建的细节。

缺点

  • 工厂类的职责相对过重,增加新的产品时需要修改工厂类的判断逻辑,违背开闭原则。
  • 不易于扩展过于复杂的产品结构。

工厂方法模式

定义

定义一个创建对象的接口,让实现这个接口的类(子类)决定实例化将哪一个类。工厂方法模式将类的实例化延迟到子类中进行。

与简单工厂模式相比,工厂方法 模式引入了抽象工厂角色,抽象工厂可以是接口,也可以是抽象类。

示例

继续使用电脑产品场景。

定义抽象工厂

   public interface IComputerFactory {
    Computer create();
}

定义联想电脑工厂,实现抽象工厂。

public class LenovoFactory implements IComputerFactory {
    @Override
    public Computer create() {
        return new Lenovo();
    }
}

定义华硕电脑工厂,实现抽象工厂。

public class ASUSFactory implements IComputerFactory {
    @Override
    public Computer create() {
        return new ASUS();
    }
}

客户端类,需要什么品牌电脑则通过电脑对应的工厂类来获取即可 。

public class Main {
    public static void main(String[] args) {
        LenovoFactory lenovoFactory = new LenovoFactory();
        Computer lenovo = lenovoFactory.create();
        lenovo.show();

        ASUSFactory asusFactory = new ASUSFactory();
        Computer asus = asusFactory.create();
        asus.show();
    }
}

当需要增加一个品牌电脑时,只需要增加具体电脑类和具体工厂类即可,不需要修改原有的电脑类和工厂类。例如 增加惠普电脑工厂。

public class HPFactory implements IComputerFactory {
    @Override
    public Computer create() {
        return new HP();
    }
}

客户端调用代码

public class Main {
    public static void main(String[] args) {
        LenovoFactory lenovoFactory = new LenovoFactory();
        Computer lenovo = lenovoFactory.create();
        lenovo.show();

        ASUSFactory asusFactory = new ASUSFactory();
        Computer asus = asusFactory.create();
        asus.show();

        HPFactory hpFactory = new HPFactory();
        Computer hp = hpFactory.create();
        hp.show();
    }
}

适用场景

  • 创建对象需要大量重复的代码。
  • 客户端不依赖于产品类实例如何被创建,实现等细节。
  • 抽象工厂类通过其子类来指定创建哪个对象。

优点

  • 用户只需要关心产品对应的工厂,无需关心创建细节。
  • 加入新产品符合开闭原则,提高了系统的可扩展性。

缺点

  • 类的数量容易过多,增加了代码结构的复杂度。
  • 增加了系统的抽象性和理解难度。

抽象工厂模式

定义

提供一个创建一系列相关或相互依赖对象的接口,无须指定它们具体的类。

在抽象工厂模式中,每一个具体工厂都提供了多个工厂方法用于产生多种不同类型的产品。

具体工厂实现了抽象工厂,每一个具体的工厂方法可以返回一个特定的产品对象,而同一个具体 工厂所创建的产品对象构成了一个产品族。

示例

继续使用上面定义的电脑产品,增加鼠标产品。

定义抽象鼠标接口

public interface Mouse {
     public void show();
}

定义联想鼠标

/**
 * 联想
 */
public class Lenovo implements Mouse {
    @Override
    public void show() {
        System.out.println("this is lenovo mouse");
    }
}

定义华硕鼠标

/**
 * 华硕
 */
public class ASUS implements Mouse {
    @Override
    public void show() {
        System.out.println("this is ASUS mouse");
    }
}

定义抽象工厂,与工厂方法模式不同,工厂方法模式中一个工厂只生产一个产品,而抽象工厂模式中一个工厂生产一族产品,有多个工厂方法。如下代码

public interface IProductFactory {
    /**
     * 生产电脑
     * @return
     */
    Computer createComputer();

    /**
     * 生产鼠标
     * @return
     */
    Mouse createMouse();
}

定义具体工厂,具体工厂都实现了抽象工厂。

public class LenovoFactory implements IProductFactory {

    @Override
    public Computer createComputer() {
        return new Lenovo();
    }

    @Override
    public Mouse createMouse() {
        return new LenovoMouse();
    }
}
public class ASUSFactory implements IProductFactory {

    @Override
    public Computer createComputer() {
        return new ASUS();
    }

    @Override
    public Mouse createMouse() {
        return new ASUSMouse();
    }
}

客户端只需要指定具体工厂,就可以获取该工厂生产的族产品。

public class Main {
    public static void main(String[] args) {

        LenovoFactory lenovoFactory = new LenovoFactory();
        Computer lenovoComputer = lenovoFactory.createComputer();
        Mouse lenovoMouse = lenovoFactory.createMouse();
        lenovoComputer.show();
        lenovoMouse.show();

        ASUSFactory asusFactory = new ASUSFactory();
        Computer asusComputer = asusFactory.createComputer();
        Mouse asusMouse = asusFactory.createMouse();
        asusComputer.show();
        asusMouse.show();

    }
}

执行结果如下图

适用场景

  • 强调一系列的产品对象(属于同一产品族)一起使用创建对象需要大量重复的代码。
  • 提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现。

优点

  • 具体产品在应用层代码隔离,无需关心创建细节。
  • 将一个系列的产品族统一到一起创建。

缺点

  • 规定了所有可能被创建的产品集合,产品族中扩展新的产品困难,需要修改抽象工厂的接口,违背了开闭原则。
  • 增加了系统的抽象性和理解难度。

以上就是个人对工厂模式的理解。欢迎大家提出不同的观点。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表