设计模式
1.创建型模式
1.单例模式
//双重检查锁+内存可见性(设计模式) ->懒汉式线程安全
package com.atguigu.design.creatation.singleton;
/**
* 单例模式
* 双重检查锁+内存可见性(设计模式)
*/
public class Person {
private String name;
private String age;
//懒汉、饿汉
private volatile static Person instance; //饿汉
//private volatile static Person instance1 = new Person(); //懒汉
//构造器私有,外部不能实例化
private Person() {
System.out.println("创建了Person");
}
//提供给外部的方法
//1、public static synchronized Person guiguBoss() 锁太大
//2、双重检查锁+内存可见性(设计模式)
public static Person guiguBoss() {
//如果没有再去创建
if (instance == null) {
synchronized (Person.class) {
if(instance == null){ //如果这里不判断,则多线程会出现问题
Person person = new Person();
//多线程问题
instance = person;
}
}
}
return instance;
}
}
----------------------------------------------------------------------------------------------
//测试代码
import java.util.Map;
import java.util.Properties;
public class MainTest {
public static void main(String[] args) {
// Person person1 = Person.guiguBoss();
// Person person2 = Person.guiguBoss();
// System.out.println(person1 == person2);
// Properties properties = System.getProperties();
// System.out.println(properties);
//获取当前系统的环境变量
Map<String, String> getenv = System.getenv();
System.out.println(getenv);
}
}
--------------------------
//单例模式应用场景
数据库连接池, 线程池, 系统环境信息, 上下文
2.原型模式
本体拷贝一个克隆体 一个对象多个修改者的场景
深克隆/浅克隆
//对象 implements Cloneable
/**
* 是用于创建重复的对象,同时又能保证性能。
* 1、GuiguMyBatis:操作数据库,从数据库里面查出很多记录(70%改变很少)
* 2、每次查数据库,查到以后把所有数据都封装一个对象,返回。
* 10000 thread:查一个记录: new User("zhangsan",18);每次创建一个对象封装并返回
* 系统里面就会有10000个User;浪费内存
* 3、解决:缓存;查过的保存。
* 如果再查相同的记录,拿到原来的原型对象
*
* 4、此时直接拿到缓存中的对象。
*
*
*/
public class MainTest {
public static void main(String[] args) throws Exception {
GuiguMybatis mybatis = new GuiguMybatis();
//十分危险
//得到的是克隆体
User zhangsan1 = mybatis.getUser("zhangsan");
System.out.println("1==>"+zhangsan1);
zhangsan1.setUsername("李四2.。。");
System.out.println("zhangsan1自己改了:"+zhangsan1);
//得到的是克隆体
User zhangsan2 = mybatis.getUser("zhangsan");
System.out.println("2-->"+zhangsan2);
//得到的是克隆体
User zhangsan3 = mybatis.getUser("zhangsan");
System.out.println("3-->"+zhangsan3);
//得到的是克隆体
User zhangsan4 = mybatis.getUser("zhangsan");
System.out.println("4-->"+zhangsan4);
System.out.println(zhangsan1 == zhangsan3);
}
}
package com.atguigu.design.creatation.prototype;
/**
* 当前对象是可克隆的
*/
public class User implements Cloneable {
private String username;
private Integer age;
public User(){
System.out.println("User对象创建");
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", age=" + age +
'}';
}
/**
* 再创建一个人,赋予我的所有属性
* @return
* @throws CloneNotSupportedException
*/
@Override
protected Object clone() throws CloneNotSupportedException {
User user = new User();
user.setUsername(username);
user.setAge(age);
return user;
}
}
package com.atguigu.design.creatation.prototype;
import java.util.HashMap;
import java.util.Map;
public class GuiguMybatis {
//缓存user.序列化和反序列化-深克隆
private Map<String,User> userCache = new HashMap<>();
/**
* 从数据库查数据
* @return
*/
public User getUser(String username) throws Exception {
User user = null;
//缓存中没有
if(!userCache.containsKey(username)){
//查询数据库
user = getUserFromDb(username);
}else {
//从缓存中直接拿,脏缓存问题
//原型已经拿到,但是不能直接给。(本人)
user = userCache.get(username);
System.out.println("从缓存中拿到的是:"+user);
//从这个对象快速得到一个克隆体(克隆人)==原型模式
user = (User) user.clone();
}
return user;
}
private User getUserFromDb(String username) throws Exception{
System.out.println("从数据库查到:"+username);
User user = new User();
user.setUsername(username);
user.setAge(18);
//给缓存中放一个clone
userCache.put(username, (User) user.clone());
return user;
}
}
3.工厂模式
3.1简单工厂(不用)
AbstractCar
package com.atguigu.design.creatation.factory.simplefactory;
/**
* 工厂的产品
*/
public abstract class AbstractCar {
String engine;
public abstract void run();
}
MainTest
package com.atguigu.design.creatation.factory.simplefactory;
public class MainTest {
public static void main(String[] args) {
WuLinSimpleFactory factory = new WuLinSimpleFactory();
AbstractCar van = factory.newCar("van");
AbstractCar mini = factory.newCar("mini");
AbstractCar zz = factory.newCar("zz");
van.run();
mini.run();
}
}
MiniCar
package com.atguigu.design.creatation.factory.simplefactory;
/**
* 简单工厂
*/
public class MiniCar extends AbstractCar{
public MiniCar(){
this.engine = "四缸水平对置发动机";
}
@Override
public void run() {
System.out.println(engine+"--> 嘟嘟嘟...");
}
}
VanCar
package com.atguigu.design.creatation.factory.simplefactory;
/**
* 具体产品
*/
public class VanCar extends AbstractCar{
public VanCar(){
this.engine = "单杠柴油机";
}
@Override
public void run() {
System.out.println(engine+"--》嗒嗒嗒....");
}
}
WuLinSimpleFactory
package com.atguigu.design.creatation.factory.simplefactory;
/**
* 简单工厂
* 1、产品数量极少
*/
public class WuLinSimpleFactory {
/**
*
* @param type Class: 好像具有扩展性,但是没有解决实际问题
* @return
*/
public AbstractCar newCar(String type){
//核心方法:一切从简
if("van".equals(type)){
// 钣金、喷漆、放发动机、申请环保
return new VanCar();
}else if("mini".equals(type)){
return new MiniCar();
}
//.....
//更多的产品,违反开闭原则。应该直接扩展出一个类来造
return null;
}
}
3.2 工厂方法
四个角色: 抽象产品 具体产品 抽象工厂 具体工厂
AbstractCar
package com.atguigu.design.creatation.factory.factorymethod;
/**
* 工厂的产品
*
* 怎么把一个功能提升一个层次:定义抽象(抽象类,接口)
* 抽象类,接口 就会有多实现,多实现自然就有多功能
*/
public abstract class AbstractCar {
String engine;
public abstract void run();
}
AbstractCarFactory
package com.atguigu.design.creatation.factory.factorymethod;
/**
* 抽象工厂的层级
*/
public abstract class AbstractCarFactory {
public abstract AbstractCar newCar();
//我能造口罩.....
}
MainTest
package com.atguigu.design.creatation.factory.factorymethod;
public class MainTest {
public static void main(String[] args) {
AbstractCarFactory carFactory = new WulinRacingCarFactory();
AbstractCar abstractCar = carFactory.newCar();
abstractCar.run();
carFactory = new WulinVanCarFactory();
AbstractCar abstractCar1 = carFactory.newCar();
abstractCar1.run();
}
}
MiniCar
package com.atguigu.design.creatation.factory.factorymethod;
public class MiniCar extends AbstractCar {
public MiniCar(){
this.engine = "四缸水平对置发动机";
}
@Override
public void run() {
System.out.println(engine+"--> 嘟嘟嘟...");
}
}
RacingCar
package com.atguigu.design.creatation.factory.factorymethod;
public class RacingCar extends AbstractCar{
public RacingCar(){
this.engine = "v8发动机";
}
@Override
public void run() {
System.out.println(engine+"=--嗖.....");
}
}
VanCar
package com.atguigu.design.creatation.factory.factorymethod;
/**
* 具体产品
*/
public class VanCar extends AbstractCar {
public VanCar(){
this.engine = "单杠柴油机";
}
@Override
public void run() {
System.out.println(engine+"--》嗒嗒嗒....");
}
}
WulinMinCarFactory
package com.atguigu.design.creatation.factory.factorymethod;
/**
* minicar分厂
*/
public class WulinMinCarFactory extends AbstractCarFactory{
@Override
public AbstractCar newCar() {
return new MiniCar();
}
}
WulinRacingCarFactory
package com.atguigu.design.creatation.factory.factorymethod;
/**
* RacingCar分厂
*/
public class WulinRacingCarFactory extends AbstractCarFactory{
@Override
public AbstractCar newCar() {
return new RacingCar();
}
}
WulinVanCarFactory
package com.atguigu.design.creatation.factory.factorymethod;
public class WulinVanCarFactory extends AbstractCarFactory {
@Override
public AbstractCar newCar() {
return new VanCar();
}
}
3.3抽象工厂
public abstract class WulinFactory {
List<String> rules;
abstract AbstractCar newCar();
abstract AbstractMask newMask();
}
/**
* wulin口罩集团
* 分类 继续是 抽象类 抽象方法再由具体的子类去实现
*/
public abstract class WulinMaskFactory extends WulinFactory{
@Override
AbstractCar newCar() {
return null;
}
abstract AbstractMask newMask();
}
/**
* 分厂:否则口罩
*/
public class WulinWuHanMaskFactory extends WulinMaskFactory{
@Override
AbstractMask newMask() {
return new N95Mask();
}
}
4.建造者模式/builder
Phone
//主类
package com.atguigu.design.creatation.builder;
import lombok.*;
@Data
@Builder
public class Phone {
protected String cpu;
protected String mem;
protected String disk;
protected String cam;
}
XiaomiBuilder
package com.atguigu.design.creatation.builder;
public class XiaomiBuilder extends AbstractBuilder{
public XiaomiBuilder(){
//无参构造
phone = Phone.builder().build();
}
@Override
AbstractBuilder customCpu(String cpu) {
phone.cpu = cpu;
return this; //使用链式调用,这里需要返回本类
}
@Override
AbstractBuilder customMem(String mem) {
phone.mem = mem;
return this;
}
@Override
AbstractBuilder customDisk(String disk) {
phone.disk = disk;
return this;
}
@Override
AbstractBuilder customCam(String cam) {
phone.cam = cam;
return this;
}
}
AbstractBuilder
package com.atguigu.design.creatation.builder;
/**
* 抽象建造者
*/
public abstract class AbstractBuilder {
Phone phone;
abstract AbstractBuilder customCpu(String cpu);
abstract AbstractBuilder customMem(String mem);
abstract AbstractBuilder customDisk(String disk);
abstract AbstractBuilder customCam(String cam);
Phone getProduct(){
return phone;
}
}
MainTest
package com.atguigu.design.creatation.builder;
public class MainTest {
public static void main(String[] args) {
AbstractBuilder builder = new XiaomiBuilder();
//链式建造者
Phone phone = builder.customCpu("骁龙8个8")
.customCam("2亿")
.customDisk("1T")
.customMem("16G")
.getProduct();
System.out.println(phone);
Phone build = Phone.builder()
.cpu("1")
.mem("2")
.cam("3")
.disk("4")
.build();
System.out.println(build);
}
}
2.结构型模式
怎样组合对象/类
类结构模式
对象结构模式
1.适配器
两个不兼容接口之间适配的桥梁
Player接口
public interface Player {
String play();
}
Translator接口
public interface Translator {
String translate(String content);
}
Zh_JPTranslator
public class Zh_JPTranslator implements Translator{
@Override
public String translate(String content) {
if("你好".equals(content)){
return "空尼几哇";
}
if ("什么".equals(content)){
return "纳尼";
}
return "*******";
}
}
MoviePlayer
public class MoviePlayer implements Player {
@Override
public String play() {
System.out.println("正在播放:宋老师的宝贵时间.avi");
String content = "你好";
System.out.println(content); //并且打印出字幕
return content;
}
}
类结构模型适配器
import com.atguigu.design.structural.adapter.Player;
import com.atguigu.design.structural.adapter.Zh_JPTranslator;
/**
* 继承的方式:类结构模型,适配转换到了翻译器的功能上
* 类适配器 : 继承+实现
*/
public class JPMoviePlayerAdapter extends Zh_JPTranslator implements Player {
private Player target;//被适配对象
public JPMoviePlayerAdapter(Player target){
this.target = target;
}
@Override
public String play() {
String play = target.play();
//转换字幕
String translate = translate(play);
System.out.println("日文:"+translate);
return play;
}
}
-----------------------------------------------------------------------------------------------
//测试类
public class MainTest {
public static void main(String[] args) {
MoviePlayer player = new MoviePlayer();
player.play();
}
}
对象结构模型适配器
/**
* 组合的方式:对象结构模型,适配转换到了翻译器的功能上
* (继承、组合)、封装、多态
*/
public class JPMoviePlayerAdapter implements Player {
//组合的方式
private Translator translator = new Zh_JPTranslator();
private Player target;//被适配对象(原有的接口)
public JPMoviePlayerAdapter(Player target){
this.target = target;
}
@Override
public String play() {
String play = target.play();
//转换字幕
String translate = translator.translate(play);
System.out.println("日文:"+translate);
return play;
}
}
2.桥接模式
将抽象与实现分离(当多个变化因素在多个对象间共享时)
public class IPhone extends AbstractPhone{
@Override
String getPhone() {
return "IPhone:"+sale.getSaleInfo();
}
}
public abstract class AbstractSale {
private String type;
private Integer price;
public AbstractSale(String type,Integer price){
this.type = type;
this.price = price;
}
String getSaleInfo(){
return "渠道:"+type+"==>"+"价格:"+price;
}
void howToSale(){
}
}
/**
* 1、抽象手机类
* 手机有各种销售渠道价格都不一样
*
*/
public abstract class AbstractPhone {
//桥接在此.....设计期间就得想好
//【真正会引起此类变化的一个维度直接抽取出来,通过组合的方式接起来】
//桥接+适配器 ...
AbstractSale sale; //分离渠道【桥接的关注点】
/**
* 当前手机的描述
*/
abstract String getPhone();
public void setSale(AbstractSale sale) {
this.sale = sale;
}
}
public class StudentSale extends AbstractSale{
public StudentSale(String type, Integer price) {
super(type, price);
}
}
--------------------------------------------测试类----------------------------------------------
/**
* 省去了创建很多类
*/
public class MainTest {
IPhone iPhone = new IPhone();
//set的是 对象的属性
iPhone.setSale(new StudentSale("学生",1));
//通过抽象的具体属性类 获取 抽象属性
String phone = iPhone.getPhone();
System.out.println(phone);
}
}
3.装饰器模式
向一个现有的独享添加新的功能,同时不改变其结构
//适配器是连接两个类,增强一个类 //装饰器只装饰一个类
public class LeiTikTok implements ManTikTok{
@Override
public void tiktok() {
System.out.println("雷丰阳,tiktok.... ");
}
}
/**
* 抽象构建
*/
public interface ManTikTok {
void tiktok();
}
/**
* 抽象装饰器
* 抖音直播装饰器
*/
public interface TiktokDecorator extends ManTikTok{
void enable();
}
public class ZhangTikTok implements ManTikTok{
@Override
public void tiktok() {
System.out.println("张三,tiktok.... ");
}
}
/**
* 美颜装饰器
* 装饰谁
* 装饰器只关系增强这个类的方法。
*/
public class MeiYanDecorator implements TiktokDecorator{
private ManTikTok manTikTok;
public MeiYanDecorator(ManTikTok manTikTok){
this.manTikTok = manTikTok;
}
@Override
public void tiktok() {
//开启美颜
enable(); //调用继承里边的方法
//我开始直播
manTikTok.tiktok();
}
/**
* 定义的增强功能
*/
@Override
public void enable() { //对继承的方法进行增强
System.out.println("看这个美女.....");
System.out.println("花花花花花花花花花花花");
}
}
/**
* 核心:想要不改变原来接口方法的情况下扩展新功能,或者增强方法.....
*/
public class MainTest {
public static void main(String[] args) {
//被装饰对象
ManTikTok manTikTok = new LeiTikTok();
MeiYanDecorator decorator = new MeiYanDecorator(manTikTok);
decorator.tiktok();//通过这个调用(重写实现类的方法), 然后 增强继承里边的方法
}
}
4.代理模式
1.静态代理
//被代理对象是一个接口, 从代理对象类实现增强功能 和 输出原始功能
/**
* 抽象主体。被代理角色能干什么
*/
public interface ManTikTok {
void tiktok();
}
LiMingTiktokProxy
/**
* 代理一般都是和被代理对象属于同一个接口
*/
public class LiMingTiktokProxy implements ManTikTok{
private ManTikTok manTikTok; //被代理对象
public LiMingTiktokProxy(ManTikTok manTikTok){
this.manTikTok = manTikTok;
}
/**
* 宋喆(代理) 宝强(被代理对象)
*/
@Override
public void tiktok() {
//这里是增强功能
System.out.println("渲染直播间....");
System.out.println("课程只要666,仅此一天....");
//这里调用的是主方法
manTikTok.tiktok();
}
}
ZhangTikTok
public class ZhangTikTok implements ManTikTok {
@Override
public void tiktok() {
System.out.println("张三,tiktok.... ");
}
}
LeiTikTok
/**
* 主体 主类 被代理的对象
*/
public class LeiTikTok implements ManTikTok {
@Override
public void tiktok() {
System.out.println("雷丰阳,tiktok.... ");
}
}
MainTest
/**
* 代理的东西不一样,每一种不同的被代理类Person、Dog、Cat,创建不同的静态代理类
*/
public class MainTest {
public static void main(String[] args) {
LiMingTiktokProxy proxy = new LiMingTiktokProxy(new LeiTikTok());
proxy.tiktok();
//静态代理就是装饰器
//装饰器模式是代理模式的一种
}
}
2.动态代理
* 动态代理模式:
* JDK要求被代理对象必须有接口
* 代理对象和目标对象的相同点在于都是同一个接口
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 敲10遍
* @param <T>
*/
public class JdkTiktokProxy<T> implements InvocationHandler {
private T target;
//接受被代理对象
JdkTiktokProxy(T target){
this.target = target;
}
/**
* 获取被代理对象的 代理对象
* @param t
* @param <T>
* @return
*/
public static<T> T getProxy(T t) {
/**
* ClassLoader loader, 当前被代理对象的类加载器
* Class<?>[] interfaces, 当前被代理对象所实现的所有接口
* InvocationHandler h,
* 当前被代理对象执行目标方法的时候我们使用h可以定义拦截增强方法
*/
Object o = Proxy.newProxyInstance(
t.getClass().getClassLoader(),
t.getClass().getInterfaces(), //必须接口
new JdkTiktokProxy(t));
return (T)o;
}
/**
* 定义目标方法的拦截逻辑;每个方法都会进来的
*
* @param proxy
* @param method
* @param args
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy,
Method method,
Object[] args) throws Throwable {
//反射执行
System.out.println("真正执行被代理对象的方法");
Object invoke = method.invoke(target, args);
System.out.println("返回值:一堆美女");
return invoke;
}
}
3.cglib代理
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
* 1、使用cglib帮我们创建出代理对象
*/
public class CglibProxy {
//为任意对象创建代理
public static<T> T createProxy(T t){
//1、创建一个增强器
Enhancer enhancer = new Enhancer();
//2、设置要增强哪个个类的功能。增强器为这个类动态创建一个子类
enhancer.setSuperclass(t.getClass());
//3、设置回调
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object obj,
Method method, //为了能获取到原方法的一些元数据信息
Object[] args,
MethodProxy proxy) throws Throwable {
//编写拦截的逻辑 这里实现的是增强的逻辑
System.out.println("cglib上场le .......xxx");
//当前方法的信息
// method.get
// method.getAnnotation()
//目标方法进行执行
Object invoke = proxy.invokeSuper(obj,args);
return invoke;
}
});
Object o = enhancer.create();
return (T) o;
}
}
测试类
public class CglibTest {
public static void main(String[] args) {
//原来的对象都不用new
LeiTikTok tikTok = new LeiTikTok();
LeiTikTok proxy = CglibProxy.createProxy(tikTok);
proxy.tiktokHaha();
}
}
5.外观模式
//提供一个统一入口,相当于网关转发
6.组合模式
相当于多叉树,字典树
7.享元模式
尝试重用现有的同类对象,如果未匹配到的对象,则创新建对象
AbstractWaitressFlyweight
package com.atguigu.design.structural.flyweight;
/**
* 可共享和不可共享状态
*/
public abstract class AbstractWaitressFlyweight {
boolean canService = true;//能否服务
//正在服务。 享元的不可共享属性留给外部进行改变的接口
abstract void service();
//服务完成。 享元的不可共享属性留给外部进行改变的接口
abstract void end();
public boolean isCanService() {
return canService;
}
}
BeautifulWaitress
package com.atguigu.design.structural.flyweight;
import lombok.AllArgsConstructor;
/**
* 具体享元类
*/
@AllArgsConstructor
public class BeautifulWaitress extends AbstractWaitressFlyweight{
String id;//工号
String name;//名字
int age;//年龄
//以上是不变的
@Override
void service() {
System.out.println("工号:"+id+";"+name+" "+age+" 正在为您服务...");
//可以服务,为false,外部不可以使用
this.canService = false;
}
@Override
void end() {
//不可以服务,外部不能共享此变量
System.out.println("工号:"+id+";"+name+" "+age+" 服务结束...请给五星好评");
//调用end方法的时候设置为 true,会把池中的对象释放,下面才能继续使用
this.canService = true;
}
}
package com.atguigu.design.structural.flyweight;
import java.util.*;
/**
* 足道店:这相当于享元工厂
* 店里面很多服务员。
*
* 享元和原型
* 1、享元返回的是这个本人。
* 2、原型返回的是克隆人。
*
*/
public class ZuDao {
private static Map<String,AbstractWaitressFlyweight> pool = new HashMap<>();
//享元,池子中有对象
static {
BeautifulWaitress waitress =
new BeautifulWaitress("1111","张三",18);
BeautifulWaitress waitress2 =
new BeautifulWaitress("9527","李四",20);
pool.put(waitress.id,waitress);
pool.put(waitress2.id,waitress2);
}
public void addWaitress(AbstractWaitressFlyweight waitressFlyweight){
pool.put(UUID.randomUUID().toString(),waitressFlyweight);
}
public static AbstractWaitressFlyweight getWaitress(String name){
AbstractWaitressFlyweight flyweight = pool.get(name);
if(flyweight == null){
for (AbstractWaitressFlyweight value : pool.values()) {
//当前共享对象能否是否
if(value.isCanService()){
return value;
}
};
return null;
}
return flyweight;
}
}
MainTest
package com.atguigu.design.structural.flyweight;
/**
*
*/
public class MainTest {
public static void main(String[] args) {
//1、我
AbstractWaitressFlyweight waitress = ZuDao.getWaitress("");
waitress.service();
System.out.println(waitress);
//2、佟老师
AbstractWaitressFlyweight waitress1 = ZuDao.getWaitress("");
waitress1.service();
System.out.println(waitress1);
waitress1.end(); //这里释放 修改状态,后面才能继续使用
//3、刘佳林
AbstractWaitressFlyweight waitress2 = ZuDao.getWaitress("");
System.out.println(waitress2);
}
}
3.行为模式
1.模板模式
调用父类的方法
抽象父类
package com.atguigu.design.behavioral.template;
/**
* 1、定义模板
*/
public abstract class CookTemplate {
/**
* 定义算法: 定义好了模板
* 父类可以实现某些步骤
* 留关键给子类
*/
public void cook(){ //核心方法 规定好方法,不能变
//定义算法步骤
heating(); //v
addfood();
addsalt();
stirfry(); //v
end(); //v
}
//加热方法
public void heating(){
System.out.println("开火...");
};
//添加食物
public abstract void addfood();
//加盐 需要调用者自己去实现
public abstract void addsalt();
//翻炒 已经实现
public void stirfry(){
System.out.println("翻炒中...");
};
//出锅
public void end(){
System.out.println("出锅....");
};
}
实现类
public class AutoCookMachine extends CookTemplate{
@Override
public void addfood() {
System.out.println("放了三个小白菜");
}
@Override
public void addsalt() {
System.out.println("放了三勺盐");
}
}
-----------------------------------------------------------------------------------------------测试类
public class MainTest {
public static void main(String[] args) {
AutoCookMachine cookMachine = new AutoCookMachine();
//调用抽象的具体方法调用, 抽象类继承类去实现抽象类 未实现的功能
cookMachine.cook();
}
}
2.策略模式
// 一个策略接口,通过调用接口实现去完成对应的目标
/**
* 游戏策略
*/
public interface GameStrategy {
//战斗策略
void warStrategy();
}
策略的应用/调用
/**
* 环境类
*/
public class TeamGNR {
//抽取游戏策略算法,并进行引用
private GameStrategy gameStrategy;
public void setGameStrategy(GameStrategy gameStrategy) {
this.gameStrategy = gameStrategy;
}
public void startGame(){
System.out.println("游戏开始.....");
//游戏策略
gameStrategy.warStrategy();//调用的是 接口的具体实现类的方法
System.out.println("win......");
}
}
实现类
/**
* 冲锋向前策略
*/
public class UziStrategy implements GameStrategy{
@Override
public void warStrategy() {
System.out.println("uzi.....");
}
}
--------------------------------------------------------------------------------------------
测试类
public class MainTest {
public static void main(String[] args) {
TeamGNR gnr = new TeamGNR();
gnr.setGameStrategy(new RandomStrategy());
gnr.startGame();
}
}
3.状态模式
在接口中调用下一个方法(和策略模式的区别), 可以连续调用
利用next方法,实现 接口实现类的多个方法来回调用
/**
* 抽象状态
*/
public interface TeamState {
//玩游戏
void playGame();
//切换到下一个状态
TeamState next();
}
核心类
/**
* 环境类:
*/
public class SKTTeam {
private TeamState teamState;
public void setTeamState(TeamState teamState) { //传入接口类,实际执行的是实现类
this.teamState = teamState;
}
//开始游戏
public void startGame(){
//状态不同会导致不同的游戏结果
teamState.playGame();
}
//下一个状态
void nextState(){
teamState = teamState.next();
}
}
状态流转类
/**
* 竞赛状态
*/
public class MatchState implements TeamState{
@Override
public void playGame() {
System.out.println("全力以赴打比赛....");
}
//状态模式的核心
@Override
public TeamState next() {
return new VocationState();
}
}
package com.atguigu.design.behavioral.state;
/**
* 休假状态
*/
public class VocationState implements TeamState {
@Override
public void playGame() {
System.out.println("三亚旅游真舒服....饿了...不玩游戏");
//状态流转
}
@Override
public TeamState next() {
return new BeafNodleState();
}
}
package com.atguigu.design.behavioral.state;
/**
* 吃牛肉面状态
*/
public class BeafNodleState implements TeamState {
@Override
public void playGame() {
System.out.println("饱饱的一顿牛肉面......中了诅咒,输了");
}
@Override
public TeamState next() {
return new MatchState();
}
}
测试类
package com.atguigu.design.behavioral.state;
/**
* 状态切换
*/
public class MainTest {
public static void main(String[] args) {
SKTTeam sktTeam = new SKTTeam();
TeamState state = new VocationState();//首先执行的是这个状态
sktTeam.setTeamState(state);
sktTeam.startGame();
sktTeam.nextState();// 调用下一个状态
sktTeam.startGame();
sktTeam.nextState();
sktTeam.startGame();
}
}
4.中介者模式
网状关系变为星状关系, 需要一个公用类 ,各个实现类给公用类赋值
/**
* 抽象机长
*/
public abstract class Captain {
//起飞
abstract void fly();
//降落
abstract void land();
//完成
abstract void success();
}
中介类
/**
* 塔台:中介者
*
* 网状变为星状
*/
public class ControlTower {
private boolean canDo = true;
//接受请求... //抽象类, 需要的是具体的实现的值 传的是当前的类
public void acceptRequest(Captain captain,String action){
if("fly".equals(action)||"land".equals(action)){
//
if(canDo == true){
System.out.println("允许......");
canDo = false;
}else {
System.out.println("不允许.....");
}
}
if("success".equals(action)){
canDo = true;
}
}
}
具体的实现
/**
* 四川8633机长
*/
public class SC8633 extends Captain{
ControlTower controlTower ;
public void setControlTower(ControlTower controlTower) {
this.controlTower = controlTower;
}
@Override
void fly() {
System.out.println("SC8633 请求起飞......");
//问每个机长能否起飞?
controlTower.acceptRequest(this,"fly");
}
@Override
void land() {
System.out.println("SC8633 请求降落......");
//问每个机长能否起飞?
controlTower.acceptRequest(this,";land");
}
@Override
void success() {
System.out.println("SC8633 完成......");
//问每个机长能否起飞?
controlTower.acceptRequest(this,"fly");
}
}
package com.atguigu.design.behavioral.mediator;
import java.util.List;
/**
* 海南8778
*/
public class HU8778 extends Captain{
ControlTower controlTower;
public void setControlTower(ControlTower controlTower) {
this.controlTower = controlTower;
}
@Override
void fly() {
System.out.println("HU8778请求起飞......");
//问每个机长能否起飞?
controlTower.acceptRequest(this,"fly");
}
@Override
void land() {
System.out.println("HU8778请求降落......");
controlTower.acceptRequest(this,"land");
}
@Override
void success() {
System.out.println("完成......");
controlTower.acceptRequest(this,"success");
}
}
5.观察者模式
package com.atguigu.design.behavioral.observer;
import java.util.ArrayList;
import java.util.List;
/**
* 主播
* 双向观察
*/
public class MMTikToker extends AbstractTikToker{
//1、观察者的核心1
List<AbstractFans> fansList = new ArrayList<>();
void startSell() {
System.out.println("雷丰阳... 开始卖货...源码设计课");
notifyFans("我开始卖东西了,是源码设计课,只要666");//调用,通知观察者的方法
}
void endSell() {
System.out.println("雷丰阳... 结束卖货...源码设计课");
notifyFans("课已经卖完了,记得五星好评...");
}
//添加粉丝
@Override
void addFans(AbstractFans fans) {
fansList.add(fans);
}
//通知所有观察者
@Override
void notifyFans(String msg) {
//1、所有粉丝拿来通知
for (AbstractFans fans : fansList) {
fans.acceptMsg(msg);//调用通知粉丝的抽象方法去找对应的实现
}
}
}
package com.atguigu.design.behavioral.observer;
/**
* 抖音主播
*
* 粉丝观察主播....
*/
public abstract class AbstractTikToker {
//添加粉丝
abstract void addFans(AbstractFans fans);
//通知粉丝
abstract void notifyFans(String msg);
}
package com.atguigu.design.behavioral.observer;
import java.util.List;
/**
* 抽象观察者
*/
public abstract class AbstractFans {
List<AbstractTikToker> tikTokers;//双向观察
//通知粉丝
abstract void acceptMsg(String msg);
void follow(AbstractTikToker tikToker){
//主播增粉了
tikToker.addFans(this);
// for (AbstractTikToker toker : tikTokers) {
//
// }
};
}
public class HumanFans extends AbstractFans {
@Override
void acceptMsg(String msg) {
System.out.println("主播说:"+msg);
}
}
public class RobotFans extends AbstractFans {
@Override
void acceptMsg(String msg) {
System.out.println("呸....");
}
}
测试方法
public class MainTest {
public static void main(String[] args) {
MMTikToker lei = new MMTikToker();
lei.startSell();
RobotFans fans1 = new RobotFans();
RobotFans fans2 = new RobotFans();
RobotFans fans3 = new RobotFans();
fans1.follow(lei);
fans2.follow(lei);
fans3.follow(lei);
HumanFans humanFans = new HumanFans();
humanFans.follow(lei);
System.out.println("=====>");
lei.endSell();
}
}
6.备忘录模式
//抽取公用对象属性,然后对象属性值对拷
import lombok.Data;
/**
* 游戏记录。需要保存的内部状态信息,
* 也叫备忘录信息
*/
@Data
public class GameRecord {
Integer id; //代表生成记录的id
Integer coin;//剩余金币
Integer hp;//血量
Integer mp;//蓝量
Integer level;//等级
}
import org.apache.commons.beanutils.BeanUtils;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
/**
* 游戏服务器
* 管理者
*/
public class GameServer {
//管理备忘录信息的
Map<Integer,GameRecord> records = new HashMap<>();
int i = 1;
void add(GameRecord gameRecord){
gameRecord.setId(i++);
records.put(gameRecord.id,gameRecord);
}
LeiGamer getRecord(Integer id) throws Exception {
GameRecord gameRecord = records.get(id);
//获取到备忘录里面的内容以后还要逆转
LeiGamer leiGamer = new LeiGamer();
// leiGamer.setCoin(gameRecord.getCoin());
//BeanUtils:工具类,属性对拷
BeanUtils.copyProperties(leiGamer,gameRecord);
return leiGamer;
}
}
package com.atguigu.design.behavioral.memento;
import lombok.Data;
import org.apache.commons.beanutils.BeanUtils;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.Random;
import java.util.Set;
/**
* 游戏者: 游戏发起人
* 当前游戏信息
*/
@Data
public class LeiGamer {
Integer coin;//剩余金币
Integer hp;//血量
Integer mp;//蓝量
Integer level;//等级
//以上的是内部状态,我们需要记录保存的信息
GameServer gameServer = new GameServer();
//保存游戏记录
void saveGameRecord() throws Exception {
System.out.println("正在保存当前记录....");
GameRecord gameRecord = new GameRecord();
//当前游戏信息保存到备忘录
BeanUtils.copyProperties(gameRecord,this);
//
gameServer.add(gameRecord);
}
//从备忘录获取游戏历史存档
LeiGamer getFromMemento(Integer id) throws Exception {
System.out.println("获取历史存档信息....");
LeiGamer record = gameServer.getRecord(id);
return record;
}
//玩游戏
void playGame(){
int i = new Random().nextInt();
System.out.println("......(〃'▽'〃)......"+i);
coin = i;
hp = i;
mp = i;
level = i;
}
//退出游戏
void exitGame() throws Exception {
System.out.println("退出&存档");
saveGameRecord();
}
}
//测试类
package com.atguigu.design.behavioral.memento;
/**
* 1、备忘录的设计(提取属性)
* 2、备忘录对象和原对象的互转操作(BeanUtils属性对拷)
* 序列化
* 保存数据库
*/
public class MainTest {
public static void main(String[] args) throws Exception {
LeiGamer leiGamer = new LeiGamer();
leiGamer.playGame();
//第一次保存
leiGamer.saveGameRecord();
leiGamer.playGame();
leiGamer.playGame();
leiGamer.saveGameRecord();
LeiGamer fromMemento = leiGamer.getFromMemento(1);
fromMemento.playGame();
}
}
7.解释器模式(很少用/解释器常用)
入口类
//给分析对象一个语言
package com.atguigu.design.behavioral.interpreter;
import java.util.HashSet;
import java.util.Set;
/**
* 环境类:
* 风景区
*/
public class Area {
Set<String> city = new HashSet<>();
Set<String> type = new HashSet<>();
IDCardExpression idCardReader;//读卡器,表达式解析器
//环境类持有表达式
public Area(){
// {"武汉市","上海市"};//免费城市
// {"医生","老人","儿童"};//免费人群
city.add("武汉市");
city.add("上海市");
type.add("医生");
// type.add("老人");
type.add("儿童");
//终结表达式
TerminalExpression city =
new TerminalExpression(this.city, ":");
TerminalExpression type =
new TerminalExpression(this.type, "-");
//以上满足一个即可
idCardReader = new OrExpression(city,type);
}
/**
* 传入表达式,判断当前表达式是否指定为免费人群
* @param expression
*/
void getTicket(String expression){
boolean interpret = idCardReader.interpret(expression);
if(interpret){
System.out.println("恭喜你,免票通过....");
}else {
System.out.println("对不起,请2元购票....");
}
}
}
解析逻辑抽象类
/**
* 身份信息表达式
* 表达式的解析
*
*/
public abstract class IDCardExpression {
/**
* 定义解析逻辑
* 假设我们需要解析的信息格式为:
* 上海市:张文宏-医生
* 武汉市:雷丰阳-程序员
* 北京市:宋宋-老人
* 表达式中,“:”以前的是城市,“-”以后的是职业
* @param expression
* @return
*/
abstract boolean interpret(String expression);
}
解析逻辑具体实现--终结符表达式
package com.atguigu.design.behavioral.interpreter;
import java.util.Set;
/**
* 终结符表达式
*
* 多少种解析规则就需要定义多少种规则类
*
*/
public class TerminalExpression extends IDCardExpression {
IDCardExpression childExp;
Set<String> data; //免费数据
String symbol; //定义解析用的符号如 : -
public TerminalExpression( Set<String> data,String symbol){
this.data = data;
this.symbol = symbol;
}
@Override
boolean interpret(String expression) {
//上海市:张文宏-医生
//1、先按照指定符号分割
String[] split = expression.split(symbol);
// 冒号: 上海市 张文宏-医生
// 短横线 上海市:张文宏 医生
boolean result = false;
for (String s : split) {
if(data.contains(s)){
return true;
};//说明是免费的信息里面的
}
//可以继续子解析
// childExp.interpret(expression);
//不在免费行列
return false;
}
}
解析逻辑具体实现--非终结符表达式
/**
* 非终结表达式 (包含两个终结表达式,只要满足一个终结表达式即可以通过)
*/
public class OrExpression extends IDCardExpression {
//组合两个终结表达式。最终的判断结果是终结表达式判断出来的,这个表达式只是一个桥梁
private IDCardExpression cityExp;
private IDCardExpression typeExp;
public OrExpression(IDCardExpression cityExp, IDCardExpression typeExp) {
this.cityExp = cityExp;
this.typeExp = typeExp;
}
@Override
boolean interpret(String expression) {
//定义所有终结表达式的合并逻辑
return cityExp.interpret(expression) || typeExp.interpret(expression);
}
}
测试类
package com.atguigu.design.behavioral.interpreter;
public class MainTest {
public static void main(String[] args) {
Area area = new Area();
/**
* 上海市:张文宏-医生
* 武汉市:雷丰阳-程序员
* 北京市:宋宋-老人
*/
String sr = "武汉市:雷丰阳-程序员";
area.getTicket(sr);
}
}
8.命令模式
先调用command 实现类的命令, 在调用实现类中调用的方法
/**
* 抽象命令类
* Controller、Service、Dao接口
*
* Service
*/
public interface Command {
/**
* 命令的执行方法
*/
void execute();
}
package com.atguigu.design.behavioral.command;
/**
* 线上课命令
*
* Controller {
* xxService
* aaService
*
*
* //宏命令
* order(){
* //结账
* //扣库存
* //出账单
* ....
* }
*
* }
*/
public class OnlineCommand implements Command{
//Dao
private LeiReceiver receiver = new LeiReceiver();
@Override
public void execute() {
System.out.println("要去上(吹)课(牛)....");
receiver.online();
}
}
package com.atguigu.design.behavioral.command;
/**
* 命令接受者(执行者)。
*/
public class LeiReceiver {
public void online(){
System.out.println("leifengyang 在线上直播大厂课......");
}
public void travel(){
System.out.println("leifengyang 出差.....");
}
}
/**
* 命令接受者(执行者)。
*/
public class LeiReceiver {
public void online(){
System.out.println("leifengyang 在线上直播大厂课......");
}
public void travel(){
System.out.println("leifengyang 出差.....");
}
}
---------------------------------------------------测试类--------------------------------------
public class MainTest {
public static void main(String[] args) {
TeacherTongInvoker invoker = new TeacherTongInvoker();
//先调用command 实现类的命令, 在调用实现类中调用的方法
invoker.setCommand(new OnlineCommand());
invoker.call();
}
}
9.迭代器模式
package com.atguigu.design.behavioral.iterator;
import java.util.ArrayList;
import java.util.List;
/**
* 抽象聚合类
*/
public abstract class BeautifulMan {
//不方便暴露给外界的集合。只允许外界获取而不可以操作
private List<String> girlFriends = new ArrayList<>();
void likeYou(String name){
girlFriends.add(name);
};
void sayBye(String name){
girlFriends.remove(name);
};
/**
* 获取迭代器
* @return
*/
public Itr getIterator(){
return new Iterator();
}
/**
* 具体迭代器
*/
class Iterator implements Itr{
private int cursor = 0; //当前指针
@Override
public boolean hasNext(){
return cursor < girlFriends.size();
}
@Override
public String next(){
//第一次调用返回第一个数据
//下一次再调用自动访问下一个数据
String s = girlFriends.get(cursor);
cursor++;
return s;
}
@Override
public String firstLove() {
return girlFriends.get(0);
}
@Override
public String current() {
return girlFriends.get(girlFriends.size()-1);
}
}
/**
* 抽象迭代器,写在外部该怎么写?
*/
interface Itr {
//有没有下一个
boolean hasNext();
//返回下一个
String next();
//返回初恋(第一个)
String firstLove();
//返回现任(最后一个女朋友)
String current();
}
}
public class MaYuCheng extends BeautifulMan{
}
public class MainTest {
public static void main(String[] args) {
MaYuCheng cheng = new MaYuCheng();
cheng.likeYou("王刚");
cheng.likeYou("李强");
cheng.likeYou("赵根");
BeautifulMan.Itr itr = cheng.getIterator();
String s = itr.firstLove();
System.out.println(s);
String current = itr.current();
System.out.println(current);
System.out.println("=================");
while (itr.hasNext()){
String next = itr.next();
System.out.println(next);
}
}
}
10.访问者模式
11.责任链模式
1.简单责任链模式
public class Teacher {
private String name;
//下一个处理的老师;1、链条的引用点
private Teacher next;
public Teacher(String name) {
this.name = name;
}
public void setNext(Teacher next) {
this.next = next;
}
public Teacher getNext() {
return next;
}
//链条调用方法
void handleRequest() {
System.out.println(this + "正在处理.....");
//2、如果链式调用,最后没有了,不能往下调用,要做判断
if (next != null) {
next.handleRequest();
}
}
;
@Override
public String toString() {
return "Teacher{" +
"name='" + name + '\'' +
'}';
}
}
测试类
/**
* //1、链条的引用点
* //2、下一个继续
* //3、构造链条
*
* 回旋责任链
* Filter:1 -- 2 -- 3 -- 本人 -- 3 -- 2 -- 1
*
*/
public class MainTest {
public static void main(String[] args) {
Teacher leifengyang = new Teacher("Leifengyang");
Teacher xiaokui = new Teacher("xiaokui");
Teacher mengmeng = new Teacher("mengmeng");
leifengyang.setNext(xiaokui);
xiaokui.setNext(mengmeng);
leifengyang.handleRequest();
}
}