除了使用new操作符之外还有更多制造对象的方法,你将了解到实例化这个活动不应该总是公开地进行,也会认识到初始化经常造成耦合问题,工厂模式将帮你从复杂的依赖中脱困。
工厂模式可以分为三类:
第一个:简单工厂模式
简单工厂模式属于创建型模式,又叫做静态工厂方法模式,但是不属于23中GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。
用猪举个例子,猪有粉色的,黑色的。。。首先定义一个抽象接口
public interface Pigs{
void color();
}
然后定义粉色和黑色,都有颜色
public class PinkPig implements Pigs{
@Override
public void color() {
System.out.println("我是粉猪");
}
}
public class BlackPig implements Pigs{
@Override
public void color() {
System.out.println("我是黑猪");
}
}
最后写一个工厂,用来生产两种猪,
public class PigsFactory {
public static Pigs makePig(String type){
if("pink".equals(type)){
PinkPig pinkPig = new PinkPig();
return pinkPig;
}else if("black".equals(type)){
BlackPig blackPig = new BlackPig();
return blackPig;
}else{
System.out.println("生产不出来");
return null;
}
}
}
还有个客户要买猪
public class BuyPigs {
public static void main(String[] args) {
PigsFactory pigsFactory = new PigsFactory();
Pigs pinkPigs = pigsFactory .makePig("pink");
pinkPigs.color();
Pigs blackPigs = pigsFactory .makePig("black");
blackPigs.color();
}
}
输出结果
图形表示就是
简单来说就是客户告诉工厂买啥猪,工厂就会直接去牵一头对应的猪来给你。
简单工厂的优点:
通过使用工厂类,外界可以从直接创建具体产品对象的尴尬局面摆脱出来,仅仅需要负责“消费”对象就可以了。而不必管这些对象究竟如何创建及如何组织的; 明确了各自的职责和权利,有利于整个软件体系结构的优化;
简单工厂的缺点:
1:扩展性差,增加不同的子类还需要修改工厂方法;
2:不同的产品需要不同的额外参数的时候不支持;
也就是说,客户想要当前的颜色猪,是很方便的,但是如果客户想要一个白色的猪,还要去给猪改基因(源代码),添加分店(每一个分支可以理解为一个店)等等,很麻烦,但是没办法,客户是上帝,所以迎合客户需求,所以来试试抽象工厂。
第二分类:工厂方法模式
定义:
- 工厂方法模式是简单工厂模式的衍生,解决了许多简单工厂模式的问题。首先完全实现‘开-闭 原则’,实现了可扩展。其次更复杂的层次结构,可以应用于产品结果复杂的场合。
- 工厂方法模式去掉了简单工厂模式中工厂方法的静态属性,使得它可以被子类继承。这样在简单工厂模式里集中在工厂方法上的压力可以由工厂方法模式里不同的工厂子类来分担。
下面上代码:
修改工厂类为如下:
public class PigsFactory {
public Pigs PinkPig(){
return new PinkPig();
}
public Pigs BlackPig(){
return new BlackPig();
}
}
修改客户为:
public class BuyPigs {
public static void main(String[] args) {
PigsFactory pigsFactory = new PigsFactory();
Pigs pinkPigs = pigsFactory.PinkPig();
pinkPigs.color();
}
}
优点:
在工厂方法模式中,工厂方法用来创建客户所需要的产品,同时还向客户端隐藏了哪种具体产品类将被实例化这一细节,用户只需要关心所需要产品对应的工厂,无须关心创建细节,甚至无须知道具体产品类的类名。
基于工厂角色和产品角色的多态性设计是工厂方法的关键,他能够让工厂模式自主的创建产品对象,而如何创建这个对象的细节完全封装在工厂类。
使用工厂方法模式最大的优点就是你新加类的时候不用动源代码,只要写新的产品新的工厂来继承对应的类就行了。
缺点:
既是优点又是缺点,你要新加类型的时候,既要创建产品类,又要创建工厂类,增加了一大波类。在一定的程度上增加系统的复杂度。
由于考虑到系统的可在性,需要引入抽象层,在客户·端代码中均用抽象定义,更加难以理解!
也就是说客户想要别的品种的猪,虽然不用再开个店了,但是还是要去添加一个新品种出来,假如可以想要啥猪都能产出来就好了,所以抽象类就出来了
第三分类:抽象工厂模式
抽象工厂模式:提供一个创建一系列的相关的或者依赖的对象的接口,无需指定它们的具体实现类,具体的时间分别在子类工厂中产生。
首先添加一个接口:
public interface IPigsColor {
Pigs getPigs();
}
然后添加PinkBigFactor和BlackPigFactor类分别实现IPigsColor 接口:
public class PinkPigFactor implements IPigsColor{
@Override
public Pigs getPigs() {
return new PinkPig();
}
}
public class BlackPigFactor implements IPigsColor{
@Override
public Pigs getPigs() {
return new BlackPig();
}
}
客户类修改为:
public static void main(String[] args) {
IPigsColor iPigsColor = new PinkPigFactor();
Pigs pigs = iPigsColor.getPigs();
pigs.color();
}
现在结构如下图:
现在的情况就是客户想再要一个白猪或者灰猪,只需要创建一个工厂和一个具体实现然后直接调用就行了。
应用场景:
第一种情况是对于某个产品,调用者清楚地知道应该使用哪个具体工厂服务,实例化该具体工厂,生产出具体的产品来。Java Collection中的iterator() 方法即属于这种情况。
第二种情况,只是需要一种产品,而不想知道也不需要知道究竟是哪个工厂为生产的,即最终选用哪个具体工厂的决定权在生产者一方,它们根据当前系统的情况来实例化一个具体的工厂返回给使用者,而这个决策过程这对于使用者来说是透明的。