常见设计模式

一:单列模式

      1:模式定义

            保证一个类只有一个实例,并且提供一个全局访问点。
 
      2:使用场景
 
             重量级的对象,不需要多个实例,如线程池,数据库连接池。
 
     3:实现方式
 
          a:懒汉式。即延迟加载, 只有在真正使用的时候,才开始实例化。
 
               注意点:给变量加上volatile是为了防止指令重排,正常的new一个对象的过程为:分配空间-->初始化-->引用赋值,如果不加volatile最后两步可能会颠倒过来
  
public class LazySingleton {
    private volatile static LazySingleton instance;
    public static LazySingleton getInstance(){
        if(instance==null){
            synchronized (LazySingleton.class){
                if(instance==null){
                    instance = new LazySingleton();
                }
            }
        }
        return instance;
    }
}

     b:饿汉模式。即初始化阶段就完成了 实例的初始化 。本质上就是借助于jvm类加载机制,保证实例的唯一性及线程安全

          类加载过程:

          1)加载二进制数据到内存中, 生成对应的Class数据结构, 
          2)连接: a. 验证, b.准备(给类的静态成员变量赋默认值),c.解析 
          3)初始化: 给类的静态变量赋初值

public class HungrySingleton {
    private static HungrySingleton instance = new HungrySingleton();
    private HungrySingleton(){ }
    public static HungrySingleton getInstance(){
        return instance;
    }
}

    c:静态内部类:本质上是利用类的加载机制来保证线程安全,只有在实际使用的时候,才会触发类的初始化,所以也是懒加载的一种

public class InnerClassSingleton {
    private static class InnerClassHolder{
        private static InnerClassSingleton instance = new InnerClassSingleton();
    }
    private InnerClassSingleton(){}
    public static InnerClassSingleton getInstance(){
        return InnerClassHolder.instance;
    }
}

二:工厂模式

       1:核心本质:

                a:实例化对象不使用new,用工厂方法代替

                b:将选择实现类,创建对象统一管理和控制。从而将调用者跟我们的实现类解耦。

       2:主要优点:

               将具体产品和创建者解耦
               符合单一职责原则
               符合开闭原则
 

        4:三种模式

                 a:简单工厂模式

                       用来生成同一等级结构中的任意产品。缺点:对于增加新的产品,需要覆盖已有的代码

                       核心代码:
public class CarFactory{
    public static Car getCar(String carName){
        if(carName=="奔驰"){
            return benchi();
        }else if (carName = "奥迪"){
            return aodi();
        }else{
            return null;
        }
    }
}

                 b:工厂方法模式

                       用来生产同一等级结构中的固定产品(支持增加任意产品)

                       核心代码:

                      先定义一个接口

                     public interface CarFactory(){ public car getCar(); }

                      对应的车实现该接口即可             

public class BenchiFactory implements CarFactory{

    @Override
    public car getCar() {
        return benchi();
    }
}

                 c:抽象工厂模式

                       围绕一个超级工厂创建其他工厂。

 

三:抽象工厂模式
 
        
 
 
 
          
 
 
 
四:建造者模式
 
       1:定义:将一个复杂对象的创建与他的表示分离,使得同样的构建过程可以创建不同的表示。
 
       2:主要作用:在用户不知道对象的建造过程和细节的情况下就可以直接创建复杂对象。
 
       3:代码编程(拿造房子来举例子)
 
         搜先有个抽象的Builder类似于房子的设计图纸:
          
public abstract class Bulid {
    abstract public void buildA();
    abstract public void buildB();
    abstract public void buildC();
    abstract public void buildD();
    abstract Product getProduct();
}
然后就算工人,即具体的Builder
 
public class Worker extends Bulid{
    private Product product;
    public Worker(){
        product = new Product();
    }
    @Override
    public void buildA() {
        product.setBuildA("A");
    }

    @Override
    public void buildB() {
        product.setBuildB("B");
    }

    @Override
    public void buildC() {
        product.setBuildC("C");
    }

    @Override
    public void buildD() {
        product.setBuildD("D");
    }

    @Override
    Product getProduct() {
        return product;
    }
}

具体的产品

public class Product {
    private String buildA;
    private String buildB;
    private String buildC;
    private String buildD;

    public void setBuildA(String buildA) {
        this.buildA = buildA;
    }

    public void setBuildB(String buildB) {
        this.buildB = buildB;
    }

    public void setBuildC(String buildC) {
        this.buildC = buildC;
    }

    public void setBuildD(String buildD) {
        this.buildD = buildD;
    }

    public String getBuildA() {
        return buildA;
    }

    public String getBuildB() {
        return buildB;
    }

    public String getBuildC() {
        return buildC;
    }

    public String getBuildD() {
        return buildD;
    }

    @Override
    public String toString() {
        return "Product{" +
                "buildA='" + buildA + '\'' +
                ", buildB='" + buildB + '\'' +
                ", buildC='" + buildC + '\'' +
                ", buildD='" + buildD + '\'' +
                '}';
    }
}

指挥者:(如果是无序的构造,可以不需要指挥者)
//指挥者
public class Director {
    public Product build(Bulid bulid){
        bulid.buildA();
        bulid.buildB();
        bulid.buildC();
        bulid.buildD();
        return bulid.getProduct();
    }
}
       
 
         
 
 
 
四:原型模式(Spring中的Bean也有使用)
 
       以某一个对象为原型进行拷贝,创建复杂对象是可以使用
 
       核心代码:
