简单工厂模式、工厂方法模式、抽象工厂模式
前言
简单工厂模式、工厂方法模式、抽象工厂模式,关联比较大 因此这里放在一起总结下。方便比较,容易理解和区分。
这3种模式也都是一种创建型模式(创建型模式提供了创建对象的机制,能够提升已有代码的灵活性和可复用性。)
先做个简单比较,有个大致了解,下面再通过例子具体说明
简单工厂模式 | 工厂方法模式 | 抽象工厂模式 |
---|---|---|
违背开闭原则,不属于GoF的23种设计模式 | 属于 | 属于 |
只有三部分:产品接口,产品实现,工厂实现 | 四要素:产品接口,产品实现,工厂接口,工厂实现 | 具有工厂方法模式同样的四要素 |
单一产品 | 单一产品 | 多种层次结构的一系列产品 |
优点:屏蔽产品的具体实现,调用者只关心产品的接口 | 同左 | 同左 |
优点:产品实例化被封装,依赖工厂生成实例 | 同左 | 同左 |
优点:降低耦合,避免了调用者与产品之间的耦合 | 同左 | 同左 |
优点:扩展性高 | 同左 | 同左 |
不足:引入新的子类,使代码变复杂 | 同左 | 同左 |
简单工厂模式(Simple Factory)
概述
简单工厂模式,是由一个工厂决定创建哪一类产品的实例。
实现:demo
下面demo是,通过工厂类PhoneFactory获取Phone对象,通过参数type实例化不同的Phone对象。
产品接口:可以是抽象类也可以是接口,这里使用了抽象类
public abstract class Phone {
void myBrand() {}
}
产品实现:两个产品苹果手机、华为手机
public class ApplePhone extends Phone {
@Override
public void myBrand() {
System.out.println("苹果:iPhoneX");
}
}
public class HuaWeiPhone extends Phone {
@Override
public void myBrand() {
System.out.println("华为:P40");
}
}
工厂类:比如富士康,同时代工生产 华为和苹果手机。
public class PhoneFactory {
public static final int NO_PHONE = -1;
public static final int HUAWEI = 1;
public static final int APPLE = 2;
public Phone getPhone(int type) {
Phone phone = null;
switch (type) {
case HUAWEI:
phone = new HuaWeiPhone();
break;
case APPLE:
phone = new ApplePhone();
break;
case NO_PHONE:
default:
break;
}
return phone;
}
}
调用demo:使用工厂类,通过参数创建和获取不同的产品实例。
public class SimplyFactoryTest {
public static void main(String[] args) {
PhoneFactory phoneFactory = new PhoneFactory();
Phone huawei = phoneFactory.getPhone(PhoneFactory.HUAWEI);
huawei.myBrand();
Phone apple = phoneFactory.getPhone(PhoneFactory.APPLE);
apple.myBrand();
}
}
打印的信息如下:
华为:P40
苹果:iPhoneX
总结
简单工厂模式 违背了开闭原则,因此不属于GoF里的23种设计模式。他可以看作工厂模式的简化,没有工厂的接口。
开闭原则简单的说就是对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码。这里的不符合是因为:假如新增一个产品,则需要修改工厂类的条件。
工厂方法模式(Factory Method)
概述
工厂方法模式,可以看作简单工厂模式的演进。解决了简单工厂存在的问题:新增一个产品 需要修改工厂类条件。
它定义一个工厂接口(一个java接口或抽象类),让其子类自己决定实例化对象的类型,使其创建过程(由上面的工厂类)延迟到子类进行。
工厂方法模式核心结构有四个角色,分别是工厂接口;工厂实现;产品接口;产品实现。(简单工厂模式只有3个,没有工厂接口)。
实现:demo
产品接口和产品实现同简单工厂模式一样(即上面的Phone、ApplePhone 、HuaWeiPhone类),这里不再重复列出。
工厂接口(抽象工厂):
public interface IFactory {
Phone productPhone();
}
工厂实现:华为工厂生产华为手机、苹果工厂生产苹果手机。
public class HuaWeiFactory implements IFactory {
@Override
public Phone productPhone() {
return new HuaWei();
}
}
public class AppleFactory implements IFactory {
@Override
public Phone productPhone() {
return new Apple();
}
}
调用demo:
public class FactoryMethodTest {
public static void main(String[] args) {
IFactory huaWeiFactory = new HuaWeiFactory();
huaWeiFactory.productPhone().myBrand();
IFactory appleFactory = new AppleFactory();
appleFactory.productPhone().myBrand();
}
}
结果:
华为:P40
苹果:iPhoneX
总结
当新增一个产品,如小米手机:我们只需新增一个XiaoMiPhone(继承Phone),一个XiaoMiFactory(实现IFactory)即可。
这样不会对原有代码有任何影响,但每增加一个产品,就需要增加一个产品实现、一个工厂实现,增加了代码量。
抽象工厂模式(Abstract Factory)
概述
抽象工厂模式,是针对多个产品(也是一系列的产品)。它定义了一个接口用于创建相关或有依赖关系的产品簇,而无需明确指定产品类。
比如,将factory理解成公司 即是华为公司、苹果公司。他们都设计生产手机和电脑等一系列产品。 你从华为公司,只会拿到华为的手机和电脑等、不会拿到苹果的产品。
实现:demo
基于上面工厂方法模式(已有的手机产品及工厂,Phone、ApplePhone 、HuaWeiPhone、HuaWeiFactory、AppleFactory类)
产品接口:新产品电脑
public interface IComputer {
void computerName();
}
产品实现:苹果电脑、华为电脑
public class AppleComputer implements IComputer {
@Override
public void computerName() {
System.out.println("苹果:MacBook Pro");
}
}
public class HuaWeiComputer implements IComputer {
@Override
public void computerName() {
System.out.println("华为:MateBook X Pro");
}
}
抽象工厂:声明生产一系列抽象产品的方法
public interface IFactory {
Phone productPhone();
IComputer productComputer();
}
工厂实现:一个公司生产一系列产品,苹果公司设计生产苹果手机、苹果电脑;华为公司设计生产华为手机、华为电脑。
public class AppleFactory implements IFactory {
@Override
public Phone productPhone() {
return new ApplePhone();
}
@Override
public IComputer productComputer() {
return new AppleComputer();
}
}
public class HuaWeiFactory implements IFactory {
@Override
public Phone productPhone() {
return new HuaWeiPhone();
}
@Override
public IComputer productComputer() {
return new HuaWeiComputer();
}
}
调用demo:
public class AbstractFactoryTest {
public static void main(String[] args) {
IFactory huaWeiFactory = new HuaWeiFactory();
huaWeiFactory.productPhone().myBrand();
huaWeiFactory.productComputer().computerName();
IFactory appleFactory = new AppleFactory();
appleFactory.productPhone().myBrand();
appleFactory.productComputer().computerName();
}
}
打印结果:
华为:P40
华为:MateBook X Pro
苹果:iPhoneX
苹果:MacBook Pro
总结
同一系列产品容易添加,像工厂方法模式一样。如小米公司:我们只需再新增一个XiaoMiPhone(继承Phone),一个XiaoMiComputer(实现IComputer),一个XiaoMiFactory(实现IFactory)即可。
产品簇中增加个新产品很难,如再增加个手表(Watch),需要新增手表的产品接口和实现,这是抽象工厂和工厂实现都需要进行修改。