1、简单工厂
使用:
代码语言:javascript复制public interface Keyboard {
void print();
void input(Context context);
}
class HPKeyboard implements Keyboard {
@Override
public void print() {
//...输出逻辑;
}
@Override
public void input(Context context) {
//...输入逻辑;
}
}
class DellKeyboard implements Keyboard {
@Override
public void print() {
//...输出逻辑;
}
@Override
public void input(Context context) {
//...输入逻辑;
}
}
class LenovoKeyboard implements Keyboard {
@Override
public void print() {
//...输出逻辑;
}
@Override
public void input(Context context) {
//...输入逻辑;
}
}
/**
* 工厂
*/
public class KeyboardFactory {
public Keyboard getInstance(int brand) {
if(BrandEnum.HP.getCode() == brand){
return new HPKeyboard();
} else if(BrandEnum.LENOVO.getCode() == brand){
return new LenovoKeyboard();
} else if(BrandEnum.DELL.getCode() == brand){
return new DellKeyboard();
}
return null;
}
public static void main(String[] args) {
KeyboardFactory keyboardFactory = new KeyboardFactory();
Keyboard lenovoKeyboard = KeyboardFactory.getInstance(BrandEnum.LENOVO.getCode());
//...
}
}
缺点:
上面的工厂实现是一个具体的类KeyboardFactory,而非接口或者抽象类,getInstance()方法利用if-else创建并返回具体的键盘实例,如果增加新的键盘子类,键盘工厂的创建方法中就要增加新的if-else。这种做法扩展性差,违背了开闭原则,也影响了可读性。所以,这种方式使用在业务较简单,工厂类不会经常更改的情况。
2、工厂方法
为了解决上面提到的"增加if-else"的问题,可以为每一个键盘子类建立一个对应的工厂子类,这些工厂子类实现同一个抽象工厂接口。这样,创建不同品牌的键盘,只需要实现不同的工厂子类。当有新品牌加入时,新建具体工厂继承抽象工厂,而不用修改任何一个类。
使用
代码语言:javascript复制public interface IKeyboardFactory {
Keyboard getInstance();
}
public class HPKeyboardFactory implements IKeyboardFactory {
@Override
public Keyboard getInstance(){
return new HPKeyboard();
}
}
public class LenovoFactory implements IKeyboardFactory {
@Override
public Keyboard getInstance(){
return new LenovoKeyboard();
}
}
public class DellKeyboardFactory implements IKeyboardFactory {
@Override
public Keyboard getInstance(){
return new DellKeyboard();
}
}
缺点
每一种品牌对应一个工厂子类,在创建具体键盘对象时,实例化不同的工厂子类。但是,如果业务涉及的子类越来越多,难道每一个子类都要对应一个工厂类吗?这样会使得系统中类的个数成倍增加,增加了代码的复杂度。
3、抽象工厂
为了缩减工厂实现子类的数量,不必给每一个产品分配一个工厂类,可以将产品进行分组,每组中的不同产品由同一个工厂类的不同方法来创建。
例如,键盘、主机这2种产品可以分到同一个分组——电脑,而不同品牌的电脑由不同的制造商工厂来创建。
使用
代码语言:javascript复制public interface Keyboard {
void print();
}
public class DellKeyboard implements Keyboard {
@Override
public void print() {
//...dell...dell;
}
}
public class HPKeyboard implements Keyboard {
@Override
public void print() {
//...HP...HP;
}
}
public interface Monitor {
void play();
}
public class DellMonitor implements Monitor {
@Override
public void play() {
//...dell...dell;
}
}
public class HPMonitor implements Monitor {
@Override
public void play() {
//...HP...HP;
}
}
public interface MainFrame {
void run();
}
public class DellMainFrame implements MainFrame {
@Override
public void run() {
//...dell...dell;
}
}
public class HPMainFrame implements MainFrame {
@Override
public void run() {
//...HP...HP;
}
}
//工厂类。工厂分为Dell工厂和HP工厂,各自负责品牌内产品的创建
public interface IFactory {
MainFrame createMainFrame();
Monitor createMainFrame();
Keyboard createKeyboard();
}
public class DellFactory implements IFactory {
@Override
public MainFrame createMainFrame(){
MainFrame mainFrame = new DellMainFrame();
//...造一个Dell主机;
return mainFrame;
}
@Override
public Monitor createMonitor(){
Monitor monitor = new DellMonitor();
//...造一个Dell显示器;
return monitor;
}
@Override
public Keyboard createKeyboard(){
Keyboard keyboard = new DellKeyboard();
//...造一个Dell键盘;
return Keyboard;
}
}
public class HPFactory implements IFactory {
@Override
public MainFrame createMainFrame(){
MainFrame mainFrame = new HPMainFrame();
//...造一个HP主机;
return mainFrame;
}
@Override
public Monitor createMonitor(){
Monitor monitor = new HPMonitor();
//...造一个HP显示器;
return monitor;
}
@Override
public Keyboard createKeyboard(){
Keyboard keyboard = new HPKeyboard();
//...造一个HP键盘;
return Keyboard;
}
}
//客户端代码。实例化不同的工厂子类,可以通过不同的创建方法创建不同的产品
public class Main {
public static void main(String[] args) {
IFactory dellFactory = new DellFactory();
IFactory HPFactory = new HPFactory();
//创建戴尔键盘
Keyboard dellKeyboard = dellFactory.createKeyboard();
//...
}
}
优缺点:
增加分组非常简单,例如要增加Lenovo分组,只需创建Lenovo工厂和具体的产品实现类。分组中的产品扩展非常困难,要增加一个鼠标Mouse,既要创建抽象的Mouse接口, 又要增加具体的实现:DellMouse、HPMouse, 还要再每个Factory中定义创建鼠标的方法实现。
总结:
简单工厂:唯一工厂类,一个产品抽象类,工厂类的创建方法依据入参判断并创建具体产品对象。工厂方法:多个工厂类,一个产品抽象类,利用多态创建不同的产品对象,避免了大量的if-else判断。抽象工厂:多个工厂类,多个产品抽象类,产品子类分组,同一个工厂实现类创建同组中的不同产品,减少了工厂子类的数量。