工厂模式定义
工厂设计模式,顾名思义,就是用来生产对象的,在java中,万物皆对象,这些对象都需要创建,如果创建的时候直接new该对象,就会对该对象耦合严重,假如我们要更换对象,所有new对象的地方都需要修改一遍,这显然违背了软件设计的开闭原则,如果我们使用工厂来生产对象,我们就只和工厂打交道就可以了,彻底和对象解耦,如果要更换对象,直接在工厂里更换该对象即可,达到了与对象解耦的目的;所以说,工厂模式最大的优点就是:解耦
介绍三种工厂设计模式的使用:
1、简单工厂
2、工厂方法
3、抽象工厂
简单工厂设计模式
定义:一个工厂方法,根据传入的参数,生成对应的产品对象
角色:
1、抽象产品
2、具体产品
3、具体工厂
4、产品使用者
使用说明:先将产品类抽象出来,比如:苹果和梨都属于水果,抽象出来一个水果类 Fruit,苹果和梨就是具体产品类,然后创建一个水果工厂,分别用来创建苹果和梨,代码如下:
水果接口
public interface Fruit {
void eat();
}
具体类,苹果
public class Apple implements Fruit{
@Override
public void eat() {
System.out.println("吃苹果!");
}
}
具体类,香蕉
public class Banana implements Fruit{
@Override
public void eat() {
System.out.println("吃香蕉!");
}
}
具体工厂,水果工厂
public class FruitFactory {
public static Fruit getFruit(String name) throws Exception{
if(name.equalsIgnoreCase("apple")){
return Apple.class.newInstance();
}else if(name.equalsIgnoreCase("banana")){
return Banana.class.newInstance();
}else{
return null;
}
}
}
产品使用,测试类
public class MainTest {
public static void main(String[] args) throws Exception{
Fruit apple = FruitFactory.getFruit("apple");
Fruit banana = FruitFactory.getFruit("banana");
apple.eat();
banana.eat();
}
}
就这样,一个非常简单的工厂设计模式就完成了,但是有没有发现什么问题呢?
对,那就是如果我想吃梨,想吃橘子呢,我万一什么都想吃呢??所以,以上的这种方式,每当我想添加一种水果,就必然要修改工厂类,这显然违反了开闭原则,亦不可取;所以简单工厂只适合于产品对象较少,且产品固定的需求,对于产品变化无常的需求来说显然不合适;所以我们来看下一种方式;
工厂方法设计模式
定义:将工厂提取成一个接口或抽象类,具体生成什么产品由子类决定
角色:
抽象产品类
具体产品类
抽象工厂类
具体工厂类
使用说明:和上例中一样,产品类抽象出来,这次我们把工厂类也抽象出来,生产什么样的产品由子类来决定,代码如下:
水果接口、苹果类 和 香蕉类 和上例一样
工厂接口:
public interface FruitFactory {
Fruit createFruit();// 生产水果
}
苹果工厂:
public class AppleFactory implements FruitFactory{
@Override
public Fruit createFruit() {
return new Apple();
}
}
香蕉工厂
public class BananaFactory implements FruitFactory{
@Override
public Fruit createFruit() {
return new Banana();
}
}
产品使用,测试类
public class MainTest {
public static void main(String[] args) {
AppleFactory appleFactory = new AppleFactory();
BananaFactory bananaFactory = new BananaFactory();
Apple apple = (Apple) appleFactory.createFruit();// 获得苹果
Banana banana = (Banana)bananaFactory.createFruit();// 获得香蕉
}
}
以上这种方式,虽然解耦了,也遵循了开闭原则,但是问题根本还是没有解决啊,换汤没换药,如果我需要的产品很多的话,需要创建非常多的工厂,所以这种方式的缺点也很明显;
抽象工厂设计模式
定义:为创建一组相关或者是相互依赖的对象提供的一个接口,而不需要指定它们的具体类。
角色:和工厂方法一样
抽象工厂和工厂方法的模式基本一样,区别在于,工厂方法是生产一个具体的产品,而抽象工厂可以用来生产一组相同,有相对关系的产品;重点在于一组,一批,一系列;
业务需求:生产不同内存条,搭配win7系统的电脑
定义抽象工厂
/**
* 业务需求:生产不同内存条搭配win7系统的电脑
*
* 定义抽象工厂
*/
public interface AbstastFactory {
public Ram createRam();
public WinSystem createSystem();
}
具体工厂实现,低端电脑配置
/**
* 具体工厂实现,低端电脑怕配置
*/
public class LowComputer implements AbstastFactory{
@Override
public Ram createRam() {
return new Ram512();
}
@Override
public WinSystem createSystem() {
return new WinSystem.SystemWin7();
}
}
具体工厂实现,高端电脑配置
public class NiceComputer implements AbstastFactory{
@Override
public Ram createRam() {
return new Ram.Ram1G();
}
@Override
public WinSystem createSystem() {
return new WinSystem.SystemWin7();
}
}
内存条接口
/**
* 内存条接口
*/
public interface Ram {
// 1G内存条实现类
public class Ram1G implements Ram{
public Ram1G(){
System.out.println("1G 内存");
}
}
}
512内存条实现类
public class Ram512 implements Ram{
public Ram512(){
System.out.println("512内存");
}
}
系统接口
/**
* 系统接口
*/
public interface WinSystem {
// win7 系统实现类
public class SystemWin7 implements WinSystem{
public SystemWin7(){
System.out.println("win7");
}
}
}
客户拿到的具体产品,测试类
public class MainTest {
public static void main(String[] args) {
LowComputer lowComputer = new LowComputer();
lowComputer.createRam();
lowComputer.createSystem();
}
}
输出结果
512内存
win7