工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式。著名的Jive论坛 ,就大量使用了工厂模式,工厂模式在Java程序系统可以说是随处可见。因为工厂模式就相当于创建实例对象的new,我们经常要根据类Class生成实例对象,如A a=new A() 工厂模式也是用来创建实例对象的,所以以后new时就要多个心眼,是否可以考虑使用工厂模式,虽然这样做,可能多做一些工作,但会给你系统带来更大的可扩展性和尽量少的修改量。
核心本质:
1.实现化对象不能使用new,用工厂方法代替。
2.将选择实现类,创建对象统一管理和控制。从而将调用者跟我们的实现类解耦。
三种模式:
1.简单工厂模式
- 用来生产同一等级结构中的任意产品(对于增加新的产品,需要覆盖已有代码)。
2.工厂方法模式
- 用来生产同一等级结构中的固定产品(支持增加任意产品)。
3.抽象工厂模式
- 围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。
车接口:
public interface Car {
void name();
}
实现接口类:
public class Tesla implements Car{
@Override
public void name() {
System.out.println("特斯拉");
}
}
public class WuLing implements Car{
@Override
public void name() {
System.out.println("五菱宏光");
}
}
车工厂类:
public class CarFactory {
public static Car getCar(String car){
if(car.equals("五菱")){
return new WuLing();
}else if(car.equals("特斯拉")){
return new Tesla();
}else{
return null;
}
}
}
测试类:
public class Consumer {
public static void main(String[] args) {
//接口,所有的实现类!工厂
// Car car = new WuLing();
// Car car1 = new Tesla();
//2.使用工厂创建
Car car = CarFactory.getCar("五菱");
Car car2 = CarFactory.getCar("特斯拉");
car.name();
car2.name();
}
}
如果我们要增加车,还得修改车工厂中的原有代码,是不符合我们的开闭原则,便产生了第二种模式工厂方法模式
工厂方法模式车接口:
public interface Car {
void name();
}
实现接口类:
public class Tesla implements Car{
@Override
public void name() {
System.out.println("特斯拉");
}
}
public class WuLing implements Car{
@Override
public void name() {
System.out.println("五菱宏光");
}
}
车工厂接口类:
public interface CarFactory {
Car getCar();
}
五菱宏光车工厂:
public class WuLingFactory implements CarFactory{
@Override
public Car getCar() {
return new WuLing();
}
}
特斯拉车工厂
public class TeslaFactory implements CarFactory{
@Override
public Car getCar() {
return new Tesla();
}
}
测试类:
public class Consumer {
public static void main(String[] args) {
Car car1 = new WuLingFactory().getCar();
Car car2 = new TeslaFactory().getCar();
car1.name();
car2.name();
}
}
工厂方法模式,在原来的简单工厂模式增加了一个车工厂的接口,每一种车都有自己的车工厂,如果要增加其他种类的车只需实现车接口和车工厂接口即可。满足了开闭原则。
抽象工厂模式**定义:**抽象工厂模式提供了一个创建一系列相关或者相互依赖对象的接口,无需指定他们具体的类。
适用场景
客户端(应用层)不依赖于产品类实例如何被创建、实现等细节。
强调一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量的重复代码。
提供一个产品类的库,所有的产品以同样的接口出现,从而使得客户端不依赖于具体的实现。
优点
- 可以在类的内部对产品族中相关联的多等级产品共同管理,而不必专门引入多个新的类来进行管理。
- 当需要产品族时,抽象工厂可以保证客户端始终只使用同一个产品的产品组。
- 抽象工厂增强了程序的可扩展性,当增加一个新的产品族时,不需要修改原代码,满足开闭原则。
缺点
- 当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。
- 增加了系统的抽象性和理解难度。
抽象工厂模式的主要角色如下。
-
抽象工厂(Abstract Factory):提供了创建产品的接口,它包含多个创建产品的方法 newProduct(),可以创建多个不同等级的产品。
-
具体工厂(Concrete Factory):主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建。
-
抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。
-
具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间是多对一的关系。
抽象工厂模式的主要角色如下。
前面介绍的工厂方法模式中考虑的是一类产品的生产,如畜牧场只养动物、电视机厂只生产电视机、计算机软件学院只培养计算机软件专业的学生等。
同种类称为同等级,也就是说:工厂方法模式中只考虑生产同等级的产品,但是在现实生活中许多工厂是综合型的工厂,能生产多等级(种类) 的产品,如农场里既养动物又种植物,电器厂既生产电视机又生产洗衣机或空调,大学既有软件专业又有生物专业等。
本节要介绍的抽象工厂模式将考虑多等级产品的生产,将同一个具体工厂所生产的位于不同等级的一组产品称为一个产品族,如下图所示的是小米工厂和 华为工厂所生产的手机与路由器对应的关系图。
具体代码演示:
//手机产品接口
public interface IphoneProduct {
void start();
void shutdown();
void callUp();
void sendSMS();
}
//路由器接口
public interface IRouterProduct {
void start();
void shutdown();
void openWife();
void setting();
}
//抽象产品工厂
public interface IProductFactory {
//生产手机
IphoneProduct iphoneProduct();
//生产路由器
IRouterProduct irouterproduct();
}
//华为手机
public class HuaweiPhone implements IphoneProduct{
@Override
public void start() {
System.out.println("开启华为手机");
}
@Override
public void shutdown() {
System.out.println("关闭华为手机");
}
@Override
public void callUp() {
System.out.println("华为打电话");
}
@Override
public void sendSMS() {
System.out.println("华为发短信");
}
}
//华为路由器
public class HuaweiRouter implements IRouterProduct{
@Override
public void start() {
System.out.println("启动华为路由器");
}
@Override
public void shutdown() {
System.out.println("关闭华为路由器");
}
@Override
public void openWife() {
System.out.println("打开华为Wifi");
}
@Override
public void setting() {
System.out.println("华为设置");
}
}
//华为产品工厂
public class HuaweiFactory implements IProductFactory{
@Override
public IphoneProduct iphoneProduct() {
return new HuaweiPhone();
}
@Override
public IRouterProduct irouterproduct() {
return new HuaweiRouter();
}
}
//小米手机
public class XiaomiPhone implements IphoneProduct{
@Override
public void start() {
System.out.println("开启小米手机");
}
@Override
public void shutdown() {
System.out.println("关闭小米手机");
}
@Override
public void callUp() {
System.out.println("小米打电话");
}
@Override
public void sendSMS() {
System.out.println("小米发短信 ");
}
}
//小米路由器
public class XiaomiRouter implements IRouterProduct{
@Override
public void start() {
System.out.println("启动小米路由器");
}
@Override
public void shutdown() {
System.out.println("关闭小米路由器");
}
@Override
public void openWife() {
System.out.println("打开小米Wifi");
}
@Override
public void setting() {
System.out.println("小米设置");
}
}
//小米产品工厂
public class XiaomiFactory implements IProductFactory{
@Override
public IphoneProduct iphoneProduct() {
return new XiaomiPhone();
}
@Override
public IRouterProduct irouterproduct() {
return new XiaomiRouter();
}
}
测试类:
public class Client {
public static void main(String[] args) {
System.out.println("===========小米系列产品=========");
//小米工厂
XiaomiFactory xiaomiFactory = new XiaomiFactory();
IphoneProduct iphoneProduct = xiaomiFactory.iphoneProduct();
iphoneProduct.callUp();
iphoneProduct.sendSMS();
IRouterProduct irouterproduct = xiaomiFactory.irouterproduct();
irouterproduct.openWife();
System.out.println("===========华为系列产品=========");
//华为工厂
HuaweiFactory huaweiFactory = new HuaweiFactory();
iphoneProduct = huaweiFactory.iphoneProduct();
iphoneProduct.callUp();
iphoneProduct.sendSMS();
irouterproduct = huaweiFactory.irouterproduct();
irouterproduct.openWife();
}
}



