一、定义:
工厂模式是Java中最常用的设计模式之一,使用工厂方法替代new操作的一种模式。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
二、工厂模式分为:简单工厂模式、工厂方法模式、抽象工厂模式
简单工厂模式
1、定义:简单工厂模式是属于创建型模式,又叫静态工厂方法模式,但不属于23种GOF设计模式之一(工厂方法模式和抽象工厂模式是23中GOF设计模式)。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。
2、结构:
3、实现
抽象产品类
public interface Produce {
Produce getInstance();
}
描述产品的具体类
ProduceA产品
public class ProduceA implements Produce{
private String desc;
public ProduceA(String desc){
this.desc = desc;
}
public Produce getInstance() {
return this;
}
public String toString() {
return "ProduceA{" +
"desc='" + desc + '\'' +
'}';
}
}
ProduceB类
public class ProduceB implements Produce{
private String desc;
public ProduceB(String desc){
this.desc = desc;
}
public Produce getInstance() {
return this;
}
public String toString() {
return "ProduceB{" +
"desc='" + desc + '\'' +
'}';
}
}
简单工厂类
public class SingleFactory {
public static Produce getProduce(int type){
if(type==1){
return new ProduceA("我是产品A");
}else if(type==2){
return new ProduceB("我是产品B");
}else{
return null;
}
}
public static Produce getProduce(Class c){
//判断类型是否是ProduceA,如果是返回ProduceA对象
if(c==ProduceA.class){
return new ProduceA("我是产品A");
}else if(c==ProduceB.class){
//判断类型是否是ProduceA,如果是返回ProduceA对象
return new ProduceB("我是产品B");
}else{
return null;
}
}
public static void main(String[] args) {
Produce produce = SingleFactory.getProduce(ProduceA.class);
System.out.println(produce);
}
}
4、优缺点
1、优点:
简单工厂模式能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象,明确区分了各自的职责和权力,有利于整个软件体系结构的优化。
2、缺点:在工厂类中集中了所有实例的创建逻辑,容易违反高内聚的责任分配原则
工厂方法模式
1、定义:工厂方法模式又称多态性工厂模式,在工厂方法模式中,核心的工厂类不再负责所有产品的创建,而是将具体创建的工作交给子类去做,该核心类称为一个抽象工厂角色,仅负责给出具体工厂子类必须实现的接口,而不接触哪一个产品类应当被实例化这种细节。工厂方法模式是简单工厂模式的衍生,解决了许多简单工厂模式的问题。首先完全实现了开闭原则,实现了可扩展。具有更复杂的层次结构,可以应用于产品结果复杂的场合
2、结构:
3、实现
抽象产品
//抽象产品类
public interface Produce {
//介绍方法
public void intro();
}
具体产品类
产品类 ProduceA类
public class ProduceA implements Produce{
public void intro() {
System.out.println("凉茶和其正!");
}
}
产品类 ProduceB类
public class ProduceA implements Produce{
public void intro() {
System.out.println("雪碧贼凉爽1");
}
}
抽象工厂类
public interface Factory {
Produce getProduce();
}
具体工厂类
//ProduceA产品的具体工厂类
public class ProduceAFactory implements Factory{
private static ProduceAFactory jdb = new ProduceBFactory();
private ProduceAFactory(){
}
public static ProduceAFactory getInstance(){
return jdb;
}
public Produce getProduce() {
return new ProduceA();
}
}
//产品ProduceB类的具体工厂类
public class ProduceBFactory implements Factory{
private static ProduceBFactory kl = new ProduceBFactory();
private ProduceBFactory(){}
public static ProduceBFactory getInstance(){
return kl;
}
public Produce getProduce() {
return new ProduceB();
}
}
顾客类
public class Test {
public static void main(String[] args) {
ProduceB xb = (ProduceB)ProduceBFactory.getInstance().getProduce();
xb.intro();
ProduceA jdb = (ProduceA)ProduceAFactory.getInstance().getProduce();
jdb.intro();
}
}
4、优缺点
优点:
(1)子类提供挂钩。基类为工厂方法提供缺省实现,子类可以重写新的实现,也可以继承父类的实现
(2)屏蔽产品类。产品类的实现如何变化,调用者都不需要关系,只需要关心产品的接口,只要接口保持不变,系统中的上层模块就不会发生变化。
(3)典型的解耦框架。高层模块只需要直到产品的抽象类,其他的实现类都不需要关心,符合迪米特法则,符合依赖倒置原则,符合里氏替换原则。
(4)多态性:客户代码可以做到与特定应用无关,适用于任何实体类
缺点:
需要creator和相应的子类作为factory method的载体,如果应用模型确实需要 creator 和子类存在,则很好;否则的话,需要增 加一个类层次。
5、应用场景
(1)日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器 等,用户可以选择记录日志到什么地方 (2)数据库访问,当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化时
(3) 设计一个连接服务器的框架,需要三个协议,“POP3”、“IMAP”、 “HTTP”,可以把这三个作为产品类,共同实现一个接口
抽象工厂模式
1、定义:
抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口。使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。根据里氏替换原则,任何接受父类类型的地方,都应当接受子类类型。因此,实际上系统所需要的,仅仅是类型与这些抽象产品角色相同的实例,而不是这些抽象产品的实例。换言之,也就是这些抽象产品的具体子类的实例。工厂类负责抽象产品的具体子类的实例。为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。
2、结构:
3、实现
内存的抽象和实现
//内存的抽象
public interface 内存 {
void 内存大小();
}
//内存的实现
public class 大内存 implements 内存{
public void 内存大小() {
System.out.println("大内存:大小为64G");
}
}
public class 小内存 implements 内存{
public void 内存大小() {
System.out.println("小内存:大小8G");
}
}
颜色的抽象和实现
//颜色的抽象
public interface 颜色 {
void 颜色();
}
//颜色的实现
public class 红颜色 implements 颜色{
public void 颜色() {
System.out.println("葡萄红!");
}
}
public class 蓝颜色 implements 颜色{
public void 颜色() {
System.out.println("天空蓝!");
}
}
工厂的抽象和实现
//工厂的抽象
public interface Factory {
内存 getMemory();
颜色 getColor();
}
//工厂的实现
//工厂A产蓝色的大内存
public class FactoryA implements Factory{
public 内存 getMemory() {
return new 大内存();
}
public 颜色 getColor() {
return new 蓝颜色();
}
}
//工厂B产红色的小内存
public class FactoryB implements Factory{
public 内存 getMemory() {
return new 小内存();
}
public 颜色 getColor() {
return new 红颜色();
}
}
顾客类
public class Client {
//顾客选择工厂A的产品
public static void main(String[] args) {
FactoryA factoryA = new FactoryA();
factoryA.getColor().颜色();
factoryA.getMemory().内存大小();
}
}
4、优缺点
优点;
(1)抽象工厂模式隔离了具体类的生产,使客户并不需要知道什么被创建。
(2)当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象
(3)增加新的具体工厂和产品族很方便,无需修改已有的系统,符合开闭原则
缺点:
增加新的产品等级结构很复杂,需要修改抽象工厂和所有的具体工厂类,对开闭原则的支持呈现倾斜性。