门面模式
门面模式的应用场景
门面模式的通用写法
public class SubSystemA{
public void doA(){
System.out.println("doing A stuff"); } } public class SubSystemB{
public void doB(){
System.out.println("doing B stuff"); } } public class SubSystemC{
public void doC(){
System.out.println("doing C stuff"); } }
然后,创建外观角色Facade类:
public class Facade{
private SubSystemA a = new SubSystemA(); private SubSystemB b = new SubSystemB(); private SubSystemC c = new SubSystemC(); //对外接口 public void doA(){
this.a.doA(); } //对外接口 public void doB(){
this.b.doB(); } //对外接口 public void doC(){
this.c.doC(); } }
来看客户端代码:
public static void main(String[] args){
Facade facede = new Facade(); facade.doA(); facade.doB(); facade.doC(); }
门面模式业务场景实例
@Data public class GiftInfo{
private String name; }
然后,编写各个子系统的业务逻辑代码,分别创建积分系统QualifyService类:
public class QualifyService{
public boolean isAvailable(GiftInfo giftInfo){
System.out.println("校验"+giftInfo.getName()+"积分资格通过,库存通过"); } }
支付系统PaymentService类:
public class PaymentService{
public boolean pay(GiftInfo pointsGift){
//扣减积分 System.out.println("支付"+pointsGift.getName()+"积分成功"); return true; } }
物流系统ShippingService类:
public class shippingService{
//发货 System.out.println(giftInfo.getName()+"进入物流系统"); String shippingOrderNo = "666"; return shippingOrderNo; }
然后创建外观角色GiftFacadeService类,对外只开放一个月换礼物的exchange()方法,在exchange()方法内部整合3个子系统的所有功能。
public class giftFacadeService{
private QualifyService qualifyService = new QualifyService(); private PaymentService paymentService = new PaymentService(); private ShippingService shippingService = new ShippingService(); public void exchange(GiftInfo giftInfo){
if(qualifyService.isAvailable(giftInfo)){
if(paymentService.pay(giftInfo)){
String shippingNo = shippingService.delivery(giftInfo); System.out.println("物流系统下单成功,物流单号是:" + shippingNo); } } } }
最后,来看客户端代码:
public class Test {
public static void main(String[] args) {
FacadeService facadeService = new FacadeService(); GiftInfo giftInfo = new GiftInfo("《Spring 5核心原理》"); facadeService.exchange(giftInfo); } }
门面模式在源码中的应用
下面我们来门面模式在源码中的应用,先来看Spring JDBC模块下的JdbcUtils类,它封装了和JDBC相关的所有操作,它一个代码片段:
public abstract class JdbcUtils {
public static final int TYPE_UNKNOWN = -; private static final Log logger = LogFactory.getLog(JdbcUtils.class); private static final Map<Integer, String> typeNames = new HashMap(); public JdbcUtils() {
} public static void closeConnection(@Nullable Connection con) {
if (con != null) {
try {
con.close(); } catch (SQLException var2) {
logger.debug("Could not close JDBC Connection", var2); } catch (Throwable var3) {
logger.debug("Unexpected exception on closing JDBC Connection", var3); } } } public static void closeStatement(@Nullable Statement stmt) {
if (stmt != null) {
try {
stmt.close(); } catch (SQLException var2) {
logger.trace("Could not close JDBC Statement", var2); } catch (Throwable var3) {
logger.trace("Unexpected exception on closing JDBC Statement", var3); } } } public static void closeResultSet(@Nullable ResultSet rs) {
if (rs != null) {
try {
rs.close(); } catch (SQLException var2) {
logger.trace("Could not close JDBC ResultSet", var2); } catch (Throwable var3) {
logger.trace("Unexpected exception on closing JDBC ResultSet", var3); } } } ... }
再来看一个MyBatis中的Configuration类。它其中有很多new开头的方法,来看一下源代码:
public MetaObject newMetaObject(Object object) {
return MetaObject.forObject(object, this.objectFactory, this.objectWrapperFactory, this.reflectorFactory); } public ParameterHandler newParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) {
ParameterHandler parameterHandler = mappedStatement.getLang().createParameterHandler(mappedStatement, parameterObject, boundSql); parameterHandler = (ParameterHandler)this.interceptorChain.pluginAll(parameterHandler); return parameterHandler; } public ResultSetHandler newResultSetHandler(Executor executor, MappedStatement mappedStatement, RowBounds rowBounds, ParameterHandler parameterHandler, ResultHandler resultHandler, BoundSql boundSql) {
ResultSetHandler resultSetHandler = new DefaultResultSetHandler(executor, mappedStatement, parameterHandler, resultHandler, boundSql, rowBounds); ResultSetHandler resultSetHandler = (ResultSetHandler)this.interceptorChain.pluginAll(resultSetHandler); return resultSetHandler; } public StatementHandler newStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
StatementHandler statementHandler = new RoutingStatementHandler(executor, mappedStatement, parameterObject, rowBounds, resultHandler, boundSql); StatementHandler statementHandler = (StatementHandler)this.interceptorChain.pluginAll(statementHandler); return statementHandler; } public Executor newExecutor(Transaction transaction) {
return this.newExecutor(transaction, this.defaultExecutorType); } ...
上面的这些方法都是对JDBC中关键组件操作的封装。另外地在Tomcat的源码中也有体现,也非常的有意思。举个例子RequestFacade类,来看源码:
public class RequestFacade implements HttpServletRequest {
... public String getContentType() {
if (this.request == null) {
throw new IllegalStateException(sm.getString("requestFacade.nullRequest")); } else {
return this.request.getContentType(); } } public ServletInputStream getInputStream() throws IOException {
if (this.request == null) {
throw new IllegalStateException(sm.getString("requestFacade.nullRequest")); } else {
return this.request.getInputStream(); } } public String getParameter(String name) {
if (this.request == null) {
throw new IllegalStateException(sm.getString("requestFacade.nullRequest")); } else {
return Globals.IS_SECURITY_ENABLED ? (String)AccessController.doPrivileged(new RequestFacade.GetParameterPrivilegedAction(name)) : this.request.getParameter(name); } } public Enumeration<String> getParameterNames() {
if (this.request == null) {
throw new IllegalStateException(sm.getString("requestFacade.nullRequest")); } else {
return Globals.IS_SECURITY_ENABLED ? (Enumeration)AccessController.doPrivileged(new RequestFacade.GetParameterNamesPrivilegedAction()) : this.request.getParameterNames(); } } ... }
我们看名字就知道他用了门面模式。它封装了非常多的request的操作,也整合了很多servlet-api以外的一些内容,给用户提供了很大的便捷。同样,Tomcat对Response和Session当也封装了ResponseFacade和StandardSessionFacade类,感兴趣的小伙伴可以去深入了解一下。
门面模式的优缺点
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/224750.html原文链接:https://javaforall.net
