常见设计模式

常见设计模式

• 创建型模式: – 单例模式、工厂模式、抽象工厂模式、建造者模式、原型模式。
• 结构型模式: – 适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模 式 。
• 行为型模式: – 模版方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模 式、解释器模式、状态模式、策略模式、职责链模式、访问者模式。

一:单例模式

单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

• 核心作用: – 保证一个类只有一个实例,并且提供一个访问该实例的全局访问点。

• 常见应用场景

– Application 也是单例的典型应用(Servlet编程中会涉及到) 
– 在Spring中,每个Bean默认就是单例的,这样做的优点是Spring容器可以管理 
– 在servlet编程中,每个Servlet也是单例 

• 单例模式的优点: – 由于单例模式只生成一个实例,减少了系统性能开销,当一个对象的产生需要 比较多的资源时,如读取配置、产生其他依赖对象时,则可以通过在应用启动 时直接产生一个单例对象,然后永久驻留内存的方式来解决 – 单例模式可以在系统设置全局的访问点,优化环共享资源访问,例如可以设计 一个单例类,负责所有数据表的映射处理

常见的五种单例模式实现方式:
– 主要: • 饿汉式(线程安全,调用效率高。 但是,不能延时加载。)
• 懒汉式(线程安全,调用效率不高。 但是,可以延时加载。)
– 其他: • 双重检测锁式(由于JVM底层内部模型原因,偶尔会出问题。不建议使用)
• 静态内部类式(线程安全,调用效率高。 但是,可以延时加载)
• 枚举单例(线程安全,调用效率高,不能延时加载)

• 饿汉式实现(单例对象立即加载)

public class SingletonDemo02 {
 private static  /*final*/   SingletonDemo02 s = new SingletonDemo02();
private SingletonDemo02(){} //私有化构造器

public static /*synchronized*/ SingletonDemo02 getInstance(){
 return s;  }} 

