抽象工厂模式(Abstract Factory Pattern)在工厂模式上添加了一个创建不同工厂的抽象接口(抽象类或接口实现),可称该接口为作“超级工厂”。在使用过程中,首先通过抽象接口创建出不同的工厂对象,然后根据不同的工厂对象创建不同的对象。
可以将工厂模式理解为针对一个产品维度进行分类,比如上述工厂模式下的苹果手机和华为手机;而抽象工厂模式针对的是多个产品维度分类,比如苹果公司既制造苹果手机也制造苹果笔记本电脑,同样,华为公司既制造华为手机也制造华为笔记本电脑。
在同一个厂商有多个维度的产品时,如果使用工厂模式,则势必会存在多个独立的工厂,这样的话,设计和物理世界是不对应的。正确的做法是通过抽象工厂模式来实现,我们可以将抽象工厂类比成厂商(苹果、华为),将通过抽象工厂创建出来的工厂类比成不同产品的生产线(手机生成线、笔记本电脑生产线),在需要生产产品时根据抽象工厂生产。
工厂模式定义了工厂方法来实现不同厂商手机的制造。可是问题来了,我们知道苹果公司和华为公司不仅制造手机,还制造电脑。如果使用工厂模式,就需要实现两个工厂类,并且这两个工厂类没有多大关系,这样的设计显然不够优雅,那么如何实现呢?使用抽象工厂就能很好地解决上述问题。我们定义一个抽象工厂,在抽象工厂中定义好要生产的产品(手机或者电脑),然后在抽象工厂的实现类中根据不同类型的产品和产品规格生产不同的产品返回给用户。UML的设计如下图:
UML的具体实现如下:
1、抽象工厂(超级工厂)
package cn.jaa.abstract_factory_pattern;
/**
* @Author: Jaa
* @Description: 超级工厂
* @Date 2023/11/27 22:51
*/
public abstract class AbstractFactory {
public abstract Phone createPhone(String brand);
public abstract Computer createComputer(String brand);
}
2、手机接口极其实现类
package cn.jaa.abstract_factory_pattern;
/**
* @Author: Jaa
* @Description: 手机接口
* @Date 2023/11/27 22:46
*/
public interface Phone {
String call();
}
package cn.jaa.abstract_factory_pattern;
/**
* @Author: Jaa
* @Description:
* @Date 2023/11/27 22:47
*/
public class PhoneApple implements Phone {
@Override
public String call() {
return "Call sb. by Apple phone...";
}
}
package cn.jaa.abstract_factory_pattern;
/**
* @Author:
* @Description:
* @Date 2023/11/27 22:48
*/
public class PhoneHuawei implements Phone {
@Override
public String call() {
return "Call sb. by Huawei phone...";
}
}
3、手机工厂类
package cn.jaa.abstract_factory_pattern;
/**
* @Author: Jaa
* @Description:
* @Date 2023/11/27 22:57
*/
public class PhoneFactory extends AbstractFactory{
@Override
public Phone createPhone(String phoneName) {
if ("Apple".equals(phoneName)) {
return new PhoneApple();
} else if ("Huawei".equals(phoneName)) {
return new PhoneHuawei();
} else {
return null;
}
}
@Override
public Computer createComputer(String brand) {
return null;
}
}
4、电脑接口及其实现类
package cn.jaa.abstract_factory_pattern;
/**
* @Author: Jaa
* @Description: 电脑接口
* @Date 2023/11/27 22:52
*/
public interface Computer {
String internet();
}
package cn.jaa.abstract_factory_pattern;
/**
* @Author: Jaa
* @Description:
* @Date 2023/11/27 22:54
*/
public class ComputerApple implements Computer{
@Override
public String internet() {
return "Surf the Internet by Apple computer...";
}
}
package cn.jaa.abstract_factory_pattern;
/**
* @Author: Jaa
* @Description:
* @Date 2023/11/27 22:55
*/
public class ComputerHuawei implements Computer{
@Override
public String internet() {
return "Surf the Internet by Huawei computer...";
}
}
5、电脑工厂
package cn.jaa.abstract_factory_pattern;
/**
* @Author: Jaa
* @Description:
* @Date 2023/11/27 22:59
*/
public class ComputerFactory extends AbstractFactory{
@Override
public Phone createPhone(String brand) {
return null;
}
@Override
public Computer createComputer(String computerName) {
if ("Apple".equals(computerName)) {
return new ComputerApple();
} else if ("Huawei".equals(computerName)) {
return new ComputerHuawei();
} else {
return null;
}
}
}
6、抽象工厂模式测试
package cn.jaa.abstract_factory_pattern;
import java.util.logging.Logger;
/**
* @Author: Jaa
* @Description: 抽象工厂模式测试
* @Date 2023/11/27 23:01
*/
public class AbstractFactoryDemoTest {
private static final Logger log = Logger.getLogger(String.valueOf(AbstractFactoryDemoTest.class));
public static void main(String[] args) {
AbstractFactory computerFactory = new ComputerFactory();
Computer macbook = computerFactory.createComputer("Apple");
Computer matebook = computerFactory.createComputer("Huawei");
log.info(macbook.internet());
log.info(matebook.internet());
AbstractFactory phoneFactory = new PhoneFactory();
Phone apple = phoneFactory.createPhone("Apple");
Phone huawei = phoneFactory.createPhone("Huawei");
log.info(apple.call());
log.info(huawei.call());
}
}
打印结果如下: