设计模式-工厂模式

定义

它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。实现了创建者和调用者分离,工厂模式分为简单工厂、工厂方法、抽象工厂模式。

工厂模式的优点

  1. 工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式。
  2. 利用工厂模式可以降低程序的耦合性,为后期的维护修改提供了很大的便利。
  3. 将选择实现类、创建对象统一管理和控制。从而将调用者跟我们的实现类解耦。

Spring开发中使用的工厂模式

1.Spring IOC

看过Spring源码就知道,在Spring IOC容器创建bean的过程是使用了工厂设计模式

Spring中无论是通过xml配置还是通过配置类还是注解进行创建bean,大部分都是通过简单工厂来进行创建的。

当容器拿到了beanName和class类型后,动态的通过反射创建具体的某个对象,最后将创建的对象放到Map中。

2.为什么Spring IOC要使用工厂设计模式创建Bean呢

在实际开发中,如果我们A对象调用B,B调用C,C调用D的话我们程序的耦合性就会变高。(耦合大致分为类与类之间的依赖,方法与方法之间的依赖。)

在很久以前的三层架构编程时,都是控制层调用业务层,业务层调用数据访问层时,都是是直接new对象,耦合性大大提升,代码重复量很高,对象满天飞

为了避免这种情况,Spring使用工厂模式编程,写一个工厂,由工厂创建Bean,以后我们如果要对象就直接管工厂要就可以,剩下的事情不归我们管了。Spring IOC容器的工厂中有个静态的Map集合,是为了让工厂符合单例设计模式,即每个对象只生产一次,生产出对象后就存入到Map集合中,保证了实例不会重复影响程序效率。

工厂模式的分类

简单工厂,工厂方法,抽象工厂;
他们三者之间的区别可以用下面几句话概括!
简单工厂 :用来生产同一等级结构中的任意产品。(不支持拓展增加产品)
工厂方法 :用来生产同一等级结构中的固定产品。(支持拓展增加产品)
抽象工厂 :用来生产不同产品族的全部产品。(不支持拓展增加产品;支持增加产品族)

简单工厂

简单工厂模式相当于是一个工厂中有各种产品,创建在一个类中,客户无需知道具体产品的名称,只需要知道产品类所对应的参数即可。但是工厂的职责过重,而且当类型过多时不利于系统的扩展维护。

代码演示:

创建工厂

package com.xinan;

public interface Drink {
	public void run();
}

创建工厂的产品(可乐)

package com.xinan;

public class KL implements Drink {
	public void run() {
		System.out.println("我是可乐...");
	}
}

创建工另外一种产品(雪碧)

package com.xinan;

public class XB implements Drink {
	public void run() {
		System.out.println("我是奥迪汽车..");
	}
}

创建核心工厂类,由他决定具体调用哪产品

package com.xinan;

public class DrinkFactory {

	 public static Drink createDrink(String name) {
		if ("".equals(name)) {
             return null;
		}
		if(name.equals("kele")){
			return new KL();
		}
		if(name.equals("雪碧")){
			return new XB();
		}
		return null;
	}
}

演示创建工厂的具体实例

package com.xinan;

public class Client01 {

	public static void main(String[] args) {
		Drink kl  =DrinkFactory.createCar("可乐");
		Drink xb  =DrinkFactory.createCar("雪碧");
		kl.run();
		xb.run();
	}
}

主要优点
简单工厂模式的主要优点如下:
(1)工厂类包含必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的职责,而仅仅“消费"产品,简单工厂模式实现了对象创建和使用的分离。
(2)客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,对于一些复杂的类名,通过简单工厂模式可以在一定程度减少使用者的记忆量。
(3)通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。
主要缺点
简单工厂模式的主要缺点如下:
(1)由于工厂类集中了所有产品的创建逻辑,职责过重,一旦不能正常工作,整个系统都要受到影响。
(2)使用简单工厂模式势必会增加系统中类的个数(引入了新的工厂类),增加了系统的复杂度和理解难度。
(3)系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护。
(4)简单工厂模式由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构。

工厂方法模式

工厂方法模式Factory Method,又称多态性工厂模式。在工厂方法模式中,核心的工厂类不再负责所有的产品的创建,而是将具体创建的工作交给子类去做。该核心类成为一个抽象工厂角色,仅负责给出具体工厂子类必须实现的接口,而不接触哪一个产品类应当被实例化这种细节

代码演示
1.创建工厂

public interface Car {
	public void run();
}

2创建工厂方法调用接口(所有的产品需要new出来必须继承他来实现方法)

public interface CarFactory {

