设计模式三:抽象工厂模式

前提

先说:抽象工厂确实很抽象,抽象的自己头疼。。。

但是,必须掌握,抽象工厂解决了多态+开放关闭原则,效率高。抽象工厂一般都用在数据库切换使用方面

经过一天的折腾,算是搞定抽象工厂,下面让你们跟着我的思维来学习抽象工厂。

首先,引入一些知识,抽象工厂和之前学的工厂方法模式的区别,在工厂方法模式之下,这样比较好学抽象工厂。

工厂方法模式:生产一种产品,比如包子(包含肉包、菜包等等)

抽象工厂模式:生产多种产品,比如包子、豆浆、油条....

抽象工厂是指工厂能生产一个系列的产品,比如包子就是属于一个系列,它里面有肉包、菜包等;豆浆又是另外一个系列,此时是两个工厂生产两个系列;关键是一个系列里面又包含多种产品

抽象工厂是指工厂能生产一个系列的产品,比如数据库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();
    }
}

输出:

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值