java 设计模式详解(持续更新)

单例模式

观察者模式

装饰者模式

适配器模式

工厂模式

代理模式

单例模式

简单点说,就是一个应用程序中,某个类的实例对象只有一个,你没办法去new,因为构造器是被private修饰的,一般通过getInstance()的方法来获取它们的实例。

  1. 延时加载

    java 复制代码
    public class Singleton {  
       private static Singleton instance;  
       private Singleton (){}  
       public static synchronized Singleton getInstance() {  
       if (instance == null) {  
           instance = new Singleton();  
       }  
       return instance;  
       }  
    }
  2. 立即加载

    java 复制代码
    public class Singleton {  
       private static Singleton instance = new Singleton();  
       private Singleton (){}  
       public static Singleton getInstance() {  
       return instance;  
       }  
    }

观察者模式

对象间一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

示例:假设有三个人,小美(女,22),小王和小李。小美是被观察者,小王和小李是观察者,被观察者发出一条信息,然后观察者们进行相应的处理

• 定义接口

java 复制代码
public interface Person {
   //小王和小李通过这个接口可以接收到小美发过来的消息
   void getMessage(String s);
}

• 小王的实现类

java 复制代码
@Data
public class LaoWang implements Person {

   @Override
   public void getMessage(String s) {
       System.out.println("小王接到了小美打过来的电话,电话内容是:" + s);
   }

}

• 小李的实现类

java 复制代码
@Data
public class LaoLi implements Person {

   @Override
   public void getMessage(String s) {
       System.out.println("小李接到了小美打过来的电话,电话内容是:->" + s);
   }

}

• 小美的呼唤

java 复制代码
@Data
public class XiaoMei {

   List<Person> list = new ArrayList<Person>();

    public void addPerson(Person person){
        list.add(person);
    }

    //遍历list,把自己的通知发送给所有暗恋自己的人
    public void notifyPerson() {
        for(Person person:list){
            person.getMessage("你们过来吧,谁先过来谁就能陪我一起玩儿游戏!");
        }
    }
}

• 场景测试

java 复制代码
public class Test {
   public static void main(String[] args) {

       XiaoMei xiao_mei = new XiaoMei();
       LaoWang lao_wang = new LaoWang();
       LaoLi lao_li = new LaoLi();

       //小王和小李在小美那里都注册了一下
       xiao_mei.addPerson(lao_wang);
       xiao_mei.addPerson(lao_li);

       //小美向小王和小李发送通知
       xiao_mei.notifyPerson();
   }
}

装饰者模式

对已有的业务逻辑进一步的封装,使其增加额外的功能,用户在使用的时候,可以任意组装,达到自己想要的效果。

示例:三明治的组合(香肠+奶油+蔬菜+面包)

• 已有的业务类

java 复制代码
@Data
public class Food {

   private String foodName;

   public Food(String foodName) {
       this.foodName = foodName;
   }

   public String make() {
       return foodName;
   };
}

• 面包类

java 复制代码
//面包类
public class Bread extends Food {

   private Food basicFood;

   public Bread(Food basicFood) {
       this.basicFood= basicFood;
   }

   public String make() {
       return basicFood.make()+"+面包";
   }
}

• 奶油类

java 复制代码
//奶油类
public class Cream extends Food {

   private Food basicFood;

   public Cream(Food basicFood) {
       this.basicFood = basicFood;
   }

   public String make() {
       return basicFood.make()+"+奶油";
   }
}

• 蔬菜类

java 复制代码
//蔬菜类
public class Vegetable extends Food {

   private Food basicFood;

   public Vegetable(Food basicFood) {
       this.basicFood = basicFood;
   }

   public String make() {
       return basicFood.make()+"+蔬菜";
   }

}

• 测试组合

java 复制代码
public class Test {
   public static void main(String[] args) {
       Food food = new Bread(new Vegetable(new Cream(new Food("香肠"))));
       System.out.println(food.make());
   }
}

适配器模式

通过适配器将两种不同的事物联系起来。

示例:手机充电器需要的电压是20V,正常的电压是220V,增加一个变压器即可

java 复制代码
public class Test {
   public static void main(String[] args) {
       Phone phone = new Phone();
       VoltageAdapter adapter = new VoltageAdapter();
       phone.setAdapter(adapter);
       phone.charge();
   }
}

// 手机类
class Phone {

   public static final int V = 220;// 正常电压220v,是一个常量

   private VoltageAdapter adapter;

   // 充电
   public void charge() {
       adapter.changeVoltage();
   }

   public void setAdapter(VoltageAdapter adapter) {
       this.adapter = adapter;
   }
}

// 变压器
class VoltageAdapter {
   // 改变电压的功能
   public void changeVoltage() {
       System.out.println("正在充电...");
       System.out.println("原始电压:" + Phone.V + "V");
       System.out.println("经过变压器转换之后的电压:" + (Phone.V - 200) + "V");
   }
}

工厂模式