	Car createCar();

}

3.创建工厂的产品(奥迪)

public class AoDi implements Car {
	public void run() {
		System.out.println("我是奥迪汽车..");
	}
}

4.创建工厂另外一种产品(宝马)

public class Bmw implements Car {
	public void run() {
		System.out.println("我是宝马汽车...");
	}
}

5.创建工厂方法调用接口的实例(奥迪)

public class AoDiFactory implements CarFactory {

	public Car createCar() {
	
		return new AoDi();
	}
}

6.创建工厂方法调用接口的实例(宝马)

public class BmwFactory implements CarFactory {

	public Car createCar() {

		return new Bmw();
	}

}

7.演示创建工厂的具体实例

public class Client {

	public static void main(String[] args) {
		Car aodi = new AoDiFactory().createCar();
		Car jili = new BmwFactory().createCar();
		aodi.run();
		jili.run();
	}
}

主要优点
工厂方法模式的主要优点如下:

   (1) 在工厂方法模式中,工厂方法用来创建客户所需要的产品,同时还向客户隐藏了哪种具体产品类将被实例化这一细节,用户只需要关心所需产品对应的工厂,无须关心创建细节,甚至无须知道具体产品类的类名。

   (2) 基于工厂角色和产品角色的多态性设计是工厂方法模式的关键。它能够让工厂可以自主确定创建何种产品对象,而如何创建这个对象的细节则完全封装在具体工厂内部。工厂方法模式之所以又被称为多态工厂模式,就正是因为所有的具体工厂类都具有同一抽象父类。

   (3) 使用工厂方法模式的另一个优点是在系统中加入新产品时,无须修改抽象工厂和抽象产品提供的接口,无须修改客户端,也无须修改其他的具体工厂和具体产品,而只要添加一个具体工厂和具体产品就可以了,这样,系统的可扩展性也就变得非常好,完全符合“开闭原则”。

主要缺点

工厂方法模式的主要缺点如下:

  (1) 在添加新产品时,需要编写新的具体产品类,而且还要提供与之对应的具体工厂类,系统中类的个数将成对增加,在一定程度上增加了系统的复杂度,有更多的类需要编译和运行,会给系统带来一些额外的开销。

  (2) 由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度,且在实现时可能需要用到DOM、反射等技术,增加了系统的实现难度。
抽象工厂模式

抽象工厂简单地说是工厂的工厂,抽象工厂可以创建具体工厂,由具体工厂来产生具体产品。
在这里插入图片描述
代码演示
创建第一个子工厂,及实现类



//汽车
public interface Car {
	   void run();
}

 class CarA implements Car{

	public void run() {
		System.out.println("宝马");
	}
	
}
 class CarB implements Car{

	public void run() {
		System.out.println("摩拜");
	}
	
}

创建第二个子工厂,及实现类



//发动机
public interface Engine {

    void run();

}

class EngineA implements Engine {

    public void run() {
        System.out.println("转的快!");
    }

}

class EngineB implements Engine {

    public void run() {
        System.out.println("转的慢!");
    }

}

创建一个总工厂,及实现类(由总工厂的实现类决定调用那个工厂的那个实例)



public interface TotalFactory {
	// 创建汽车
	Car createChair();
	// 创建发动机
	Engine createEngine();
}

//总工厂实现类,由他决定调用哪个工厂的那个实例
class TotalFactoryReally implements TotalFactory {

	public Engine createEngine() {

		return new EngineA();
	}

	public Car createChair() {

		return new CarA();
	}
}


运行测试

public class Test {

    public static void main(String[] args) {
        TotalFactory totalFactory2 = new TotalFactoryReally();
        Car car = totalFactory2.createChair();
        car.run();

        TotalFactory totalFactory = new TotalFactoryReally();
        Engine engine = totalFactory.createEngine();
        engine.run();
    }
}


主要优点
抽象工厂模式的主要优点如下:

   (1) 抽象工厂模式隔离了具体类的生成,使得客户并不需要知道什么被创建。由于这种隔离,更换一个具体工厂就变得相对容易,所有的具体工厂都实现了抽象工厂中定义的那些公共接口,因此只需改变具体工厂的实例,就可以在某种程度上改变整个软件系统的行为。

   (2) 当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。

   (3) 增加新的产品族很方便,无须修改已有系统,符合“开闭原则”。

主要缺点

抽象工厂模式的主要缺点如下:

   增加新的产品等级结构麻烦,需要对原有系统进行较大的修改,甚至需要修改抽象层代码,这显然会带来较大的不便,违背了“开闭原则”。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值