1.普通工厂模式
概念
就是建立一个工厂类,对实现了同一接口的一些类进行实例的创建。简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例。
上图:
我们写一个蔡徐坤的特长的工厂类例子:
创建唱跳的共同接口Cxk
public interface Cxk {
public void Cxks();
}
创建唱和跳的实现类继承Cxk接口
public class Jump implements Cxk {
public void Cxks() {
System.out.println("这个人很会跳");
}
}
public class Sing implements Cxk{
public void Cxks() {
System.out.println("这个人很会唱");
}
}
最后建立工厂类
public class SendFactory {
public Cxk produce(String type){
if (type.equals("sing")){
return new Sing();
}else if(type.equals("jump")){
return new Jump();
}else {
System.out.println("我家gerger还不会这项技能哦");
return null;
}
}
}
测试下:
public class Main {
public static void main(String[] args) {
SendFactory sendFactory = new SendFactory();
Cxk cxk = sendFactory.produce("jump");
cxk.Cxks();
}
}
输出结果为:
该方法如果传入的字符串错误将无法建立实例。
2.多个工厂方法模式
概念
多个工厂方法模式,是对普通工厂方法模式的改进,在普通工厂方法模式中,如果传递的字符串出错,则不能正确创建对象,而多个工厂方法模式是提供多个工厂方法,分别创建对象。
如图所示:
将上面的代码做下修改,改动下SendFactory类就行,如下:
public class SendFactory2 {
public Cxk produceSing(){
return new Sing();
}
public Cxk produceJump(){
return new Jump();
}
}
执行测试:
public class Main {
public static void main(String[] args) {
SendFactory2 sendFactory2 = new SendFactory2();
Cxk cxk = sendFactory2.produceSing();
cxk.Cxks();
}
}
执行结果:
3.静态工厂方法模式
将上面的多个工厂方法模式里的方法置为静态的,不需要创建实例,直接调用即可。
public class SendFactory2 {
public static Cxk produceSing(){
return new Sing();
}
public static Cxk produceJump(){
return new Jump();
}
}
public class Main {
public static void main(String[] args) {
Cxk cxk =SendFactory2.produceSing();
cxk.Cxks();
}
}
执行结果:
总体来说,工厂模式适合:凡是出现了大量的产品需要创建,并且具有共同的接口时,可以通过工厂方法模式进行创建。在以上的三种模式中,第一种如果传入的字符串有误,不能正确创建对象,第三种相对于第二种,不需要实例化工厂类,所以,大多数情况下,我们会选用第三种——静态工厂方法模式。
好处:客户端不需要创建对象,明确了各个类的职责
缺点:该工厂类负责创建所有实例,如果有新的类加入,需要不断的修改工厂类,不利于后期的 维护
4.抽象工厂模式
抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的。抽象工厂模式可以向客户端提供一个接口,使得客户端在不必指定产品的具体类型的情况下,能够创建多个产品族的产品对象。
举例:粉丝们不再满足蔡徐坤一个人的唱和跳,主办方于是就请来了加拿大电鳗——吴亦凡(接口Wxf)来和蔡徐坤一起唱跳
接口:
//吴亦凡
public interface Wyf {
public void Wyfs();
}
//蔡徐坤
public interface Cxk {
public void Cxks();
}
实现类:
public class CxkSing implements Cxk{
public void Cxks() {
System.out.println("蔡徐坤唱");
}
}
public class CxkJump implements Cxk {
public void Cxks() {
System.out.println("蔡徐坤跳");
}
}
public class WxfSing implements Wyf {
public void Wyfs() {
System.out.println("吴亦凡唱");
}
}
public class WyfJump implements Wyf{
public void Wyfs() {
System.out.println("吴亦凡跳");
}
}
蔡徐坤工厂:
public class CxkFactory {
public static Cxk Sing(){
return new CxkSing();
}
public static Cxk Jump(){
return new CxkJump();
}
}
吴亦凡工厂:
public class WxfFactory {
public static Wyf Sing(){
return new WxfSing();
}
public static Wyf Jump(){
return new WyfJump();
}
}
测试
public class Main {
public static void main(String[] args) {
Cxk cxk = CxkFactory.Jump();
cxk.Cxks();
Cxk cxk1 = CxkFactory.Sing();
cxk1.Cxks();
System.out.println("===================================");
Wyf wyf =WxfFactory.Jump();
wyf.Wyfs();
Wyf wyf1 = WxfFactory.Sing();
wyf1.Wyfs();
}
}
运行结果
总结:
无论是简单工厂模式,工厂方法模式,还是抽象工厂模式,他们都属于工厂模式,在形式和特点上也是极为相似的,他们的最终目的都是为了解耦。在使用时,我们不必去在意这个模式到底工厂方法模式还是抽象工厂模式,因为他们之间的演变常常是令人琢磨不透的。经常你会发现,明明使用的工厂方法模式,当新需求来临,稍加修改,加入了一个新方法后,由于类中的产品构成了不同等级结构中的产品族,它就变成抽象工厂模式了;而对于抽象工厂模式,当减少一个方法使的提供的产品不再构成产品族之后,它就演变成了工厂方法模式。
所以,在使用工厂模式时,只需要关心降低耦合度的目的是否达到了。