首页 > 技术文章 > Factory Method

huaranmeng 2021-01-14 21:54 原文

设计模式目录

工厂模式又称工厂方法模式,是一种创建型设计模式, 解决了在不指定具体类的情况下创建产品对象的问题。其在父类中提供一个创建对象的方法,允许子类决定实例化对象的类型。
这种设计模式也是Java开发中最常见的一种模式,它的主要意图是定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。

核心 Java 程序库中有该模式的应用:

识别方法: 工厂方法可通过构建方法来识别, 它会创建具体类的对象, 但以抽象类型或接口的形式返回这些对象。

样例

生成跨平台的 GUI 元素

由按钮担任产品的角色,对话框担任创建者的角色

接口:

package creational.factorymethod;

/**
 * 通用的 Button 接口
 */
public interface IButton {
    void render();

    void onClick();
}

具体产品:

package creational.factorymethod;

/**
 * Html Button 实现类
 */
public class HtmlButton implements IButton {

    @Override
    public void render() {
        System.out.println("<button>Test: Button</button>");
        onClick();
    }

    @Override
    public void onClick() {
        System.out.println("Click~! Button says - 'Hello World'");
    }
}




package creational.factorymethod;

import javax.swing.*;
import java.awt.*;

/**
 * Windows Button 实现类
 */
public class WindowsButton implements IButton {

    JPanel panel = new JPanel();
    JFrame frame = new JFrame();
    JButton button;

    @Override
    public void render() {
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JLabel label = new JLabel("Hello World!");
        label.setOpaque(true);
        label.setBackground(new Color(235, 233, 126));
        label.setFont(new Font("Dialog", Font.BOLD, 44));
        label.setHorizontalAlignment(SwingConstants.CENTER);
        panel.setLayout(new FlowLayout(FlowLayout.CENTER));
        frame.getContentPane().add(panel);
        panel.add(label);
        onClick();
        panel.add(button);

        frame.setSize(320, 200);
        frame.setVisible(true);
        onClick();
    }

    @Override
    public void onClick() {
        button = new JButton("Exit");
        button.addActionListener(e -> {
            frame.setVisible(false);
            System.exit(0);
        });
    }
}

工厂:

package creational.factorymethod;

/**
 * Base factory class
 */
public abstract class Dialog {
    public void renderWidow() {
        IButton okButton = createButton();
        okButton.render();
    }

    /**
     * 子类将重写此方法来创建具体的按钮
     * @return
     */
    public abstract IButton createButton();
}

具体的创建者:

package creational.factorymethod;

public class HtmlDialog extends Dialog {

    @Override
    public IButton createButton() {
        return new HtmlButton();
    }
}



package creational.factorymethod;

public class WindowsDialog extends Dialog {

    @Override
    public IButton createButton() {
        return new WindowsButton();
    }
}

测试代码:

package creational.factorymethod;

public class Demo {
    private static Dialog dialog;

    public static void main(String[] args) {
        configure();
        runBusinessLogic();
    }

    static void configure() {
        if (System.getProperty("os.name").equals("Windows 10")) {
            dialog = new WindowsDialog();
        } else {
            dialog = new HtmlDialog();
        }
    }

    static void runBusinessLogic() {
        dialog.renderWidow();
    }
}

推荐阅读