包含:简单工厂模式、工厂方法模式、抽象工厂模式

  1. 简答工厂模式

    一个抽象接口,多个实现抽象接口的类,一个工厂类(用来实例化抽象的接口)

    java 复制代码
    // 抽象产品类
    abstract class Car {
       public void run();
    
       public void stop();
    }
    
    // 具体实现类
    class Benz implements Car {
       public void run() {
           System.out.println("Benz开始启动了。。。。。");
       }
    
       public void stop() {
           System.out.println("Benz停车了。。。。。");
       }
    }
    
    class Ford implements Car {
       public void run() {
           System.out.println("Ford开始启动了。。。");
       }
    
       public void stop() {
           System.out.println("Ford停车了。。。。");
       }
    }
    
    // 工厂类
    class Factory {
       public static Car getCarInstance(String type) {
           Car c = null;
           if ("Benz".equals(type)) {
               c = new Benz();
           }
           if ("Ford".equals(type)) {
               c = new Ford();
           }
           return c;
       }
    }
    
    public class Test {
    
       public static void main(String[] args) {
           Car c = Factory.getCarInstance("Benz");
           if (c != null) {
               c.run();
               c.stop();
           } else {
               System.out.println("造不了这种汽车。。。");
           }
    
       }
    
    }
  2. 工厂方法模式

    有四个角色,抽象工厂模式,具体工厂模式,抽象产品模式,具体产品模式。
    不再是由一个工厂类去实例化具体的产品,而是由抽象工厂的子类去实例化产品

    java 复制代码
    // 抽象产品角色
    public interface Moveable {
       void run();
    }
    
    // 具体产品角色
    public class Plane implements Moveable {
       @Override
       public void run() {
           System.out.println("plane....");
       }
    }
    
    public class Broom implements Moveable {
       @Override
       public void run() {
           System.out.println("broom.....");
       }
    }
    
    // 抽象工厂
    public abstract class VehicleFactory {
       abstract Moveable create();
    }
    
    // 具体工厂
    public class PlaneFactory extends VehicleFactory {
       public Moveable create() {
           return new Plane();
       }
    }
    
    public class BroomFactory extends VehicleFactory {
       public Moveable create() {
           return new Broom();
       }
    }
    
    // 测试类
    public class Test {
       public static void main(String[] args) {
           VehicleFactory factory = new BroomFactory();
           Moveable m = factory.create();
           m.run();
       }
    }
  3. 抽象工厂模式

    与工厂方法模式不同的是,工厂方法模式中的工厂只生产单一的产品,而抽象工厂模式中的工厂生产多个产品

    java 复制代码
    public abstract class AbstractFactory {
       public abstract Vehicle createVehicle();
       public abstract Weapon createWeapon();
       public abstract Food createFood();
    }
    //具体工厂类,其中Food,Vehicle,Weapon是抽象类,
    public class DefaultFactory extends AbstractFactory{
       @Override
       public Food createFood() {
           return new Apple();
       }
       @Override
       public Vehicle createVehicle() {
           return new Car();
       }
       @Override
       public Weapon createWeapon() {
           return new AK47();
       }
    }
    //测试类
    public class Test {
       public static void main(String[] args) {
           AbstractFactory f = new DefaultFactory();
           Vehicle v = f.createVehicle();
           v.run();
           Weapon w = f.createWeapon();
           w.shoot();
           Food a = f.createFood();
           a.printName();
       }
    }

代理模式

将任务交由第三方处理即为代理模式。代理模式分静态代理和动态代理两种。

  1. 静态代理

    • 代理接口

    java 复制代码
    //代理接口
    public interface ProxyInterface {
    //需要代理的是结婚这件事,如果还有其他事情需要代理,比如吃饭睡觉上厕所,也可以写
    void marry();
    
    }

    • 代理实现

    java 复制代码
    public class WeddingCompany implements ProxyInterface {
    
    	private ProxyInterface proxyInterface;
    	
    	public WeddingCompany(ProxyInterface proxyInterface) {
    	 this.proxyInterface = proxyInterface;
    	}
    	
    	@Override
    	public void marry() {
    	 System.out.println("我们是婚庆公司的");
    	 System.out.println("我们在做结婚前的准备工作");
    	 System.out.println("节目彩排...");
    	 System.out.println("礼物购买...");
    	 System.out.println("工作人员分工...");
    	 System.out.println("可以开始结婚了");
    	 proxyInterface.marry();
    	 System.out.println("结婚完毕,我们需要做后续处理,你们可以回家了,其余的事情我们公司来做");
    	}
    
    }

    • 客户方

    java 复制代码
    public class NormalHome implements ProxyInterface{
    	@Override
    	public void marry() {
    	 System.out.println("我们结婚啦~");
    	}
    }

    • 场景测试

    java 复制代码
    public class Test {
    	public static void main(String[] args) {
    	 ProxyInterface proxyInterface = new WeddingCompany(new NormalHome());
    	 proxyInterface.marry();
    	}
    }
相关推荐
蓝天星空27 分钟前
spring cloud gateway 3
java·spring cloud
罗政32 分钟前
PDF书籍《手写调用链监控APM系统-Java版》第9章 插件与链路的结合:Mysql插件实现
java·mysql·pdf
一根稻草君38 分钟前
利用poi写一个工具类导出逐级合并的单元格的Excel(通用)
java·excel
kirito学长-Java40 分钟前
springboot/ssm网上宠物店系统Java代码编写web宠物用品商城项目
java·spring boot·后端
木头没有瓜1 小时前
ruoyi 请求参数类型不匹配,参数[giftId]要求类型为:‘java.lang.Long‘,但输入值为:‘orderGiftUnionList
android·java·okhttp
奋斗的老史1 小时前
Spring Retry + Redis Watch实现高并发乐观锁
java·redis·spring
high20111 小时前
【Java 基础】-- ArrayList 和 Linkedlist
java·开发语言
老马啸西风1 小时前
NLP 中文拼写检测纠正论文 C-LLM Learn to CSC Errors Character by Character
java
一条小小yu1 小时前
单例模式
单例模式
Cosmoshhhyyy1 小时前
LeetCode:3083. 字符串及其反转中是否存在同一子字符串(哈希 Java)
java·leetcode·哈希算法