package com.xushan.bulid.prototype.demo01;

import java.util.Date;
/*
    1:实现Cloneable接口
    2:
 */
public class Video implements Cloneable{
    private String videoName;
    private Date createTime;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Video video = (Video)super.clone();
        //将对象的属性进行克隆,否则克隆出来的对象与原始对象中的属性指向同一个地址,会造成浅拷贝,如本对象中的createTime
        video.createTime = (Date)video.createTime.clone();
        return video;
    }

    public Video(String videoName, Date createTime) {
        this.videoName = videoName;
        this.createTime = createTime;
    }

    @Override
    public String toString() {
        return "Video{" +
                "videoName='" + videoName + '\'' +
                ", createTime=" + createTime +
                '}';
    }

    public void setVideoName(String videoName) {
        this.videoName = videoName;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public String getVideoName() {
        return videoName;
    }

    public Date getCreateTime() {
        return createTime;
    }
}
 
 
 
 
 
五:适配器模式
 
       1:定义:将一个类的接口转换成客户希望的另一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
 
          核心代码(电脑,网线,适配器举例子):
 
//要被适配的类,此处可以表示网线
public class Adaptee {
    public void request(){
        System.out.println("连接网线上网");
    }
}
//接口转换器的抽象实现
public interface NetToUsb {
    //作用处理请求
    public void handler();
}
   
/*
继承的方法实现也就是类适配器
public class Adapter extends Adaptee implements NetToUsb{
    @Override
    public void handler() {
        super.request();
    }
}
 */
//组合方式实现,即对象适配器,常用
public class Adapter implements NetToUsb{
    private Adaptee adaptee;

    public Adapter(Adaptee adaptee) {
        this.adaptee = adaptee;
    }

    @Override
    public void handler() {
        adaptee.request();
    }
}
//客户端类:电脑
public class Computer {
    public void net(Adapter adapter){
        //上网的具体实现,找一个转街头
        adapter.handler();
    }

    public static void main(String[] args) {
        /*
        类适配器的测试
        Computer computer = new Computer();
        Adapter adapter = new Adapter();
        computer.net(adapter);
        */
        //对象适配的测试
        Computer computer = new Computer();
        Adaptee adaptee = new Adaptee();
        Adapter adapter = new Adapter(adaptee);
        computer.net(adapter);
    }
}
      图解可以表示如下
       
 
 
六:桥接模式
 
       桥接模式是将抽象部分与它的实现部分分离,使他们都可以独立的变化。
 
       传统的多层继承结构(图一)违背了单一职责原则,复用性较差,类的个数也是非常的多,而桥接模式(图二)很好的解决了这个问题。
图一:
 
       
 
图二:
 
在Computer中通过组合的方式搭建了一座桥,
 
核心代码
 
先定义一个品牌的接口
//品牌
public interface Brand {
    public void info();
}
 对应的品牌实现接口
 
//苹果品牌
public class Apple implements Brand{
    @Override
    public void info() {
        System.out.println("苹果");
    }
}

类别,这里用抽象类Computer代替

//抽象的电脑类型
public abstract class Computer {
    //通过组合的方式搭建了一座桥
    protected Brand brand;

    public Computer(Brand brand) {
        this.brand = brand;
    }
    public void info(){
        brand.info();
    }
}
//具体的类别,比如台式电脑
class Desktop extends Computer{

    public Desktop(Brand brand) {
        super(brand);
    }
    public void info(){
        super.info();
        System.out.println("台式机");
    }
}

测试类:

public class Test {
    public static void main(String[] args) {
        Computer computer = new Desktop(new Apple());
        computer.info();
    }
}
     
 
 
七:代理模式
 
      一:静态代理模式
 
            1: 编码步骤:
 
             1)接口(抽象角色)
 
             2)真实角色(被代理的角色)
 
             3)代理角色
 
             4)客户端访问代理角色(客户)
 
            2:优缺点    
 
                  优点:可以使真实的操作更加纯粹,不必去关注一些公共的业务,方便集中管理
 
                  缺点:一个真实角色就会产生一个代理角色,代码量会翻倍
 
        二:动态代理模式
 
               核心代码(通用的代理模式):
 
               
public class ProxyInvocationHandler implements InvocationHandler {
    private Object object;

    public void setObject(Object object) {
        this.object = object;
    }

    public Object getProxy(){
       return Proxy.newProxyInstance(this.getClass().getClassLoader(),object.getClass().getInterfaces(),this );
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = method.invoke(object, args);
        return result;
    }
}
 
八:门面模式
 
    1:定义:为子系统中的一组接口提供一个一致的接口,Facade 模式定义了一个s高层接口,这个接口使得这一子系统更加容易使用
 
    2:应用场景:当您需要使用复杂子系统的有限但直接的接口时,请使用Facade模式。当您想要将子系统组织成层时,请使用Facade。
 
 
九:观察者模式
 
       定义:定义了对象之间的一对多依赖,让多个观察者对象同时监听某一个主题对象,当主题对象发生变化时,它的所有依赖者都会收到通知并更新。
 
      应用场景: 当更改一个对象的状态可能需要更改其他对象,并且实际的对象集事先 未知或动态更改时,请使用观察者模式。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值