前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >浅谈几种设计模式

浅谈几种设计模式

作者头像
田维常
发布2019-07-16 10:37:39
5290
发布2019-07-16 10:37:39
举报

设计模式分类

总体来说设计模式分为三大类:

创建型模式:

单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式。

结构型模式:

适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。

行为型模式:

策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

设计模式思维导图

单例模式

单例模式的八种写法

1、饿汉式(静态常量)[可用]

2、饿汉式(静态代码块)[可用]

3、懒汉式(线程不安全)[不可用]

4、懒汉式(线程安全,同步方法)[不推荐用]

5、懒汉式(线程安全,同步代码块)[不可用]

6、双重检查[推荐用]

7、静态内部类[推荐用]

8、枚举[推荐用]

简单工厂

又叫做静态工厂方法(StaticFactory Method)模式,但不属于23种GOF设计模式之一。

简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类。

Spring中的BeanFactory就是简单工厂模式的体现,根据传入一个唯一的标识来获得Bean对象,但是否是在传入参数后创建还是传入参数前创建这个要根据具体情况来定。

工厂方法模式

代码语言:javascript
复制
public abstract class AbstractDriverFactory {
  public abstract Animal createDriver();//这个方法是为了它的子类重写它的构造方法
}
public class ZhangFactory extends AbstractDriverFactory {
  @Override
  public Driver createDriver() {
    return new Zhang();//返回一个具体的对象老张。  
  }
}
public static void main(String[] args) {
  ZhangFactory zf = new ZhangFactory();//创建老张的工厂对象
  Driver driver = zf.createDriver();//再调用创建司机的方法
  driver.driveCar();//司机去开车
}

不得不说,工厂方法模式虽然完美符合了ocp开闭原则(Open Closed Principle)原则,但却使整个程序变得很沉重。就拿数据库来说,如果有100个访问数据库的类,那么就要创建100个这个类的工厂。

1.简单工厂模式:最大的优点就是在工厂中就包含了必要的判断,使用时只需要根据客户端的选择来实例化即可,对于客户端使用来说,去除了与具体产品的依赖。而缺点就是违背的ocp原则。假如未来要添加一个新的需求,则需要更改简单工厂中的判断语句。这对代码本身就不利。

2.工厂方法模式:最大的优点就是抽象化了简单工厂模式。再有新的需求进来时,不需要更改工厂的内容,符合了ocp原则。而缺点是每增加一个产品就要新增加一个相应的实例化工厂,增加了额外的开发量。

3.抽象工厂模式:分离了具体的类。不会出现在客户端代码中,易于交换产品系列。而且具体的工厂类只在它初始化的时候才会出现。这使得改变一个应用的具体工厂变得很容易~~缺点是,抽象工厂几乎确定了可以创建的对象的集合。加入新的类型对象就需要扩展其接口,这将涉及到具体工厂及其子类的修改。

三种工厂模式虽然用法各不相同,但它们的最终目的都是一致的----解耦。spring容器就是个大型的抽象工厂,不仅可以创建普通的bean实例,也可以创建bean工厂。

适配器模式

将一个类的接口转换成客户希望的另一个接口。适配器模式让那些接口不兼容的类可以一起工作,说白了就是为了挂羊头卖狗肉而专门设计的模式。也就是把一个类的接口变换成客户端所期待的另一种接口。

1 ,类的适配

(1)目标(Target)角色:这就是所期待得到的接口。注意:由于这里讨论的是类适配器模式,因此目标不可以是类。

(2)源(Adapee)角色:现在需要适配的接口。

(3)适配器(Adaper)角色:适配器类是本模式的核心。适配器把源接口转换成目标接口。显然,这一角色不可以是接口,而必须是具体类。

2, 对象的适配

  对象的适配依赖于对象的组合,而不是类适配中的继承。

还是以手机为例子,每一种机型都自带有从电器,有一天自带充电器坏了,而且市场没有这类型充电器可买了,怎么办?万能充电器就可以解决,这个万能充电器就是适配器。

首先来一个IPhone的充电器类(Adaptee角色):

代码语言:javascript
复制
public class IPhoneCharger {
     public void applePhoneCharge(){
         System.out.println("The iPhone is charging ...");
    }
}

要对这个特殊的充电器进行适配,上个适配的接口(Target角色):

代码语言:javascript
复制
 public interface ChargeAdapter {
   public void phoneCharge();
}

因为适配有两种,所以先进行类的适配示例,创建类的适配器:

代码语言:javascript
复制
public class UniversalCharger extends IPhoneCharger implements ChargeAdapter{
  @Override
    public void phoneCharge() {
        System.out.println("The phone is charging, but which kind of phone it is, who cares ...");
       super.applePhoneCharge();//iphone charging
    }
 }

这就是万能充电器了,我们让它来充个电,测试类准备:

代码语言:javascript
复制
public class AdapterClassTest {
    public static void main(String[] args) {
       ChargeAdapter charger = new UniversalCharger();
        charger.phoneCharge();
    } 
}

测试结果:

The phone is charging, but which kind of phone it is, who cares ... The iPhone is charging ...

以上是类的适配,我们还有种对象的适配方式,创建对象的适配器:

代码语言:javascript
复制
public class UniversalCharger implements ChargeAdapter{
     IPhoneCharger iphoneCharger;
     public UniversalCharger(IPhoneCharger iphoneCharger){
         this.iphoneCharger = iphoneCharger;
     }
     @Override
     public void phoneCharge() {
         System.out.println("The phone is charging, but which kind of phone it is, who cares ...");
         iphoneCharger.applePhoneCharge();    
     }
 }

对象适配器创建完毕,测一下:

代码语言:javascript
复制
public class AdapterObjectTest {
     public static void main(String[] args) {
         IPhoneCharger iphoneCharger = new IPhoneCharger();
         ChargeAdapter charger = new UniversalCharger(iphoneCharger);
        charger.phoneCharge();
     }
}

测试结果:

The phone is charging, but which kind of phone it is, who cares ... The iPhone is charging ...

总结一下:

(1)类的适配器模式:当希望将一个类转换成满足另一个新接口的类时,可以使用类的适配器模式,创建一个新类,继承原有的类,实现新的接口即可。

(2)对象的适配器模式:当希望将一个对象转换成满足另一个新接口的对象时,可以创建一个包装类,持有原类的一个实例,在包装类的方法中,调用实例的方法就行。

推荐阅读:

易懂版设计模式--门面模式

设计模式---命令模式

如何搞定Mybatis 中的 9 种设计模式

一篇搞定---装饰器模式

设计模式-Spring

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-05-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java后端技术栈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 设计模式分类
  • 设计模式思维导图
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档