工厂模式(Factory Pattern)是 Java中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
1. 简单工厂模式
公共的接口 Phone.java
public interface Phone {
void doSome();
}
具体的产品 Xiaomi.java
public class Xiaomi implements Phone {
@Override
public void doSome() {
System.out.println("Xiaomi phone");
}
}
具体的产品 Apple.java
public class Apple implements Phone {
@Override
public void doSome() {
System.out.println("Apple phone");
}
}
工厂类 PhoneFactory.java
public class PhoneFactory {
public Phone getPhone(String type) {
if ("XIAOMI".equalsIgnoreCase(type)) {
return new Xiaomi();
}
if ("APPLE".equalsIgnoreCase(type)) {
return new Apple();
}
return null;
}
}
测试类 Demo.java
public class Demo {
public static void main(String[] args) {
PhoneFactory phoneFactory = new PhoneFactory();
Phone xiaomiPhone = phoneFactory.getPhone("Xiaomi");
Phone applePhone = phoneFactory.getPhone("Apple");
xiaomiPhone.doSome();
applePhone.doSome();
}
}
运行结果
优点:我们通过名称即可获取到具体的实例对象,实现简单
缺点:当我们想增加一个品牌的手机时,需要在工厂中新增 if 逻辑,不符合OCP原则
2. 抽象方法模式
工厂方法模式定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
- 抽象工厂:声明了工厂方法的接口。
- 具体产品工厂:实现工厂方法的接口,负责创建产品对象。
- 产品抽象类或接口:定义工厂方法所创建的产品对象的接口。
- 具体产品实现:具有统一父类的具体类型的产品。
抽象工厂 Factory.java
public interface Factory {
Phone makePhone();
}
公共接口 Phone.java
public interface Phone {
void doSome();
}
具体类 Xiaomi.java
public class Xiaomi implements Phone {
@Override
public void doSome() {
System.out.println("Xiaomi Phone");
}
}
具体类 Xiaomi对应的工厂
public class XiaomiFactory implements Factory {
@Override
public Phone makePhone() {
return new Xiaomi();
}
}
具体类 Apple.java
public class Apple implements Phone {
@Override
public void doSome() {
System.out.println("Apple Phone");
}
}
具体类 Apple 对应的工厂类
public class AppleFactory implements Factory {
@Override
public Phone makePhone() {
return new Apple();
}
}
测试类 Demo.java
public class Demo {
public static void main(String[] args) throws Exception {
Factory xiaomiFactory = (XiaomiFactory) Class.forName("factorymode.mode02.XiaomiFactory").newInstance();
Factory appleFactory = (AppleFactory) Class.forName("factorymode.mode02.AppleFactory").newInstance();
Phone xiaomiPhone = xiaomiFactory.makePhone();
Phone applePhone = appleFactory.makePhone();
xiaomiPhone.doSome();
applePhone.doSome();
}
}
运行结果
优点:扩展性好,当增加一个品牌的手机时,可以增加一个工厂和具体类
缺点:每一个品牌对应一个工厂类,当业务比较复杂,涉及到的类非常多时,就会使类的数量成倍的增加
3. 抽象工厂模式
为了缩减工厂实现子类的数量,不必给每一个产品分配一个工厂类,可以将产品进行分组,每组中的不同产品由同一个工厂类的不同方法来创建。
公共接口 Phone.java
public interface Phone {
void doSome();
}
公共接口 Computer.java
public interface Computer {
void doOther();
}
具体类 XiaomiPhone.java
public class XiaomiPhone implements Phone {
@Override
public void doSome() {
System.out.println("Xiaomi Phone");
}
}
具体类 ApplePhone.java
public class ApplePhone implements Phone {
@Override
public void doSome() {
System.out.println("Apple Phone");
}
}
具体类 XiaomiComputer.java
public class XiaomiComputer implements Computer {
@Override
public void doOther() {
System.out.println("Xiaomi Computer");
}
}
具体类 AppleComputer.java
public class AppleComputer implements Computer {
@Override
public void doOther() {
System.out.println("Apple Computer");
}
}
抽象工厂 AbstractFactory.java
public interface AbstractFactory {
Phone makePhone();
Computer makeComputer();
}
具体工厂 XiaomiFactory.java
public class XiaomiFactory implements AbstractFactory {
@Override
public Phone makePhone() {
return new XiaomiPhone();
}
@Override
public Computer makeComputer() {
return new XiaomiComputer();
}
}
具体工厂 AppleFactory.java
public class AppleFactory implements AbstractFactory {
@Override
public Phone makePhone() {
return new ApplePhone();
}
@Override
public Computer makeComputer() {
return new AppleComputer();
}
}
测试类 Demo.java
public class Demo {
public static void main(String[] args) throws Exception {
AbstractFactory xiaomiFactory = (XiaomiFactory) Class.forName("factorymode.mode03.XiaomiFactory").newInstance();
AbstractFactory appleFactory = (AppleFactory) Class.forName("factorymode.mode03.AppleFactory").newInstance();
Phone xiaomiPhone = xiaomiFactory.makePhone();
Phone applePhone = appleFactory.makePhone();
Computer xiaomiComputer = xiaomiFactory.makeComputer();
Computer appleComputer = appleFactory.makeComputer();
xiaomiPhone.doSome();
applePhone.doSome();
xiaomiComputer.doOther();
appleComputer.doOther();
}
}
运行结果
优点:将产品以品牌进行分组,减少了工厂类的数量,一个工厂类对应一个品牌,一个品牌对应着几类产品
总结
- 简单工厂:唯一工厂类,一个产品抽象类,工厂类的创建方法依据传入参数判断并创建具体产品对象。
- 工厂方法:多个工厂类,一个产品抽象类,利用多态创建不同的产品对象,避免了大量的if-else判断。
- 抽象工厂:多个工厂类,多个产品抽象类,产品根据品牌分组,同一个工厂实现类创建同一品牌中的不同产品,减少了工厂子类的数量。