定义一个创建对象的接口,让子类决定实例化哪个类。工厂方法使一个类的实例化延迟到其子类。
理解工厂方法模式:通过虚函数延迟对象创建到子类
掌握工厂方法的核心结构:Creator、ConcreteCreator、Product、ConcreteProduct
理解"依赖倒置原则"——Creator 依赖 Product 接口而非具体类
了解工厂方法与简单工厂的区别,以及何时应该使用它
创建者定义工厂方法,具体子类决定实例化哪一种产品
/** 产品接口:所有按钮实现此接口 */
public interface Button {
void render();
void onClick();
}/** HTML 按钮实现 */
public class HtmlButton implements Button {
public void render() {
System.out.println("<button>Test Button</button>");
onClick();
}
public void onClick() {
System.out.println(
"Click! Button says - \'Hello World!\'");
}
}/** Windows 风格按钮实现 */
public class WindowsButton implements Button {
public void render() {
System.out.println("[Windows Button]");
onClick();
}
public void onClick() {
System.out.println(
"Click! Windows Button - \'Hello World!\'");
}
}/**
* 基础创建者类。
* renderWindow() 包含核心业务逻辑,
* 需要 createButton() 创建产品。
*/
public abstract class Dialog {
public void renderWindow() {
Button okButton = createButton();
okButton.render();
}
/** 子类重写此方法以创建具体按钮 */
public abstract Button createButton();
}/** HTML 对话框 → 产出 HTML 按钮 */
public class HtmlDialog extends Dialog {
@Override
public Button createButton() {
return new HtmlButton();
}
}/** Windows 对话框 → 产出 Windows 按钮 */
public class WindowsDialog extends Dialog {
@Override
public Button createButton() {
return new WindowsButton();
}
}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.renderWindow();
}
}Creator 调用工厂方法,由子类决定创建哪个具体产品(new 的位置从业务代码转移到子类)。
新增产品(如 WebDialog 适配新平台)无需修改 Dialog,只需添加新子类。
Dialog.renderWindow() 只认识 Button 接口,不知道具体是 HtmlButton 还是 WindowsButton。
如:跨平台 UI(iOS/Android 按钮族)、数据库驱动、日志框架、文档生成器。