参考:《HeadFirst设计模式》
1.工厂模式存在的意义
工厂存在的意义是:高效的制造某一类产品。
工厂模式存在的意义是:高效的创建某一类对象。
工厂模式有很多种,本文只介绍以下三种:
简单工厂模式
,又称静态工厂模式
。工厂方法模式
,全称多个工厂方法模式
。抽象工厂模式
。
本文以`手机制造工厂生产手机为场景来学习工厂模式。
- 手机有两种:苹果手机和安卓手机。
- 手机制造工厂分别可以制造上述两种手机。
2.关于手机
关于手机的编码不过多的叙述,就是很简单的一个父抽象类加两个子实现类的关系。
父抽象手机类:Phone
/** * <p>手机</P> * * @author hanchao */
@Getter
@Setter
@AllArgsConstructor
public abstract class Phone {
private String name;
/** * 打个电话测试一下 */
public abstract void callTest();
}
子实现类:苹果手机:ApplePhone
/** * <p>苹果手机</P> * * @author hanchao */
@Slf4j
public class ApplePhone extends Phone {
public ApplePhone() {
super("苹果手机");
}
@Override
public void callTest() {
log.info("使用[" + super.getName() + "]给13322224444打电话.");
}
}
子实现类:安卓手机:AndroidPhone
/** * <p>安卓手机</P> * * @author hanchao */
@Slf4j
public class AndroidPhone extends Phone {
public AndroidPhone() {
super("安卓手机");
}
@Override
public void callTest() {
log.info("使用[" + super.getName() + "]给15533335555打电话.");
}
}
3.简单/静态工厂模式
简单工厂模式:一般情况下,创建对象的方法需要传入代表类型的参数type,然后再通过if-else或者switch语句根据type创建对应的对象。
直接上代码:PhoneFactory
/** * <p>简单工厂:手机工厂</P> * * @author hanchao */
public class PhoneFactory {
public static final int TYPE_APPLE = 1;
public static final int TYPE_ANDROID = 2;
/** * 简单工厂:一般情况下,创建对象的方法需要传入代表类型的参数type,然后再通过if-else或者switch语句根据type创建对应的对象。 */
public static Phone producePhone(int type) {
Phone phone;
switch (type) {
case TYPE_APPLE:
//制造一个苹果手机
phone = new ApplePhone();
break;
case TYPE_ANDROID:
//制造一个安卓手机
phone = new AndroidPhone();
break;
default:
throw new IllegalArgumentException("此型号手机暂不制造!");
}
return phone;
}
}
-
简单工厂的机制很简单:根据传入的类型,创建对应的对象。
-
这里将可用的类型编写成了静态变量,这用能在一定程度上减少出错的可能。
然后,写一个简单的测试类:SimpleFactoryDemo
/** * <p>1.简单工厂模式</P> * * @author hanchao */
public class SimpleFactoryDemo {
public static void main(String[] args) {
//某客户下了一笔大单子,要求制造2台苹果手机和1台安卓手机
//于是手机工厂开始了制造
//先来一台苹果手机
Phone phone = PhoneFactory.producePhone(PhoneFactory.TYPE_APPLE);
//测试一下
phone.callTest();
//再来一台苹果手机
phone = PhoneFactory.producePhone(PhoneFactory.TYPE_APPLE);
//测试一下
phone.callTest();
//再来一台安卓手机
phone = PhoneFactory.producePhone(PhoneFactory.TYPE_ANDROID);
//测试一下
phone.callTest();
}
}
运行结果:
2019-06-30 15:03:10,353 INFO [main-1] pers.hanchao.designpattern.factory.simple.telephone.ApplePhone:19 - 使用[苹果手机]给13322224444打电话.
2019-06-30 15:03:10,357 INFO [main-1] pers.hanchao.designpattern.factory.simple.telephone.ApplePhone:19 - 使用[苹果手机]给13322224444打电话.
2019-06-30 15:03:10,358 INFO [main-1] pers.hanchao.designpattern.factory.simple.telephone.AndroidPhone:19 - 使用[安卓手机]给15533335555打电话.
3.1.简单/静态工厂模式的总结
**简单工厂:**一般情况下,创建对象的方法需要传入代表类型的参数type,然后再通过if-else或者switch语句根据type创建对应的对象。
通常提供的创建对象的方法是静态的
,所以简单工厂模式
也称之为静态工厂模式
。
3.2.简单/静态工厂模式的优点
实现简单
:代码逻辑很简单。可复用高
:所有对象的创建都通过同名的方法创建。
3.3.简单/静态工厂模式的缺点
容错率低
,如果传入的类型参数type因为粗心写错,则创建的产品会与预期不符。耦合度高
,每增减一种产品,都需要对创建对象的唯一方法进行修改。扩展性差
,每增减一种产品,都需要修改工厂类,违背了设计模式的开放-封闭原则(OCP,对扩展开放,对修改关闭)。
造成以上缺点的关键在于:所有对象的创建都通过唯一的工厂方法。
为了解决以上问题,尝试为每种对象提供相应的工厂方法
。如此进化成了:多个工厂方法模式。
4.(多个)工厂方法模式
(多个)工厂方法模式的关键点在于:为每种对象提供相应的工厂方法
,所以很容易得到如下的工厂类:
PhoneFactory
/** * <p>多个工厂方法模式:手机工厂</P> * * @author hanchao */
public class PhoneFactory {
/** * 制造一个苹果手机 */
public static Phone produceApplePhone() {
return new ApplePhone();
}
/** * 制造一个安卓手机 */
public static Phone produceAndroidPhone() {
return new AndroidPhone();
}
}
然后,写一个简单的测试类:MultiFactoryMethodsDemo
/** * <p>2.多个工厂方法模式</P> * * @author hanchao */
public class MultiFactoryMethodsDemo {
public static void main(String[] args) {
//某客户下了一笔大单子,要求制造2台苹果手机和1台安卓手机
//于是手机工厂开始了制造
//先来一台苹果手机
Phone phone = PhoneFactory.produceApplePhone();
//测试一下
phone.callTest();
//再来一台苹果手机
phone = PhoneFactory.produceApplePhone();
//测试一下
phone.callTest();
//再来一台安卓手机
phone = PhoneFactory.produceAndroidPhone();
//测试一下
phone.callTest();
}
}
运行结果:略
4.1.(多个)工厂方法模式的总结
多个工厂方法模式
: 每种对象分别编写专用的创建方法,根据调用的创建方法的不同,产生不同的对象。
多个工厂方法模式
又简称为工厂方法模式
。
4.2.(多个)工厂方法模式的优点
实现简单
:代码逻辑很简单。容错率高
,因为每种对象都有专用的创建方法,无需传入类型等参数,只要调用正确的创建方法就不会出错。耦合度低
,每增减一种产品,只需要增减一个创建方法,不会影响其他对象的创建方法。
4.3.(多个)工厂方法模式的缺点
扩展性差
,每增减一种产品,都需要修改工厂类,违背了设计模式的开放-封闭原则(OCP,对扩展开放,对修改关闭)。可复用低
,所有对象的创建方法都不同名。
造成以上缺点的关键在于:所有对象的创建方法都存在于唯一个工厂。
为了解决以上问题,尝试为每种对象提供单独的工厂及工厂方法
。如此进化成了:抽象工厂模式。
5.抽象工厂模式
抽象工厂模式
的关键点在于:“为每种对象提供单独的工厂及工厂方法`。
所以需要把工厂类抽象出来,形成抽象工厂,然后针对每种对象分别实现专用的工厂及工厂方法,这就是命名抽象工厂
的由来。
抽象工厂:AbstractPhoneFactory
/** * <p>抽象手机工厂</P> * * @author hanhao */
public abstract class AbstractPhoneFactory {
/** * 制造手机 * * @return 手机 */
public abstract Phone producePhone();
}
苹果手机专用的工厂及创建方法:ApplePhoneFactory
/** * <p>具体工厂:苹果手机工厂</P> * * @author hanchao */
public class ApplePhoneFactory extends AbstractPhoneFactory {
@Override
public Phone producePhone() {
return new ApplePhone();
}
}
安卓手机专用的工厂及创建方法:AndroidPhoneFactory
/** * <p>具体工厂:安卓手机工厂</P> * * @author hanchao */
public class AndroidPhoneFactory extends AbstractPhoneFactory {
@Override
public Phone producePhone() {
return new AndroidPhone();
}
}
然后,写一个简单的测试类:AbstractFactoryDemo
/** * <p>3.抽象工厂模式</P> * * @author hanchao */
public class AbstractFactoryDemo {
public static void main(String[] args) {
//某客户下了一笔大单子,要求制造2台苹果手机和1台安卓手机
//于是手机工厂开始了制造
//先来一台苹果手机
Phone phone = new ApplePhoneFactory().producePhone();
//测试一下
phone.callTest();
//再来一台苹果手机
phone = new ApplePhoneFactory().producePhone();
//测试一下
phone.callTest();
//再来一台安卓手机
phone = new AndroidPhoneFactory().producePhone();
//测试一下
phone.callTest();
}
}
运行结果:略
5.1.抽象工厂模式的总结
抽象工厂模式
: 定义一个抽象工厂和抽象方法,每种对象都有专用的子工厂及对象创建方法。
5.2.抽象工厂模式的优点
容错率高
,因为每种对象都有专用的工厂及创建方法,只要调用正确的工厂的创建方法就不会出错。耦合度低
,每增减一种产品,只需增减一个工厂及创建方法,不会影响其他对象的创建方法。扩展性好
,每增减一种产品,只需增减此对象的工厂及创建方法,不修改其他工厂,遵循了开放-封闭原则(OCP,对扩展开放,对修改关闭)。可复用高
,所有对象的创建都通过同名的方法创建。
5.3.抽象工厂模式的缺点
实现复杂
:代码逻辑相对复杂。可能100种对象,需要定义100个工厂类。
6.总结
最后以UML类图来总结本文的三种工厂模式。
从设计模式原则考虑,上述三种工厂模式的推荐优先级:抽象工厂模式
>>>(多个)工厂方法模式
>>>简单/静态工厂模式
。
不过凡事不绝对,如果你说你能百分百的保证业务场景不会发生变动,那你是用哪种模式都是无所谓的。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/34664.html