工厂方法模式
工厂方法模式是一种创建型设计模式, 其在父类中提供一个创建对象的方法, 允许子类决定实例化对象的类型
1 2 3 4 5
| public interface Button { void render(); void onClick(Runnable f);
}
|
1 2 3 4 5 6 7 8 9 10 11 12
| public class WindowsButton implements Button{
@Override public void render() { }
@Override public void onClick(Runnable f) { } }
|
1 2 3 4 5 6 7 8 9 10 11 12
| public class HTMLButton implements Button{
@Override public void render() { }
@Override public void onClick(Runnable f) { } }
|
声明工厂抽象类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| abstract class Dialog { abstract Button createButton();
void render() { Button okButton = createButton(); okButton.onClick(this::closeDialog); okButton.render(); } private void closeDialog() {
} }
|
WebDialog实现抽象工厂
1 2 3 4 5 6
| public class WebDialog extends Dialog{ @Override Button createButton() { return new HTMLButton(); } }
|
WindowDialog实现抽象工厂
1 2 3 4 5 6
| public class WindowsDialog extends Dialog{ @Override Button createButton() { return new WindowsButton(); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| public class Application { private Dialog dialog;
void initialize() { Config config = readApplicationConfigFile(); if (config.getOS().equals("Windows")) { dialog = new WindowsDialog(); } else if (config.getOS().equals("Web")) { dialog = new WebDialog(); } else { System.out.println(config.getOS()); } } void main() { this.initialize(); dialog.render(); }
private static class Config { private String OS;
public String getOS() { return OS; }
public Config() { this.OS = System.getProperty("os.name"); } } private Config readApplicationConfigFile() { return new Config(); }
public static void main(String[] args) { Application application = new Application(); application.main(); } }
|
实现方式
让所有产品都遵循同一接口。 该接口必须声明对所有产品都有意义的方法。
在创建类中添加一个空的工厂方法。 该方法的返回类型必须遵循通用的产品接口。
在创建者代码中找到对于产品构造函数的所有引用。 将它们依次替换为对于工厂方法的调用, 同时将创建产品的代码移入工厂方法
如果应用中的产品类型太多, 那么为每个产品创建子类并无太大必要, 这时你也可以在子类中复用基类中的控制参数
如果代码经过上述移动后, 基础工厂方法中已经没有任何代码, 你可以将其转变为抽象类。 如果基础工厂方法中还有其他语句, 你可以将其设置为该方法的默认行为
工厂模式方法优缺点:
优点:你可以避免创建者和具体产品之间的紧密耦合
单一职责原则。 你可以将产品创建代码放在程序的单一位置, 从而使得代码更容易维护
开闭原则。 无需更改现有客户端代码, 你就可以在程序中引入新的产品类型
缺点:应用工厂方法模式需要引入许多新的子类, 代码可能会因此变得更复杂。 最好的情况是将该模式引入创建者类的现有层次结构中