3.工厂模式
3.1 作用
- 实现了创建者和调用这分离。
- 详细分类:
简单工厂模式
工厂方法模式
抽象方法模式
- 需要满足OOP原则,开闭原则,依赖倒转原则,迪米特原则
3.2 核心本质
- 实例化对象不使用new,用工厂方法代替
- 将选择实现类,创建对象统一管理和控制。从而将调用者跟实现类解耦
3.3 三种模式:
- 简单工厂模式:用来生产同一等级结构中的任意产品(对于新增的产品,需要修改已有代码)
- 工厂方法模式:用来生产同一等级结构中的固定产品(对于新增的产品,需要扩展已有代码)。
- 抽象工厂模式:围绕一个超级工厂创建其他工厂。改超级工厂有称为其他工厂的工厂。
- 客户直接new对象的话 需要知道很多属性和细节,而加入一个工厂,对外封闭建造过程,直接工厂调用方便
3.4 简单工厂模式
public interface Car {
public void getName();
}
public class BmwCar implements Car {
@Override
public void getName() {
System.out.println("BMW车!");
}
}
public class BydCar implements Car {
@Override
public void getName() {
System.out.println("比亚迪车!");
}
}
- 车工厂类生产车辆
/**简单工厂模式
* 静态工厂模式
* 增加一个新产品,不修改代码,做不到
* 违反开闭原则:更多的代价,工厂方法模式
* 大多数情况是这个模式
* */
public class CarFactory {
public static Car car;
//方法1:
public static Car getCar(String name){
if (name.equals("Bwm")) {
car = new BmwCar();
}else if(name.equals("Byd")){
car = new BydCar();
}else {
car = null;
}
return car;
}
//方式二:
public static Car getBmwCar(){
car = new BmwCar();
return car;
}
public static Car getBydCar(){
car = new BydCar();
return car;
}
}
- 调用
@Test
public void testSimple(){
Car bmw = CarFactory.getCar("Bwm");
bmw.getName();
}
3.5 工厂方法模式
- 实现步骤:产品接口
public interface Car {
public void getName();
}
public class BmwCar implements Car {
@Override
public void getName() {
System.out.println("BMW车!");
}
}
public class BydCar implements Car {
@Override
public void getName() {
System.out.println("比亚迪车!");
}
}
- 工厂接口
public interface CarFactory {
public Car getCar();
}
- A车工厂接口生产A车
public class BmwCarFactory implements CarFactory{
@Override
public Car getCar() {
return new BmwCar();
}
}
- B车工厂接口生产B车
public class BydCarFactory implements CarFactory{
@Override
public Car getCar() {
return new BydCar();
}
}
- 两种工厂比较
结构复杂度:simple
代码复杂度:simple
编码复杂度:simple
管理复杂度:simple
根据设计原则:工厂方法模式
根据实际业务:简单工厂模式
3.6 抽象工厂模式
-
定义:抽象工厂模式提供了一个创建一系列相关或相互依赖对象的接口,无需指定他们具体的类
-
使用场景
客户端(应用层)不依赖于产品类实例如何被创建,实现等细节
强调一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量的重复的代码
提供一个产品类的库,所有产品以同样的接口出现,从而使的客户端不依赖于具体的实现
- 优点:
具体产品的应用层代码隔离,无需关心创建的细节
将一个系列的产品统一到一起创建
产品体系稳定的时候职责分明,效率高,违反了开闭原则
- 缺点
规定了所有可能被创建的产品集合,产品族中扩展新的产品困难
增加了系统的抽象性和理解难度
- 举例步骤:
- 定义两种产品并实现不同的品牌产品
/***
* 钢筋
* 长度
* 建造
* 温度
* 价格
*/
public interface SteelBar {
void len();
void build();
void temperature();
void price();
}
/*
* 水泥
* 成分
* 铺路
* 吨数
* 硬度
* */
public interface Cement {
void component();
void paving();
void tonnage();
void hardness();
}
public class ASteelBar implements SteelBar{
@Override
public void len() {
System.out.println("A品牌钢筋长度!");
}
@Override
public void build() {
System.out.println("A品牌钢筋建筑!");
}
@Override
public void temperature() {
System.out.println("A品牌钢筋温度!");
}
@Override
public void price() {
System.out.println("A品牌钢筋价格!");
}
}
public class BSteelBar implements SteelBar{
@Override
public void len() {
System.out.println("B品牌钢筋长度!");
}
@Override
public void build() {
System.out.println("B品牌钢筋建筑!");
}
@Override
public void temperature() {
System.out.println("B品牌钢筋温度!");
}
@Override
public void price() {
System.out.println("B品牌钢筋价格!");
}
}
public class ACement implements Cement{
@Override
public void component() {
System.out.println("A品牌水泥成分!");
}
@Override
public void paving() {
System.out.println("A品牌水泥铺路!");
}
@Override
public void tonnage() {
System.out.println("A品牌水泥吨数!");
}
@Override
public void hardness() {
System.out.println("A品牌水泥硬度!");
}
}
public class BCement implements Cement{
@Override
public void component() {
System.out.println("B品牌水泥成分!");
}
@Override
public void paving() {
System.out.println("B品牌水泥铺路!");
}
@Override
public void tonnage() {
System.out.println("B品牌水泥吨数!");
}
@Override
public void hardness() {
System.out.println("B品牌水泥硬度!");
}
}
- 定义工厂产品的协议
public interface ProductProtocol {
Cement getCement();
SteelBar getSteelBar();
}
- 定义两个具体生产两个产品的不同品牌的工厂
public class AProduct implements ProductProtocol{
@Override
public Cement getCement() {
return new ACement();
}
@Override
public SteelBar getSteelBar() {
return new ASteelBar();
}
}
public class BProduct implements ProductProtocol{
@Override
public Cement getCement() {
return new BCement();
}
@Override
public SteelBar getSteelBar() {
return new BSteelBar();
}
}
- 测试,通过具体品牌工厂创建某产品
@Test
public void testAbstractFactory(){
AProduct aProduct = new AProduct();
aProduct.getSteelBar().build();
BProduct bProduct = new BProduct();
bProduct.getSteelBar().build();
}
3.7 小结
- 简单工厂模式(静态工厂模式):虽然有点不符合设计原则,但实际使用多
- 工厂方法模式:不修改已有类,通过增加工厂类来实现扩展
- 抽象方法模式:不增加产品,增加产品族
3.8 应用场景
- jdk中calendar的getInstance方法
- jdbc中connection对象获取方法
- Spring中IOC容器创建管理bean对象
- 反射中Class对象的newInstance方法
本专栏下一篇:设计模式之建造者模式
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/123933.html