创建型模式————工厂模式(2.2)
什么是工厂模式?
工厂模式是创建型模式的一种,工厂是用来生产的,而在Java里,是用来生产对象实例的。
和单例模式相似,工厂模式同样聚焦于在考虑整个软件构建的情况下合理创建对象,从而保证软件的扩展性和稳定性。
工厂模式分为三种:
- 简单工厂模式
- 工厂方法模式
- 抽象工厂模式
简单工厂模式(实现服务端自扩展)
服务端:提供代码的人(作者)
客户端:使用代码的人(用户)
【对于程序员来说,自己是作者,用户是普通人;那么对于发明语言,框架的人来说,创建者是作者,而普通程序员是用户】
假设没有使用简单工厂模式:
定义一个Coder接口,然后定义JavaCoder和PythonCoder实现Coder接口。客户端通过new来创建对象。(耦合)
//服务端
interface Coder {
void express();
}
class JavaCoder implements Coder
{
@Override
public void express()
{
System.out.println("I am a Java Coder");
}
}
class PythonCoder implements Coder
{
@Override
public void express()
{
System.out.println("I am a Python Coder");
}
}
//===============================================================================
public class ProductManager //客户端
{
public static void main(String[] args) {
Coder javaCoder = new JavaCoder();
javaCoder.express();
}
}
当服务端需要扩展一个类时:需要进行1,2两步
//服务端
interface Coder {
void express();
}
class JavaCoder implements Coder
{
@Override
public void express()
{
System.out.println("I am a Java Coder");
}
}
class PythonCoder implements Coder
{
@Override
public void express()
{
System.out.println("I am a Python Coder");
}
}
class GoCoder implements Coder //1.服务端扩展
{
@Override
public void express()
{
System.out.println("I am a Go Coder");
}
}
//===============================================================================
public class ProductManager //客户端
{
public static void main(String[] args) {
Coder javaCoder = new JavaCoder();
javaCoder.express();
Coder goCoder = new GoCoder(); //2.客户端跟着修改
goCoder.express();
}
}
服务端和客户端处于高度耦合状态。(服务端的变化会引起客户端的变化)
使用简单工厂模式:(如果服务端要扩展一个GoCoder,客户端无需做修改)
//服务端
interface Coder {
void express();
}
class JavaCoder implements Coder
{
@Override
public void express()
{
System.out.println("I am a Java Coder");
}
}
class PythonCoder implements Coder
{
@Override
public void express()
{
System.out.println("I am a Python Coder");
}
}
class GoCoder implements Coder //1.服务端扩展
{
@Override
public void express()
{
System.out.println("I am a Go Coder");
}
}
class SimpleFactory
{
//使用静态内部类实现单例模式
private static class StaticClassInnerInstance {
private static final SimpleFactory INSTANCE = new SimpleFactory();
}
public static SimpleFactory getInstance() {
return StaticClassInnerInstance.INSTANCE;
}
public Coder createCoder(String language)
{
Coder coder = null;
if(language.equals("Java"))
{
coder= new JavaCoder();
}
else if(language.equals("Python"))
{
coder= new PythonCoder();
}
else if(language.equals("Go")) //2.扩展条件
{
coder= new GoCoder();
}
return coder;
}
}
//===============================================================================
public class ProductManager //客户端
{
public static void main(String[] args) {
SimpleFactory factory = SimpleFactory.getInstance();
Coder javaCoder = factory.createCoder("Java");
javaCoder.express();
}
}
简单工厂UML类图:
简单工厂的优缺点:
优点:
解决了服务端与客户端的耦合问题,实现了服务端的自扩展。
缺点:
当客户端需要进行功能扩展时,无法在SimpleFactory中添加对应修改代码。
简单工厂可以完成服务端的自扩展,但客户端只能调用,无法扩展。
工厂方法模式(实现客户端自扩展)
//服务端
interface Coder {
void express();
}
class JavaCoder implements Coder
{
@Override
public void express()
{
System.out.println("I am a Java Coder");
}
}
class PythonCoder implements Coder
{
@Override
public void express()
{
System.out.println("I am a Python Coder");
}
}
class GoCoder implements Coder //1.服务端扩展
{
@Override
public void express()
{
System.out.println("I am a Go Coder");
}
}
interface CoderFactory //抽象出CoderFactory
{
public Coder createCoder(String language);
}
class ServerFactory implements CoderFactory
{
private static class StaticClassInnerInstance {
private static final ServerFactory INSTANCE = new ServerFactory();
}
public static ServerFactory getInstance() {
return StaticClassInnerInstance.INSTANCE;
}
@Override
public Coder createCoder(String language)
{
Coder coder = null;
if(language.equals("Java"))
{
coder= new JavaCoder();
}
else if(language.equals("Python"))
{
coder= new PythonCoder();
}
else if(language.equals("Go")) //2.扩展条件
{
coder= new GoCoder();
}
return coder;
}
}
//===============================================================================
class RustCoder implements Coder
{
@Override
public void express()
{
System.out.println("I am a Rust Coder");
}
}
class ClientFactory implements CoderFactory
{
private static class StaticClassInnerInstance1 {
private static final ClientFactory INSTANCE = new ClientFactory();
}
public static ClientFactory getInstance() {
return ClientFactory.StaticClassInnerInstance1.INSTANCE;
}
@Override
public Coder createCoder(String language)
{
return new RustCoder();
}
}
public class ProductManager //客户端
{
public static void main(String[] args) {
ClientFactory clientFactory = ClientFactory.getInstance();
Coder coder = clientFactory.createCoder("Rust");
coder.express();
}
}
工厂方法UML类图:
工厂方法模式的优缺点:
优点:实现了客户端的自扩展。
缺点:无法扩展多个产品。
抽象工厂模式(实现产品簇)
适应多个产品,加入设计师。
抽象工厂中可以生产多个产品,产品之间存在内在联系。比如说JavaCoder对应JavaDesigner。
而实例化的工厂就是根据这种内在联系来划分的。
同一个工厂的产品属于一个产品簇,不同产品簇之间是不能互相组合的。比如说GoDesigner和PythonCoder是不能组合到一个工厂里的。
//服务端
interface Coder {
void express();
}
interface Designer {
void express();
}
class JavaCoder implements Coder
{
@Override
public void express()
{
System.out.println("I am a Java Coder");
}
}
class PythonCoder implements Coder
{
@Override
public void express()
{
System.out.println("I am a Python Coder");
}
}
class GoCoder implements Coder
{
@Override
public void express()
{
System.out.println("I am a Go Coder");
}
}
class JavaDesigner implements Designer
{
@Override
public void express()
{
System.out.println("I am a Java Designer!");
}
}
class PythonDesigner implements Designer
{
@Override
public void express()
{
System.out.println("I am a Python Designer!");
}
}
class GoDesigner implements Designer
{
@Override
public void express()
{
System.out.println("I am a Go Designer!");
}
}
interface ProductFactory
{
public Coder createCoder();
public Designer createDesigner();
}
class GoFactory implements ProductFactory
{
private static class StaticClassInnerInstance {
private static final GoFactory INSTANCE = new GoFactory();
}
public static GoFactory getInstance() {
return StaticClassInnerInstance.INSTANCE;
}
@Override
public Coder createCoder()
{
Coder coder= new GoCoder();
return coder;
}
@Override
public Designer createDesigner()
{
Designer designer= new GoDesigner();
return designer;
}
}
class JavaFactory implements ProductFactory
{
private static class StaticClassInnerInstance {
private static final JavaFactory INSTANCE = new JavaFactory();
}
public static JavaFactory getInstance() {
return StaticClassInnerInstance.INSTANCE;
}
@Override
public Coder createCoder()
{
Coder coder= new JavaCoder();
return coder;
}
@Override
public Designer createDesigner()
{
Designer designer= new JavaDesigner();
return designer;
}
}
//===============================================================================
public class ProductManager //客户端
{
public static void main(String[] args) {
JavaFactory javaFactory = JavaFactory.getInstance();
Coder coder =javaFactory.createCoder();
Designer designer = javaFactory.createDesigner();
coder.express();
designer.express();
}
}
抽象工厂UML类图:
工厂模式总结
简单工厂模式:适用客户端无需扩展的应用场景
工厂方法模式:适合客户端创建单个产品的应用场景
抽象工厂模式:适合创建多个产品的应用场景(但产品类别需要固定)
-------------------------------------------------------------------------------------------------------------2019.8.11