这三个模式都在解决“对象创建”问题,强相关,合并学习效率最高。
一句话区分:
直接 new 不是错,很多时候它就是最简单、最清晰的方案。
适合直接 new:
适合引入工厂:
真实痛点对比:
new:新增一种类型时,业务代码里到处改 if-else场景:根据类型创建支付处理器(微信、支付宝、银行卡)。
场景:插件化系统,不同模块自己决定创建哪种实现。
场景:跨平台 UI(Windows 按钮+输入框,Mac 按钮+输入框)必须成套出现。
interface PayService {
void pay();
}
class WechatPayService implements PayService {
@Override
public void pay() {
System.out.println("微信支付");
}
}
class AlipayService implements PayService {
@Override
public void pay() {
System.out.println("支付宝支付");
}
}
class PayServiceFactory {
public static PayService create(String type) {
if ("wechat".equalsIgnoreCase(type)) {
return new WechatPayService();
}
if ("alipay".equalsIgnoreCase(type)) {
return new AlipayService();
}
throw new IllegalArgumentException("不支持的支付类型: " + type);
}
}public class Demo1 {
public static void main(String[] args) {
PayService payService = PayServiceFactory.create("wechat");
payService.pay();
}
}interface PayService {
void pay();
}
class WechatPayService implements PayService {
@Override
public void pay() {
System.out.println("微信支付");
}
}
class AlipayService implements PayService {
@Override
public void pay() {
System.out.println("支付宝支付");
}
}
interface PayFactory {
PayService createPayService();
}
class WechatPayFactory implements PayFactory {
@Override
public PayService createPayService() {
return new WechatPayService();
}
}
class AlipayFactory implements PayFactory {
@Override
public PayService createPayService() {
return new AlipayService();
}
}public class Demo2 {
public static void main(String[] args) {
PayFactory factory = new WechatPayFactory();
factory.createPayService().pay();
}
}interface Button {
void render();
}
interface Input {
void render();
}
class WindowsButton implements Button {
@Override
public void render() {
System.out.println("Windows 按钮");
}
}
class WindowsInput implements Input {
@Override
public void render() {
System.out.println("Windows 输入框");
}
}
class MacButton implements Button {
@Override
public void render() {
System.out.println("Mac 按钮");
}
}
class MacInput implements Input {
@Override
public void render() {
System.out.println("Mac 输入框");
}
}
interface UiFactory {
Button createButton();
Input createInput();
}
class WindowsUiFactory implements UiFactory {
@Override
public Button createButton() {
return new WindowsButton();
}
@Override
public Input createInput() {
return new WindowsInput();
}
}
class MacUiFactory implements UiFactory {
@Override
public Button createButton() {
return new MacButton();
}
@Override
public Input createInput() {
return new MacInput();
}
}public class Demo3 {
public static void main(String[] args) {
UiFactory factory = new WindowsUiFactory();
factory.createButton().render();
factory.createInput().render();
}
}| 模式 | 优点 | 缺点 | 适用建议 |
|---|---|---|---|
| 简单工厂 | 上手快,代码集中 | 工厂类容易膨胀,违反开闭原则 | 小项目、类型变化少 |
| 工厂方法 | 符合开闭原则,易扩展 | 类数量增加 | 业务扩展频繁、插件化 |
| 抽象工厂 | 保证产品族一致性 | 抽象层次更复杂 | 多产品族、跨平台体系 |
Calendar.getInstance():工厂思想DocumentBuilderFactory.newInstance():工厂方法风格BeanFactory / FactoryBean:工厂思想落地ApplicationContext:对象获取入口,屏蔽创建细节flowchart LR
A["业务代码"] --> B["BeanFactory / ApplicationContext"]
B --> C["创建或获取 Bean"]
C --> D["返回接口类型对象"]
new)建议顺序: