简单工厂模式
-
简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。
-
简单工厂模式(静态工厂模式):定义了一个创建对象的类,由这个类来封装实例化对象的行为(代码)
-
在软件开发中,当我们会用到大量的创建某种、某类或者某批对象时,就会使用到工厂模式.
注意:简单工厂模式不是23中设计模式之一
-
优点
-
工厂类包含必要的逻辑判断,可以决定在什么时候创建哪一个产品的实例。客户端可以免除直接创建产品对象的职责,很方便的创建出相应的产品。工厂和产品的职责区分明确。
-
客户端无需知道所创建具体产品的类名,只需知道参数即可。
-
也可以引入配置文件,在不修改客户端代码的情况下更换和添加新的具体产品类。
-
-
缺点
- 简单工厂模式的工厂类单一,负责所有产品的创建,职责过重,一旦异常,整个系统将受影响。且工厂类代码会非常臃肿,违背高聚合原则。
- 使用简单工厂模式会增加系统中类的个数(引入新的工厂类),增加系统的复杂度和理解难度
- 系统扩展困难,一旦增加新产品不得不修改工厂逻辑,在产品类型较多时,可能造成逻辑过于复杂
- 简单工厂模式使用了 static 工厂方法,造成工厂角色无法形成基于继承的等级结构。
应用场景
-
对于产品种类相对较少的情况
-
只知道传入工厂类的参数,不关心如何创建对象的逻辑
案例
public interface Car {
void name();
}
// 产品1
public class Tesla implements Car {
@Override
public void name() {
System.out.println("特斯拉");
}
}
// 产品1
public class WuLing implements Car {
@Override
public void name() {
System.out.println("五菱");
}
}
// 当我们再添加一个产品,要修改CarFactory中的代码,违反了开闭原则
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){
// 使用new创建对象
// Car car1 = new Tesla();
// Car car2 = new WuLing();
// 通过简单工厂模式创建
Car car1 = CarFactory.getCar("五菱");
Car car2 = CarFactory.getCar("特斯拉");
car1.name();
car2.name();
}
}
工厂方法模式
用来生产同一等级结构中的固定产品(支持增加任意产品)
案例
public interface Car {
void name();
}
// 工厂方法
public interface CarFactory {
Car getCar();
}
public class BaoMa implements Car {
@Override
public void name() {
System.out.println("宝马");
}
}
public class BaoMaFactory implements CarFactory {
@Override
public Car getCar() {
return new BaoMa();
}
}
public class Tesla implements Car {
@Override
public void name() {
System.out.println("特斯拉");
}
}
public class TeslaFactory implements CarFactory {
@Override
public Car getCar() {
return new Tesla();
}
}
public class WuLing implements Car {
@Override
public void name() {
System.out.println("五菱");
}
}
public class WuLingFactory implements CarFactory{
@Override
public Car getCar() {
return new WuLing();
}
}
public class Consumer {
public static void main(String[] args){
// 通过工厂方法模式创建
Car car1 = new WuLingFactory().getCar();
Car car2 = new TeslaFactory().getCar();
// 添加新的产品,不需要修改之前的代码
Car car3 = new BaoMaFactory().getCar();
car1.name();
car2.name();
car3.name();
}
}
抽象工厂模式
抽象工厂模式提供了一个创建一系列相关或者相互依赖对象的接口,无需指定它们具体的类
适用场景
-
客户端(应用层)不依赖于产品类实例如何被创建、实现等细节
-
强调一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量的重复代码
-
提供一个产品类的库,所有的产品以同样的接口出现,从而使得客户端不依赖于具体的实现
优点
- 具体产品在应用层的代码隔离,无需关心创建的细节
- 将一个系列的产品统一到一起创建
缺点
- 规定了所有可能被创建的产品集合,产品簇中扩展新的产品困难
- 增加了系统的抽象性和理解难度
案例
public interface IPhoneProduct {
void start();
void shutdown();
void callUp();
void sendEmail();
}
public interface IRouterProduct {
void start();
void shutdown();
void setWife();
void setting();
}
// 抽象产品工厂
public interface ProductFactory {
// 生产手机
IPhoneProduct iphoneProduct();
// 生产路由器
IRouterProduct iRouterProduct();
}
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 sendEmail() {
System.out.println("小米手机 发短信");
}
}
public class HuaweiiPhone 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 sendEmail() {
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 setWife() {
System.out.println("小米路由器 设置wife");
}
@Override
public void setting() {
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 setWife() {
System.out.println("华为路由器 设置wife");
}
@Override
public void setting() {
System.out.println("华为路由器 相关设置");
}
}
public class XiaomiProductFactory implements ProductFactory {
@Override
public IPhoneProduct iphoneProduct() {
return new XiaomiPhone();
}
@Override
public IRouterProduct iRouterProduct() {
return new XiaomiRouter();
}
}
public class HuaweiProductFactory implements ProductFactory {
@Override
public IPhoneProduct iphoneProduct() {
return new HuaweiiPhone();
}
@Override
public IRouterProduct iRouterProduct() {
return new HuaweiRouter();
}
}
// 测试
public class Client {
public static void main(String[] args){
System.out.println("===== 小米系列产品 =====");
XiaomiProductFactory xiaomiProductFactory = new XiaomiProductFactory();
IPhoneProduct iPhoneProduct = xiaomiProductFactory.iphoneProduct();
iPhoneProduct.start();
iPhoneProduct.callUp();
iPhoneProduct.sendEmail();
IRouterProduct routerProduct = xiaomiProductFactory.iRouterProduct();
routerProduct.start();
routerProduct.setWife();
routerProduct.setting();
System.out.println("===== 华为系列产品 =====");
HuaweiProductFactory huaweiProductFactory = new HuaweiProductFactory();
IPhoneProduct iPhoneProduct2 = huaweiProductFactory.iphoneProduct();
iPhoneProduct2.start();
iPhoneProduct2.callUp();
iPhoneProduct2.sendEmail();
IRouterProduct routerProduct2 = huaweiProductFactory.iRouterProduct();
routerProduct2.start();
routerProduct2.setWife();
routerProduct2.setting();
}
}
小结
- 简单工厂模式(静态工厂模式)
虽然某种程度上不符合设计原则,但实际使用最多 - 工厂方法模式
不修改已有类的前提下,通过增加新的工厂类实现扩展。 - 抽象工厂模式
不可以增加产品,可以增加产品族