一、工厂模式
1. 什么是工厂模式
JAVA制造对象时,提供了“new”关键字,当“new”的时候,我们确实是在实例化一个具体的类,但是这样的代码在扩展的时候缺乏足够的弹性,难以应付更加复杂的情景。工厂模式定义了一个创建对象的接口,但由子类决定要实例化地类是哪一个。工厂模式让类把实例化推迟到子类。如果出现了更多个性化需求,通过实现工厂类产生相关的子类,我们就可以简单的实例化子类去实现这个需求,完全不需要去关注这个子类产生过程中需要怎样的步骤。工厂模式分为简单工厂模式,工厂方法模式,抽象工厂模式。
2.工厂模式的应用场景
客户端不知道它要创建的具体是哪一个子类。 一个类想要由自己的子类来定义某对象的创建过程。 类将创建某对象的职责代理给一些帮助子类中的一个,并且你想要将哪一个子类作为代理的信息进行局部化。
3.简单工厂模式
简单工厂模式又称静态工厂方法模式。它存在的目的很简单:定义一个用于创建对象的接口。我们先来看看它的组成:
1.工厂类角色:这是本模式的核心,含有一定的判断逻辑,用来创建产品
package factory.simplefactory;
/**
* @author zhangbj
* @version 1.0
* @Type SimpleFactory
* @Desc 工厂类
* @data 2017/6/28
*/
public class SimpleFactory {
public static Music getInstance (String style) {
switch (style){
case "jazz" : return new JazzMusic();
case "blues" : return new BluesMusic();
default : break ;
}
return null ;
}
}
2.抽象产品角色:它一般是具体产品继承的父类或者实现的接口。一般来说,它有该类产品共有的特征。
package factory.simplefactory;
/**
* @author zhangbj
* @version 1.0
* @Type Music
* @Desc
* @data 2017/6/28
*/
public abstract class Music {
public Music (){
System.out.println("the music is wonderful" );
}
}
3.具体产品角色:工厂类所创建的对象就是此角色的实例。在Java中由一个具体类实现。
package factory.simplefactory;
/**
* @author zhangbj
* @version 1.0
* @Type BluesMusic
* @Desc
* @data 2017/6/28
*/
public class BluesMusic extends Music {
public BluesMusic (){
System.out.println("play Blues Music" );
}
}
package factory.simplefactory;
/**
* @author zhangbj
* @version 1.0
* @Type JazzMusic
* @Desc
* @data 2017/6/28
*/
public class JazzMusic extends Music {
public JazzMusic (){
System.out.println("play Jazz Music" );
}
}
这样就形成了一个简单工厂模式。现在我们来测试一下:
package factory.simplefactory;
/**
* Created by PC on 2017/6/30.
*/
public class SimpleFactoryTest {
public static void main (String[] args) {
SimpleFactory.getInstance("jazz" );
SimpleFactory.getInstance("blues" );
}
}
结果:
the music is wonderful
play Jazz Music
the music is wonderful
play Blues Music
4.工厂方法模式
工厂方法模式去掉了简单工厂模式中工厂方法的静态属性,使得它可以被子类继承。这样在简单工厂模式里集中在工厂方法上的压力可以由工厂方法模式里不同的工厂子类来分担。 就好像简单工厂模式就只有一个音乐播放器,他既要播放Jazz,又要播放Blues(播放时如果要达到完美体验还必须调节音乐均衡器),那么如果我有多个音乐播放器,想听Jazz的时候开Jazz播放器,想听Blues的时候开Blues播放器这样不就好很多么。于是工厂方法模式就出现了,他拥有很多工厂(很多播放器),这些工厂同时继承一个抽象工厂(拥有播放音乐功能)。
工厂方法模式组成:
抽象工厂角色: 这s是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。
package factory.factorymethod;
import factory.simplefactory.Music;
/**
* @author zhangbj
* @version 1.0
* @Type MusicFactory
* @Desc
* @data 2017/6/30
*/
public interface MusicFactory {
Music createMusic();
}
具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。
package factory.factorymethod;
import factory.simplefactory.JazzMusic;
/**
* @author zhangbj
* @version 1.0
* @Type JazzFactory
* @Desc
* @data 2017/6/30
*/
public class JazzFactory implements MusicFactory {
@Override
public JazzMusic createMusic () {
return new JazzMusic();
}
}
package factory.factorymethod;
import factory.simplefactory.BluesMusic;
/**
* @author zhangbj
* @version 1.0
* @Type BluesFactory
* @Desc
* @data 2017/6/30
*/
public class BluesFactory implements MusicFactory {
@Override
public BluesMusic createMusic () {
return new BluesMusic();
}
}
抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。如简单工厂模式中的抽象产品角色一样
具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。如简单工厂模式中的具体产品角色一样。
3.抽象工厂模式
抽象工厂模式是工厂方法模式的升级版本,他用来创建一组相关或者相互依赖的对象。就拿音乐来说我想它可以在Linux和Windows的不同版本中播放。使用抽象工厂就可以解决这个问题:
产品类:
package factory.abstractfactory;
/**
* @author zhangbj
* @version 1.0
* @Type Linux
* @Desc Linux平台
* @data 2017/7/3
*/
public interface Linux {
}
package factory.abstractfactory;
/**
* @author zhangbj
* @version 1.0
* @Type CentOS
* @Desc
* @data 2017/7/3
*/
public class CentOS implements Linux {
public CentOS () {
System.out.print("用CentOS " );
}
}
package factory.abstractfactory;
/**
* @author zhangbj
* @version 1.0
* @Type Ubuntu
* @Desc
* @data 2017/7/3
*/
public class Ubuntu implements Linux {
public Ubuntu () {
System.out.print("用Ubuntu " );
}
}
package factory.abstractfactory;
/**
* @author zhangbj
* @version 1.0
* @Type Windows
* @Desc windows平台
* @data 2017/7/3
*/
public interface Windows {
}
package factory.abstractfactory;
/**
* @author zhangbj
* @version 1.0
* @Type Win7
* @Desc
* @data 2017/7/3
*/
public class Win7 implements Windows {
public Win7 () {
System.out.print("用 Win7 " );
}
}
package factory.abstractfactory;
/**
* @author zhangbj
* @version 1.0
* @Type WinXP
* @Desc
* @data 2017/7/3
*/
public class WinXP implements Windows {
public WinXP () {
System.out.print("用WinXP " );
}
}
工厂类:
package factory.abstractfactory;
/**
* @author zhangbj
* @version 1.0
* @Type PlatformFactory
* @Desc 平台接口
* @data 2017/7/3
*/
public interface PlatformFactory {
Windows useWindows();
Linux userLinux();
}
package factory.abstractfactory;
/**
* @author zhangbj
* @version 1.0
* @Type JazzMusic
* @Desc
* @data 2017/7/3
*/
public class JazzMusic implements PlatformFactory {
@Override
public Windows useWindows () {
return new WinXP();
}
@Override
public Linux userLinux () {
return new CentOS();
}
public static void main (String[] args) {
JazzMusic music = new JazzMusic();
music.userLinux();
music.useWindows();
}
}
总结
无论是简单工厂模式,工厂方法模式,还是抽象工厂模式,最终的目的就是为了解耦,随着产品结构的丰富而逐渐由简单工厂模式变为工厂方法模式,然后变为抽象工厂模式,反之递减。参考:http://blog.csdn.net/jason0539/article/details/23020989