工厂模式主要是为创建对象提供了接口,以便将创建对象的具体过程隔离屏蔽起来,提高代码的灵活性。
如果有许多地方,都需要生成A的对象,那么就需要写很多的A a=new A()。如果有需要修改的话,就需要修改许多地方, 但是如果使用工厂模式,只需要修改工厂代码。其他地方引用工厂,可以做到只修改一个地方,其他地方都不动,这就是解耦。
1.在编码时不能预见需要创建那儿种类的实例。
2.系统不应依赖于产品实例如何被创建、组合和表达的细节
工厂模式主要分为三类:
1.简单工厂模式(不利于产生系列产品,不推荐使用)
2.普通工厂模式(又称为多行性工厂)
3.抽象工厂模式(又称为工具箱,产生产品族,不利于生产新的产品)
一、简单工厂模式
违背了设计模式原则的开闭原则,不推荐使用
下面以一个实例来说明简单工厂模式:
/** * 1.创建一个学习的接口 */ public interface IStudy { void study(); } /** * 2.创建学习接口的实现类javaStudy以及phpStudy */ public class JavaStudyImpl implements IStudy { @Override public void study() { System.out.println("学java"); } } public class PhpStudyImpl implements IStudy { @Override public void study() { System.out.println("学php"); } } /** * 3.创建简单工厂 */ public class EasyFactory { public IStudy study(String name) { if (name == "java") { return new JavaStudyImpl(); } else if (name == "php") { return new PhpStudyImpl(); } return null; } } /** * 4.测试简单工厂 */ public class Demo { public static void main(String[] args) { EasyFactory easyFactory = new EasyFactory(); IStudy study = easyFactory.study("java"); IStudy study1 = easyFactory.study("php"); study.study(); study1.study(); } }
/**
* 简单工厂的优缺点:
* 优点:在一个工厂类里统一进行功能的管理,分配,不用关心这些功能具体的底层实现方式,
* 若新增功能的话,只需要在工厂类里新增新功能的对象的分配调用就好了,不用关心底层代码的具体实现代码。
* 缺点:若新增加功能的话,就要在工厂类里修改原有方法的代码,
* 若新增加的功能较多,就会出现很多类似的大量代码的分配调用
*/
二、普通工厂模式
工厂方法模式需要有一个工厂功能的统一接口,然后该工厂用有几个功能,就创建几个工厂的实现类,在每个工厂的实现类里边,分别返回 该工厂 实现代码的实现类 的对象(这句话说起来比较绕口,其实就是给每个功能都创建一个专门的工厂,该工厂就只负责对应的功能)。同样该工厂的实现类依然不关注具体的底层代码的实现,全部代码实现都是放到底层实现类里实现的。
/**
* 普通工厂
* 1.即每个实现类的实例化的工作,专门有一个对应的工厂来管理,
* 就是在该工厂类里,不用关心底层代码的实现方式,代码相对来说较安全
* 2.增加新的功能的时候,直接增加该功能对应的管理工厂即可,对源码没有任何影响
* 3.(缺点)工厂类会变得越来越多,导致代码变得繁琐
*/
/** * 1.定义工厂接口 */ public interface StudyFactory { IStudy getStudy(); } /*2.创建java工厂*/ public class JavaFactory implements StudyFactory { public IStudy getStudy() { return new JavaStudyImpl(); } } //创建php工厂 public class PhpFactory implements StudyFactory { public IStudy getStudy() { return new PhpStudyImpl(); } }
三、抽象工厂
抽象工厂模式更加注意的是家族关系,它适合用来生产一系列的族产品(抽象工厂之前一直没有搞清楚他与普通工厂的区别,因为例子比较少,看了很多博主的介绍,总结了一下)
假如说有两个电器,一个冰箱,一个空调
/** * 创建电器的接口,所有的电器都有工作的方法 */ public interface Bing { void work(); }
public interface Kong{
void work();
}
/** * 冰箱A、B实现工作的方法 */
public class BingA implements Bing{ @Override public void work() { System.out.println("冰箱A在工作"); } }
public class BingB implements Bing{ @Override public void work() { System.out.println("冰箱B在工作"); } }
/** * 空调A、B实现工作的方法 */
public class KongA implements Kong{ @Override public void work() { System.out.println("空调A在工作"); } }
public class KongB implements Kong{ @Override public void work() { System.out.println("空调B在工作"); } }
如果按照普通工厂模式,我们需要给空调A、B,冰箱A、B分别创建一个专门的工厂,也就是要创建4个工厂。但是使用抽象工厂的话, 他注重的是族关系,也就是,冰箱A、B都是冰箱这一个族的,空调A、B都是空调这个族的,因此抽象工厂的建造,就是按照这种族关系建的
/** * 创建抽象工厂 */ public interface AbstractFactory { Bing getBing(String bing); Kong getKong(String kong); } public class BingFactory implements AbstractFactory{ @Override public Bing getBing(String bing) { if (bing == "A") { return new BingA(); } else if (bing == "B") { return new BingB(); } return null; } @Override public Kong getKong(String kong) { return null; } } public class KongFactory implements AbstractFactory { @Override public Bing getBing(String bing) { return null; } @Override public Kong getKong(String kong) { if (kong == "A") { return new KongA(); } else if (kong == "B") { return new KongB(); } return null; } }
/**
* 抽象工厂的优缺点:
* 优点:是普通工厂以及简单工厂的结合,拥有两种工厂的优点,以及代码的公用性更高了
* 缺点:进行功能的新增或修改的时候,需要在底层的实现类与工厂类同时进行维护
*/
从上面可以看出,他就是简单工厂与普通工厂的结合,拥有两种工厂的优点,缺点也会得到适当的均和。