设计模式之简单工厂

所谓设计模式:在软件开发中,经过验证的,用于解决在特定环境下,重复出现的,特定问题解决方案.
对设计模式的理解:

  • 设计模式是解决某些问题的办法.
  • 设计模式不是凭空想象出来的,是经验的累积和总结.
  • 结构型模式:描述如何组织类和对象,以获得更大的结构.
  • 行为型模式:描述算法和对象间职责的分配.

学习设计模式第一步:准确理解每一个设计模式的功能,结构,标准实现,了解适合使用它的场景以及使用效果.
第二步:在实际开发中,尝试使用这些设计模式,并反复思考总结使用是否得当,是否需要做一些变化.


1. 简单工厂

严格来说,简单工厂并不属于标准的设计模式.但是很常用.所以可以作为热身来掌握.

1.1接口回顾

  • 接口的概念:接口是一种特殊的抽象类,跟一般的抽象类相比,接口里所有方法都是抽象方法,接口里所有属性都是常量.
  • 接口用来干什么:接口是用来定义实现类的外观,也就是实现类的行为定义.用来约束实现类的行为.
  • 接口的思想:接口的思想就是"封装隔离".
    封装通常的封装指的是对数据的封装.这里的封装指的是:对被隔离体的行为(或者说职责)的封装.
    隔离指的是:外部调用和内部实现的隔离,外部调用只能通过接口进行调用,外部调用时不知道内部实现的.也就是说外部调用和内部实现是被接口隔离开的.
  • 接口的好处:由于外部调用和内部实现是隔离开的,只要接口不变,内部实现的变化是不会影响外部调用的,从而使系统更加灵活,更好的扩展性和维护性.这也就是接口是系统可插拔性的保证这句话的意思
  • 接口和抽象类的选择:
    1.优先选择接口.2.既要定义子类的行为,有要为子类提供功能的功能时选择抽象类.

1.2 面向接口编程

java程序设计里面,非常讲究层的划分和模块的划分.通常按照三层来划分java程序:表现层,逻辑层,数据层.他们之间都要通过接口来通信.
在每一层有很多小模块,每个小模块对外则是一个整体.所以一个模块应该对外提供接口,当需要使用这个模块的功能时,可以通过这个接口来调用.这就是常说的:接口是其被隔离部分的外观.

既然java中需要面向接口编程,那么在程序中如何使用接口来做到面向接口编程呢?

1.3 场景问题

我们是怎么使用接口?假设有一个接口HelloApi,然后有一个实现类HelloApiImpl,然后创建一个实现类对象,那么客户端怎么用呢?
通常都是在客户端创建一个实现类对象实例,把它赋值给一个HelloApi接口类型的变量.然后客户端就可以通过这个变量来操作接口的功能了.代码示例:


public interface HelloApi {
	void hello(String s);
}

-------------------------
public class HelloApiImpl implements HelloApi {
	@Override
	public void hello(String s) {
		System.out.println("this is helloApiImpl..." + s);
	}
}

----------------------------------------
public class Test {
	public static void main(String[] args) {
		HelloApi helloApi = new HelloApiImpl();
		helloApi.hello("hello world");
	}
}

有什么问题?
客户端调用的时候:HelloApi helloApi = new HelloApiImpl();
客户端不仅知道了接口,还知道具体实现类就是HelloApiImpl.接口的思想是封装隔离,而实现类应该是被接口HelloApi封装并与客户端隔离开的,也就是说客户端根本不应该知道实现类就是HelloApiImpl.

1.4 解决方案

什么是简单工厂:提供创建一个具体实例的功能,而无需关心起具体实现.被创建的实例的类型可以是接口,抽象类,也可以是具体的类.
使用简单工厂来解决上述问题:

public interface HelloApi {
	void hello(String s);
}

-------------------------
public class HelloApiImpl implements HelloApi {
	@Override
	public void hello(String s) {
		System.out.println("this is helloApiImpl..." + s);
	}
}

----------------------------
public class HelloApiFactory {

	public static HelloApi create(){

		// 如果HelloApi接口有多种实现,可以通过参数传入条件
		// 根据不同条件,创建不同实现类.本例就一个实现类,所以就简单省略了.
		return new HelloApiImpl();
	}
}

------------------------------
public class Test {
	public static void main(String[] args) {
		// 重要改变,没有new HelloApiImpl了,如同上面
		HelloApi helloApi = HelloApiFactory.create();
		helloApi.hello("hello world");
	}
}

如同上面的示例,客户端通过简单工厂创建了一个实现接口的对象,然后面向接口编程.从客户端来看,他根本不知道具体的实现是什么,如何实现.它只知道通过简单工厂获得了一个接口对象,然后通过这个接口获取想要的功能.
事实上,简单工厂能够真正的帮助我们面向接口编程.之前的做法,其实只是用到了接口的多态,而最重要的"封装隔离性"并没有体现出来.

1.5模式讲解

典型疑问:简单工厂不就是把new HelloApiImpl()从客户端移到了简单工厂吗?把这句代码放到客户端和放到简单工厂有什么区别吗?
从前面的学习我们知道,接口是用来封装隔离具体实现的,目标就是不让客户端知道封装体内部的具体实现.简单工厂是位于封装体内的,是和接口,具体实现类在一起的,算是封装体内部的一个类.简单工厂结构图:
在这里插入图片描述
虚线框好比是一个组件的包装边界,表示接口,实现类,简单工厂组成了一个组件.在这个封装体里面,只有接口和工厂是对外的.

1.6 认识简单工厂

使用简单工厂的时候,通常不用创建工厂的类实例,所以把简单工厂类实现成一个工具类,直接使用静态方法就可以了.所以也被称为静态工厂.
理论上来讲,工厂什么都可以创建.但是对于简单工厂可创建对象的范围,通常不要太大,建议控制在一个组件级别或一个模块级别.否则工厂会职责不明,像一个大杂烩.
简单工厂类名建议"模块名称+Factory".方法名称建议"get+接口名称".
虽然说简单工厂的方法大多是用来创建接口的,但是真正实现功能的是接口的实现类,这些类是已经做好的,并不是要靠简单工厂来创建.所以简单工厂的方法的内部主要实现的功能是选择合适的实现类

简单工厂的本质:选择实现. 实现简单工厂的难点就在于"如何选择"实现.

何时选择简单工厂?
1.如果想要完全封装隔离具体实现,让外部只能通过接口来操作封装体.
2.如果想要把对外创建对象的职责集中管理和控制.

相关设计模式:
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值