public class Client { 
public static void main(String[] args) {
 SingletonDemo02 s = SingletonDemo02.getInstance();
  SingletonDemo02 s2 = SingletonDemo02.getInstance(); 
  System.out.println(s==s2); //结果为true } }

• 饿汉式单例模式代码中,static变量会在类装载时初始化,此时也不会涉及多个线程对象访问该对象的问 题。虚拟机保证只会装载一次该类,肯定不会发生并发访问的问题。因此,可以省略synchronized关键字。
• 问题:如果只是加载本类,而不是要调用getInstance(),甚至永远没有调用,则会造成资源浪费!

• 懒汉式实现(单例对象延迟加载)

public class SingletonDemo01 {    
   private static SingletonDemo01 s;
    private SingletonDemo01(){} //私有化构造器
    public static synchronized SingletonDemo01 getInstance(){ 
    if(s==null){                        
     s = new SingletonDemo01();  }         
     return s;        }
}

• 要点: – lazy load! 延迟加载, 懒加载! 真正用的时候才加载!
• 问题: – 资源利用率高了。但是,每次调用getInstance()方法都要同步,并发 效率较低。

• 如何选用?
– 单例对象 占用 资源 少,不需要 延时加载: • 枚举式 好于 饿汉式
– 单例对象 占用 资源 大,需要 延时加载: • 静态内部类式 好于 懒汉式

*二:工厂模式

– 实现了创建者和调用者的分离。
– 详细分类: • 简单工厂模式 • 工厂方法模式 • 抽象工厂模式
• 核心本质: – 实例化对象,用工厂方法代替new操作。
– 将选择实现类、创建对象统一管理和控制。从而将调用者跟我们的实 现类解耦。

• 工厂模式:
– 简单工厂模式 • 用来生产同一等级结构中的任意产品。(对于增加新的产品,需要修改已 有代码)
– 工厂方法模式 • 用来生产同一等级结构中的固定产品。(支持增加任意产品)
– 抽象工厂模式 • 用来生产不同产品族的全部产品。(对于增加新的产品,无能为力;支持 增加产品族)

• 应用场景 – JDK中Calendar的getInstance方法 – JDBC中Connection对象的获取
 – Hibernate中SessionFactory创建Session 
 – spring中IOC容器创建管理bean对象 
 – XML解析时的DocumentBuilderFactory创建解析器对象
  – 反射中Class对象的newInstance()

 • 不使用简单工厂的情况
  public class Client01 {   //调用者
  public static void main(String[] args) {    
  Car c1 = new Audi();  
  Car c2 = new Byd();
  c1.run(); 
  c2.run();
  } }
– (1)简单工厂模式也叫静态工厂模式:
	就是工厂类一般是使用静态方法, 通过接收的参数的不同来返回不同的对象实例。
 – 对于增加新产品无能为力!不修改代码的话,是无法扩展的。
 public class ComputerFactory {
    public static Computer createComputer(String type){
        Computer mComputer=null;
        switch (type) {
            case "lenovo":
                mComputer=new LenovoComputer();
               break;
            case "hp":
                mComputer=new HpComputer();
                break;
            case "asus":
                mComputer=new AsusComputer();
                break;

        }
        return mComputer;
    }
}


public class CreatComputer {
    public static void main(String[]args){
      ComputerFactory.createComputer("hp").start();
    }
}
3 优点和缺点
3.1 优点
工厂类含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的责任,而仅仅“消费”产品;简单工厂模式通过这种做法实现了对责任的分割,它提供了专门的工厂类用于创建对象。
客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,对于一些复杂的类名,通过简单工厂模式可以减少使用者的记忆量。
通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。
3.2 缺点
由于工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响。
使用简单工厂模式将会增加系统中类的个数,在一定程序上增加了系统的复杂度和理解难度。
系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,同样破坏了“开闭原则”;在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护。
简单工厂模式由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构。
4 适用环境
在以下情况下可以使用简单工厂模式:
工厂类负责创建的对象比较少:由于创建的对象较少,不会造成工厂方法中的业务逻辑太过复杂。
客户端只知道传入工厂类的参数,对于如何创建对象不关心:客户端既不需要关心创建细节,甚至连类名都不需要记住,只需要知道类型所对应的参数。


(2)• 工厂方法模式要点: – 为了避免简单工厂模式的缺点,不完全满足OCP。
– 工厂方法模式和简单工厂模式最大的不同在于,简单工厂模式只有一个(对于一个项目 或者一个独立模块而言)工厂类,而工厂方法模式有一组实现了相同接口的工厂类。

(3) 抽象工厂模式 – 用来生产不同产品族的全部产品。(对于增加新的产品,无能为力; 支持增加产品族) – 抽象工厂模式是工厂方法模式的升级版本,在有多个业务品种、业务 分类时,通过抽象工厂模式产生需要的对象是一种非常好的解决方式。

三 :适配器模式
特点:

适配器继承或依赖已有的对象,实现想要的目标接口

消除由于接口不匹配所造成的类的兼容性问题

类的适配器模式、对象的适配器模式、接口的适配器模式

提高了类的复用,增加了类的透明度

(1)类的适配器模式

通过实现目标接口,继承原有类,在原有类的基础上增加接口中方法,将一个类转换成满足另一个新接口的类

Original.java

public class Original {
    public void show(){
        Log.i("msg", "This is Original");
    }
}

ExpandInterfacen .java

public interface ExpandInterfacen {
    void show();
    void hide();
}

NewAdapter .java

public class NewAdapter extends Original implements ExpandInterfacen {
    @Override
    public void hide() {
        Log.i("msg", "This is NewAdapter");
    }
}

使用如下

public void onClick(View view){
    NewAdapter adapter = new NewAdapter();
    adapter.hide();
    adapter.show();
}

(2)对象的适配器模式

不继承原有类,而是持有该类实例来实现兼容,将一个对象转换成满足另一个新接口的对象

ObjectAdapter.java

public class ObjectAdapter implements ExpandInterfacen {

    private Original mOriginal;

    public ObjectAdapter (){
        mOriginal = new Original();
    }

    @Override
    public void show() {
        mOriginal.show();
    }

    @Override
    public void hide() {
        Log.i("msg", "This is ObjectAdapter");
    }
}

使用如下

ObjectAdapter adapter = new ObjectAdapter();
adapter.show();
adapter.hide();

(3)接口的适配器模式

不希望实现一个接口中所有的方法,可选择一个抽象类实现接口,然后继承该抽象类实现想实现的方法即可

ExpandInterfacen.java

public interface ExpandInterfacen {
    void show();
    void hide();
    void close();
    void open();
}

AbstractInterface.java

public abstract class AbstractInterface implements ExpandInterfacen {

    @Override
    public void show() {

    }

    @Override
    public void hide() {

    }

    @Override
    public void close() {

    }

    @Override
    public void open() {

    }
}

Expand.java

public class Expand extends AbstractInterface {

    @Override
    public void show() {
        super.show();
    }

    @Override
    public void close() {
        super.close();
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值