前提
先说:抽象工厂确实很抽象,抽象的自己头疼。。。
但是,必须掌握,抽象工厂解决了多态+开放关闭原则,效率高。抽象工厂一般都用在数据库切换使用方面。
经过一天的折腾,算是搞定抽象工厂,下面让你们跟着我的思维来学习抽象工厂。
首先,引入一些知识,抽象工厂和之前学的工厂方法模式的区别,在工厂方法模式之下,这样比较好学抽象工厂。
工厂方法模式:生产一种产品,比如包子(包含肉包、菜包等等)
抽象工厂模式:生产多种产品,比如包子、豆浆、油条....
抽象工厂是指工厂能生产一个系列的产品,比如包子就是属于一个系列,它里面有肉包、菜包等;豆浆又是另外一个系列,此时是两个工厂生产两个系列;关键是一个系列里面又包含多种产品;
抽象工厂是指工厂能生产一个系列的产品,比如数据库Mysql就是属于一个系列,它里面的方法可以有查询注册等;Oracle又是另外一个系列,此时是两个工厂生产两个系列;关键是一个系列里面又包含多种产品;与工厂方法相比,抽象就是针对一个系列,系列里面包含多种产品,而工厂方法是只能生产一种产品;
包子可以抽象出来
public interface FoodFactory {
//肉类
Food Rouproduce();
//素菜类
Food Caiproduce();
}
第一道例子
我的设计思想:在土系列中找到土猫,在宠物系列中找到宠物猫。
我自己想,画,得出来的抽象工厂,这道题没有实际意义,但是却能让我掌握抽象工厂流程
找出系列:土、宠物
如图,分析(好好体会分析过程):
1、动物接口类:狗、猫、猪
2、动物实现类:土狗、宠物狗、土猫、宠物猫、土猪、宠物猪(对应实现了狗、猫、猪接口)
3、特征系列:土、宠物(由特征系列确定具体工厂系列)
4、工厂接口确定:生产狗、猫、猪方法
5、具体工厂系列1,土工厂实现(实现生产土狗、土猫、土猪)
6、具体工厂系列2,宠物工厂实现(实现生产宠物狗、宠物猫、宠物猪)
代码实现
package com.design.abstractfactory;
/**
* @Description
* @Author xuexue
* @Date 2019/6/217:05
*/
public class AbstractFactory {
public static void main(String[] args) {
//选择土系列中,找到猫
AnimalFactory lowFactory = new LowFactory();
lowFactory.createCat().name();
//选择在宠物系列中找到狗
AnimalFactory petFactory = new PetFactory();
petFactory.createDog().name();
}
}
//接口Dog、Cat、Pig
interface Dog {
void name();
}
interface Cat {
void name();
}
interface Pig {
void name();
}
//接口Dog、Cat、Pig的实现类(土、宠物)
class LowDog implements Dog {
@Override
public void name() {
System.out.println("我是土狗");
}
}
class PetDog implements Dog {
@Override
public void name() {
System.out.println("我是宠物狗");
}
}
class LowCat implements Cat {
@Override
public void name() {
System.out.println("我是土猫");
}
}
class PetCat implements Cat {
@Override
public void name() {
System.out.println("我是宠物猫");
}
}
class LowPig implements Pig {
@Override
public void name() {
System.out.println("我是土猪");
}
}
class PetPig implements Pig {
@Override
public void name() {
System.out.println("我是宠物猪");
}
}
//工厂
interface AnimalFactory {
Dog createDog();
Cat createCat();
Pig createPig();
}
//土工厂实现类
class LowFactory implements AnimalFactory {
@Override
public Dog createDog() {
return new LowDog();
}
@Override
public Cat createCat() {
return new LowCat();
}
@Override
public Pig createPig() {
return new LowPig();
}
}
//土工厂实现类
class PetFactory implements AnimalFactory {
@Override
public Dog createDog() {
return new PetDog();
}
@Override
public Cat createCat() {
return new PetCat();
}
@Override
public Pig createPig() {
return new PetPig();
}
}
输出
第二道例子
上面的例子没有搞懂不要紧,接下来这实际应用的例子更有用
在一张信息表中,我们可以查询一条信息,插入一条信息。同时在一张注册表也可以查询一条信息,插入一条信息。但是,每次查询或者插入可以用mysql或者用oracle,这个时候就可以采用抽象工厂来设计,同时满足可以用任意一种数据库来操作。这里用mysql数据库进行对login表进行插入一条数据,对注册表查询一条数据。或者选择使用oracle数据库进行对login表进行插入一条数据,对注册表查询一条数据。2选1,测试中都用了,实际情况就是有的选择。
分析:
找出系列,有共同之处,就是mysql、oracle操作两张表,就有两个系列
此时设计:
1、信息表接口、注册表接口(查询、插入方法)
2、分别用mysql、oracle实现两张表(有四次实现,mysql实现信息表,mysql实现注册表,oracle实现信息表,oracle实现注册表)
3、系列:mysql、oracle
4、工厂接口(方法:创建信息表,创建注册表)
5、系列1,mysql(实现工厂接口,创建mysql信息表,创建mysql注册表)
6、系列2,oracle(实现工厂接口,创建oracle信息表,创建oracle注册表接口)
代码实现
package com.design.abstractfactory;
/**
* @Description
* 抽象工厂
* @Author
* @Date 2019/6/218:45
*/
public class ConnectionFactory {
public static void main(String[] args) {
//选择使用mysql数据库进行对login表进行插入一条数据,对注册表查询一条数据
Factory mysqlFactory = new MysqlFactory();
mysqlFactory.createLogin().insert();
mysqlFactory.createRegister().query();
//选择使用oracle数据库进行对login表进行插入一条数据,对注册表查询一条数据
Factory oracleFactory = new OracleFactory();
oracleFactory.createLogin().insert();
oracleFactory.createRegister().query();
}
}
//登录表与注册表接口定义
interface Login {
void insert();
void query();
}
interface Register {
void insert();
void query();
}
//mysql实现登录表
class MysqlLogin implements Login {
@Override
public void insert() {
System.out.println("使用mysql,在login表实现插入一条数据");
}
@Override
public void query() {
System.out.println("使用mysql,在login表查询一条数据");
}
}
//mysql实现注册表
class MysqlRegister implements Register {
@Override
public void insert() {
System.out.println("使用mysql,在Register实现插入一条数据");
}
@Override
public void query() {
System.out.println("使用mysql,在Register实现查询一条数据");
}
}
//oracle实现登录表
class OracleLogin implements Login {
@Override
public void insert() {
System.out.println("使用oracle,在login表实现插入一条数据");
}
@Override
public void query() {
System.out.println("使用oracle,在login表查询一条数据");
}
}
//mysql实现注册表
class OracleRegister implements Register {
@Override
public void insert() {
System.out.println("使用oracle,在Register实现插入一条数据");
}
@Override
public void query() {
System.out.println("使用oracle,在Register实现查询一条数据");
}
}
//定义工厂
interface Factory {
Login createLogin();
Register createRegister();
}
//系列1mysql实现工厂类
class MysqlFactory implements Factory {
@Override
public Login createLogin() {
return new MysqlLogin();
}
@Override
public Register createRegister() {
return new MysqlRegister();
}
}
//系列2oracle实现工厂类
class OracleFactory implements Factory {
@Override
public Login createLogin() {
return new OracleLogin();
}
@Override
public Register createRegister() {
return new OracleRegister();
}
}
输出: