立志于精炼好理解。一句话怎么绝不多半句。是为了方便自己脑子形成设计模式的思维导图。
如果你不了解每个模式类图结构。就不建议看了。这是有基础的再次理解。
1,简单工厂模式:通过一个类来负责创建其他类的实例,被创建的通常有共同的特点。
先看代码(手机为例):
package com.design.sampleFactory;
/**
* 手机的基本功能
*/
public interface Phone {
/*
打电话
*/
public void tellSomeone();
/*
发短息
*/
public void sendMessage();
}
实现的类(自我命名为缺点类,因为当我每增加一款手机,就需要增加对应的实现类,繁杂):仅实现。
重点是简单工厂类:
方式一:
package com.design.sampleFactory;
/**
* 生成手机实例的工厂
*/
public class SampleFactory {
/*
获取手机实例
*/
public static Phone getOneOfPhone(String className) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
return (Phone) Class.forName(className).newInstance();
}
}
调用方式:
package com.design.sampleFactory;
// 简单工厂模式:通过一个类来负责创建其他类的实例,被创建的通常有共同的特点
// 比如手机系列
public class Main {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
Phone applePhone = null;
Phone oppoPhone = null;
try {
// 要传入相对路径😭。idea中原因不明。eclisp就可以
applePhone = SampleFactory.getOneOfPhone("com.design.sampleFactory.ApplePhone");
applePhone.sendMessage();
oppoPhone = SampleFactory.getOneOfPhone("com.design.sampleFactory.OppoPhone");
oppoPhone.sendMessage();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
}
}
另外还两种方式(不过每次新增一个实例类,都要改工厂是不建议的):不推荐使用,扩展性很差
package com.design.sampleFactory;
/**
* 生成手机实例的工厂
*/
public class SampleFactory {
/*
第二种
*/
public static Phone getOneOfPhone(String className) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
return (Phone) Class.forName(className).newInstance();
}
public static Phone getApplePhone() {
return new ApplePhone();
}
/*
第三者
*/
public static Phone getPhone(String className) {
if (className.equals("ApplePhone")) {
return new ApplePhone();
} else if (className.equals("OppoPhne")) {
return new OppoPhone();
}
return null;
}
}
2,工厂方法模式:为了满足开放封闭原则。本质未变。但需要新增一个oppo手机时,就得增加一个OppoPhone实例类和OppoFactory
工厂实现举例:
package com.design.FactoryMethod;
public class AppleFactory implements PhoneFactory {
@Override
public Phone getPhone() {
return new ApplePhone();
}
}
实现方式:
package com.design.FactoryMethod;
// 工厂方法模式:为了满足开放封闭原则。本质未变。
// 比如手机系列
public class Main {
public static void main(String[] args) {
// 通过苹果工厂来获取:
AppleFactory af = new AppleFactory();
af.getPhone().sendMessage();
// 但是比如我们现在新增一个oppo手机,就得增加一个OppoPhone实例类和OppoFactory
OppoFactory of = new OppoFactory();
of.getPhone().sendMessage();
}
}
3,抽象工厂模式:引入满足产品族概念。找了一张很好懂的图。
来实现上面的结果图:
按步骤即可:
产品接口类
package com.design.FactoryMethod;
public interface Product {
void sendMesage();
}
产品实现类:
工厂类:
package com.design.FactoryMethod;
// 生成多个产品族
public interface AbstractFoctory {
// 获得1产品
public Product getProduct1();
// 获得2产品
public Product getProduct2();
}
工厂类实现:
测试:
package com.design.FactoryMethod;
public class Main {
public static void main(String[] args) {
Product1Factory p1 = new Product1Factory();
p1.getProduct1().sendMesage();
p1.getProduct2().sendMesage();
Product2Factory p2 = new Product2Factory();
p2.getProduct1().sendMesage();
p2.getProduct2().sendMesage();
}
}
4,单例模式(即只生成唯一一个全局实例对象)。
饿汉式:
package com.design.singleton;
/*
饿汉式
*/
public class SQLPrimayId {
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
private SQLPrimayId() {}
// 饿的体现,没有就创建
private static SQLPrimayId sqlPrimayId;
public static SQLPrimayId getSQlInstace() {
if (sqlPrimayId == null) {
sqlPrimayId = new SQLPrimayId();
}
return sqlPrimayId;
}
}
调试:
package com.design.singleton;
public class Main {
public static void main(String[] args) {
SQLPrimayId sql1 = SQLPrimayId.getSQlInstace();
SQLPrimayId sql2 = SQLPrimayId.getSQlInstace();
sql1.setId("123");
sql2.setId("456");
System.out.println(sql1.getId());
System.out.println(sql2.getId());
}
}
懒汉式:
package com.design.singleton;
/*
饿汉式
*/
public class SQLPrimayId {
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
private SQLPrimayId() {}
// 懒的体现,初始创建创建
private static SQLPrimayId sqlPrimayId = new SQLPrimayId();
public static SQLPrimayId getSQlInstace() {
return sqlPrimayId;
}
}
上面的单线程是没问题。饿汉多线程是可以保证的。懒汉式就凉凉了。
解决办法之一,直接锁住整个方法:(但是效率极低)
package com.design.singleton;
/*
饿汉式
*/
public class SQLPrimayId {
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
private SQLPrimayId() {}
private static SQLPrimayId sqlPrimayId;
public static synchronized SQLPrimayId getSQlInstace() {
if (sqlPrimayId == null) {
sqlPrimayId = new SQLPrimayId();
}
return sqlPrimayId;
}
}
因此引出双重检查。
package com.design.singleton;
/*
饿汉式
*/
public class SQLPrimayId {
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
private SQLPrimayId() {}
private static volatile SQLPrimayId sqlPrimayId;
public static SQLPrimayId getSQlInstace() {
if (sqlPrimayId == null) {
synchronized (SQLPrimayId.class) {
if (sqlPrimayId == null) {
sqlPrimayId = new SQLPrimayId();
}
}
}
return sqlPrimayId;
}
}
另外静态内部内也推荐使用:
package com.design.singleton;
/*
静态内部类
*/
public class SQLPrimayId {
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
private SQLPrimayId() {}
private static class SQLInstacne {
private static final SQLPrimayId SQL_PRIMAY_ID = new SQLPrimayId();
}
public static SQLPrimayId getSQlInstace() {
return SQLInstacne.SQL_PRIMAY_ID;
}
}
5,原型模式:复制得到原型对象数据。从而避免大量的get,set语句。
package com.design.singleton;
// 1,实现Cloneable
public class Student implements Cloneable {
private int id;
private String name;
private String className;
private String grade;
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public String getGrade() {
return grade;
}
public void setGrade(String grade) {
this.grade = grade;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
// 2,提供方法,并实现克隆
public Student clone() {
try {
return (Student) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return null;
}
}
测试类:
package com.design.singleton;
public class Main {
public static void main(String[] args) {
Student stu1 = new Student();
stu1.setId(12);
stu1.setName("喵喵");
stu1.setClassName("302");
stu1.setGrade("2年级");
// Student stu2 = new Student();
// stu2.setId(11);
// stu2.setName("酱酱");
// stu1.setClassName("302");
// stu1.setGrade("2年级");
// 我们发现stu2和stu1两者很相似。
Student stu2 = stu1.clone(); // stu2和stu1拥有相同的数据
stu2.setId(11);
stu2.setName("酱酱");
}
}
以上我们发现都是基础类型。属于浅克隆。但是当一个类种还引用了其他的实体类或者其他对象集合,就属于深度克隆。
深度克隆类:
package com.design.singleton;
import java.util.ArrayList;
import java.util.List;
public class Student implements Cloneable {
private int id;
private String name;
private String className;
private String grade;
private List<String> teachers;
public List<String> getTeachers() {
return teachers;
}
public void setTeachers(List<String> teachers) {
this.teachers = teachers;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public String getGrade() {
return grade;
}
public void setGrade(String grade) {
this.grade = grade;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
// 核心处理
public Student clone() {
try {
// 先解决基本类型
Student student = (Student) super.clone();
// 在手动复制引用类型
List<String> teachers = new ArrayList<>();
for (String str : this.getTeachers()) {
teachers.add(str);
}
student.setTeachers(teachers);
return student;
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return null;
}
}
测试类:
package com.design.singleton;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
Student stu1 = new Student();
stu1.setId(12);
stu1.setName("喵喵");
stu1.setClassName("302");
stu1.setGrade("2年级");
List<String> list = new ArrayList<>();
list.add("李凡");
list.add("张武");
stu1.setTeachers(list);
Student stu2 = stu1.clone();
stu2.setId(11);
stu2.setName("酱酱");
list.add("王五");
stu1.setTeachers(list);
}
}
解释下为什么需要下面的这段代码:
// 在手动复制引用类型
List<String> teachers = new ArrayList<>();
for (String str : this.getTeachers()) {
teachers.add(str);
}
student.setTeachers(teachers);
因为,它们上面stu1和stu2他们指向同一个引用,如果改变一个就会同时改变。所以上面的代码就是改变引用。你可以注释掉上面的试试哟!
6,建造者模式:用来隐藏符复合对象的创建。
1,参考如下:
内部内实现建造者模式
2,也可以有一个类,专门去set。然后返回对象。推荐用一,灵活性更高。
7,装饰者模式:对客服端透明的方式来扩展对象的功能(是实现子类的一种替换方式)。比如手机举例:基础手机,通过装饰者类实现功能扩展。
客户需要的手机类:
package com.design.singleton;
public interface Phone {
// 每部手机都有的基础功能
/*
通话功能
*/
public void tell();
/*
展示手机所有功能
*/
public void show();
}
基础手机类:
package com.design.singleton;
public class P5G implements Phone {
@Override
public void tell() {
System.out.println("通话");
}
@Override
public void show() {
this.tell();
this.message();
}
public void message() {
System.out.println("短信");
}
}
抽象装饰类:
package com.design.singleton;
public abstract class Decorator implements Phone {
private Phone phone;
public Decorator(Phone phone) {
this.phone = phone;
}
public Phone getPhone() {
return phone;
}
public void setPhone(Phone phone) {
this.phone = phone;
}
}
手机升级5g类:
package com.design.singleton;
// 无限升级实现phone,继承装饰者实现扩展
public class P5GshoujiDecorator extends Decorator implements Phone {
public P5GshoujiDecorator(Phone phone) {
super(phone);
}
public void show() {
// 以前的功能
this.getPhone().show();
// 新增功能
this.gaoQingshiping();
}
public void gaoQingshiping() {
System.out.println("高清视频");
}
@Override
public void tell() {
}
}
继续升级为无敌手机:
package com.design.singleton;
// 无限升级实现phone,继承装饰者实现扩展
public class P5GshoujiDecorator extends Decorator implements Phone {
public P5GshoujiDecorator(Phone phone) {
super(phone);
}
public void show() {
// 以前的功能
this.getPhone().show();
// 新增功能
this.gaoQingshiping();
}
public void gaoQingshiping() {
System.out.println("高清视频");
}
@Override
public void tell() {
}
}
客户端实现升级:
package com.design.singleton;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
// 5G手机实现 new P5G()为基础手机
P5GshoujiDecorator p5Gshouji = new P5GshoujiDecorator(new P5G());
//p5Gshouji.show();
// 5G手机升级为无敌手机出现
PWudishoujiDecorator wudishouji = new PWudishoujiDecorator(p5Gshouji);
wudishouji.show();
}
}
简单来说,举例手机卡,最基础的手机卡类,我们给他一个装饰类。这样我们可以从基础升级到5G卡,也可以有4G升级到5G卡。内部怎么做的客户端不在乎,它只需要知道这个可以这么升级就可以了。
8,策略模式:对一系列算法接口进行封装,为所有算法顶一个抽象的算法接口。(较为简单)。实际种打折就用策略模式就还不错。符合开闭原则。
策略接口:
package com.design.strategy;
public interface Strategy {
// 加密
public void encrype();
}
MDS加密算法:
package com.design.strategy;
public class MDSStrategy implements Strategy {
@Override
public void encrype() {
System.out.println("MDS加密");
}
}
MD5Jami算法:
package com.design.strategy;
public class MDStrategy implements Strategy {
@Override
public void encrype() {
System.out.println("MD5加密");
}
}
策略封装类:
package com.design.strategy;
public class Context {
private Strategy strategy;
public Context(Strategy strategy) {
this.strategy =strategy;
}
public void encrypt() {
// 实现加密
this.strategy.encrype();
}
}
客户端测试:
package com.design.strategy;
public class Main {
public static void main(String[] args) {
// new MDStrategy() 这决定起作用的那个,也可MD5
Context context = new Context(new MDStrategy());
context.encrypt();
}
}
9,观察者模式(重要):行为模式之一。它的作用是当一个对象的状态发生改变时,能够自动通知其他关联对象,自动刷新对象状态。
被观察者:被观察的对象。当被观察者状态变法,需要通知队列中所有观察者对象,被观察者需要添加,删除,通知一个观察者对象的队列。
观察者:接口或者抽象类。当被观察者状态发生改变时,观察者通过一个callback函数得到通知。
两者都有实现类,去扩展业务实现。
被观察者:
package com.design.observer;
import jdk.nashorn.internal.objects.annotations.Getter;
import java.util.Observable;
// **被观察者继承实现 Observable 里面有各种方法运用值得研究**
public class Student extends Observable {
private String name;
private String chaoXi;
private String daJia;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getChaoXi() {
return chaoXi;
}
public void setChaoXi(String chaoXi) {
this.chaoXi = chaoXi;
//是否状态以改变
this.setChanged();
// 观察有抄袭
this.notifyObservers();
}
public String getDaJia() {
return daJia;
}
public void setDaJia(String daJia) {
this.daJia = daJia;
//是否状态以改变,默认true
this.setChanged();
// 发现有打架
this.notifyObservers();
}
}package com.design.observer;
import jdk.nashorn.internal.objects.annotations.Getter;
import java.util.Observable;
// 被观察者继承实现 Observable 里面有各种方法运用值得研究
public class Student extends Observable {
private String name;
private String chaoXi;
private String daJia;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getChaoXi() {
return chaoXi;
}
public void setChaoXi(String chaoXi) {
this.chaoXi = chaoXi;
//是否状态以改变
this.setChanged();
// 观察有抄袭 可传你的需要业务
this.notifyObservers("有抄袭");
}
public String getDaJia() {
return daJia;
}
public void setDaJia(String daJia) {
this.daJia = daJia;
//是否状态以改变,默认true
this.setChanged();
// 发现有打架
this.notifyObservers("发现有打架");
}
}
观察者:
package com.design.observer;
import java.util.Observable;
import java.util.Observer;
// 观察者需要实现Observer
public class Teacher implements Observer {
@Override
public void update(Observable o, Object arg) {
// Object arg这个传改变,或其他业务相关参数
System.out.println("学生有违纪现象:" +arg);
// 业务代码位置
}
}
测试类:
package com.design.observer;
public class Main {
public static void main(String[] args) {
Student studentA = new Student();
// 给学生注册老师作为观察者
studentA.addObserver(new Teacher());
studentA.setName("王五");
studentA.setChaoXi("有抄袭");
// 删除所有观察者
// studentA.deleteObservers();
}
}
结果:
10,享元模式:通过与其他类似对象共享数据来减小内存占用。
比如;apple的两个p是指向同一个对象。
基本字母类:
package com.design.chararctor;
public class MyChar {
private char myChar;
public MyChar(char myChar) {
this.myChar = myChar;
}
public char getMyChar() {
return myChar;
}
public void setMyChar(char myChar) {
this.myChar = myChar;
}
}
字母工厂(内有池子保存):
package com.design.chararctor;
import java.util.HashMap;
import java.util.Map;
public class MycharFactory {
// 池子:保存已有对象
private Map<Character, MyChar> charPool;
public MycharFactory() {
charPool = new HashMap<>();
}
// 从池子获取
public MyChar getMychar(Character character){
// 从池子获取
MyChar myChar = charPool.get(character);
if (myChar == null) {
// 池子没有创建并添加进池子
myChar = new MyChar(character);
charPool.put(character,myChar);
}
return myChar;
}
}
测试类:
package com.design.chararctor;
import com.design.observer.Student;
import com.design.observer.Teacher;
public class Main {
public static void main(String[] args) {
MycharFactory factory = new MycharFactory();
MyChar myChar1 = factory.getMychar('a');
MyChar myChar2 = factory.getMychar('p');
MyChar myChar3 = factory.getMychar('p');
MyChar myChar4 = factory.getMychar('l');
MyChar myChar5 = factory.getMychar('e');
if (myChar2 == myChar3) {
// 两者公用一个对象
System.out.println(true);
} else {
System.out.println(false);
}
}
}
结果:
11,代理模式。
参考:
以前详细写过动态代理链接
12,外观模式。是一组有类似功能的类群(模块或者子系统)。这个一致的简单界面被称为外观模式。
比如有三个子系统,客户端可以一次调用一个,两个,三个。不可能类访问一样访问一次,两次,三次。
子系统A:
package com.design.facade;
/**
* 子系统A
*/
public class SystemA {
public void doSomething() {
System.out.println("子系统A");
}
}
子系统B:
package com.design.facade;
/**
* 子系统B
*/
public class SystemB {
public void doSomething() {
System.out.println("子系统B");
}
}
子系统C:
package com.design.facade;
/**
* 子系统C
*/
public class SystemC {
public void doSomething() {
System.out.println("子系统C");
}
}
外观模式:
package com.design.facade;
// 外观模式
public class Facade {
private SystemA systemA;
private SystemB systemB;
private SystemC systemC;
public Facade() {
systemA = new SystemA();
systemB = new SystemB();
systemC = new SystemC();
}
public void ABCUse() {
this.systemA.doSomething();
this.systemB.doSomething();
this.systemC.doSomething();
}
public void ABUse() {
this.systemA.doSomething();
this.systemB.doSomething();
}
public void AUse() {
this.systemA.doSomething();
}
}
客户端测试:你想要更多的情况,在Facade添加即可
package com.design.facade;
public class Main {
public static void main(String[] args) {
Facade facade = new Facade();
facade.ABCUse();
// facade.ABUse();
// facade.AUse();
}
}
13,组合模式。通过递归手段来构造树形的对象结构,并可以通过一个对象来访问整个对象树。
类结构图:
简单举例:访问文件夹就是这个逻辑。文件的添加删除等。以下display为operation,其对应很名明显。
文件接口:
package com.design.composite;
import java.util.List;
public interface MyFile {
/*
显示文件名: 正真的业务实现
*/
public void showName();
/*
添加文件 (核心一)
*/
public boolean addFile(MyFile myFile);
/*
删除文件 (核心一)
*/
public boolean deleteFile(MyFile myFile);
/*
获取下一个结点(核心一)
*/
public List<MyFile> getNextChild();
}
单文件类:
package com.design.composite;
import java.util.List;
/**
* 单文件类
*/
public class MyFileIml implements MyFile {
private String file;
public MyFileIml(String file) {
this.file = file;
}
@Override
public void showName() {
System.out.println(file);
}
@Override
public boolean addFile(MyFile myFile) {
return false;
}
@Override
public boolean deleteFile(MyFile myFile) {
return false;
}
@Override
public List<MyFile> getNextChild() {
return null;
}
}
文件夹类:
package com.design.composite;
import com.design.facade.SystemB;
import java.util.ArrayList;
import java.util.List;
/**
* 文件夹类
*/
public class Floder implements MyFile {
private String file;
// 文件夹池
private List<MyFile> filePool;
public Floder(String file) {
this.file = file;
filePool = new ArrayList<MyFile>();
}
@Override
public void showName() {
System.out.println(file);
}
@Override
public boolean addFile(MyFile myFile) {
return filePool.add(myFile);
}
@Override
public boolean deleteFile(MyFile myFile) {
return filePool.remove(myFile);
}
@Override
public List<MyFile> getNextChild() {
return filePool;
}
}
测试类:
package com.design.composite;
import java.util.List;
public class Main {
public static void main(String[] args) {
// C盘创建
Floder rootCpan = new Floder("C:");
// 目录appdata
Floder appData = new Floder("appData");
// 文件zy.txt
MyFileIml zy = new MyFileIml("zy.txt");
// C盘下有appData文件夹和zy.txt文件
rootCpan.addFile(appData);
rootCpan.addFile(zy);
// appData目录下有文件zy.ini和目录qq
Floder qq = new Floder("qq");
MyFileIml zyini = new MyFileIml("zy.ini");
appData.addFile(qq);
appData.addFile(zyini);
// 递归实现访问
display(rootCpan);
}
/**
* 通过一个对象访问对象树(核心二)
* @param rootCpan
*/
public static void display(MyFile rootCpan) {
// 自身显示
rootCpan.showName();
// 获得子树
List<MyFile> child = rootCpan.getNextChild();
for (MyFile file: child) {
// 是文件MyFileIml
if (file instanceof MyFileIml) {
file.showName();
} else {
// 是目录
display(file);
}
}
}
}
结果:
14,桥接模式。类的最小设计原则,把抽象和实现分离开,保证各部分的独立性。
比如,不同的车,有不同的引擎。将车和引擎分开,通过桥接实现增加车的种类。
引擎接口:
package com.design.bridage;
public interface Engine {
public void installEngine();
}
引擎2000实现:
package com.design.bridage;
public class Engine2000 implements Engine {
@Override
public void installEngine() {
System.out.println("安装2000引擎");
// 这里应该是具体业务代码位置
}
}
引擎2200实现:
package com.design.bridage;
public class Engine2200 implements Engine {
@Override
public void installEngine() {
System.out.println("安装2200引擎");
// 这里应该是具体业务代码位置
}
}
引擎和车的桥接类:
package com.design.bridage;
/**
* 桥接类
*/
public abstract class BridageCar{
private Engine engine;
public BridageCar(Engine engine) {
this.engine = engine;
}
public abstract void installEngine();
public Engine getEngine() {
return engine;
}
public void setEngine(Engine engine) {
this.engine = engine;
}
}
通过桥接实现小轿车:
package com.design.bridage;
/**
* 通过桥接实现小轿车
*/
public class SmallCar extends BridageCar{
public SmallCar(Engine engine) {
super(engine);
}
@Override
public void installEngine() {
// 车的业务代码
System.out.print("小轿车:");
this.getEngine().installEngine();
}
}
客服端测试类:
package com.design.bridage;
public class Main {
public static void main(String[] args) {
// 生产引擎为2000小轿车
SmallCar smallCar = new SmallCar(new Engine2000());
smallCar.installEngine();
}
}
接下来,比如我要生产2200引擎的大卡车。通过车和引擎的桥接类实现大卡车即可。你也可以继续增加车的类型。我们发现她很好的满足了最小开放和封闭原则。
// 比如已经有了bigCar
BigCar bigCar = new BigCar(new Engine2200());
bigCar .installEngine();
15,适配器模式(adapter)。通过适配器模式可以改变已有的类的接口形式。现实举例,手机需要5V电压,家里220V电压。中间充电器作为适配器,降压给手机。
代码中往往由于某些接口或功能不成熟,要做升级。但是不能每次大规模的去改动,大面积的修改。为了降低修改面。我们采用了适配器模式。改动后,你最多需要修改几个适配器类就可以了。
电压类:
package com.design.adapter;
/**
* 电流类
*/
public class Current {
// 国家供应电压
public void privide220(){
System.out.println("使用220V电压");
}
}
适配器类:
package com.design.adapter;
// 引用方式实现适配器
public class Adapter {
private Current current;
public Adapter(Current current) {
this.current = current;
}
// 适配改为5V电压
public void use5V() {
this.current.privide220();
System.out.println("使用适配器变为5V");
}
}
测试类:
package com.design.adapter;
public class Main {
public static void main(String[] args) {
Adapter adapter = new Adapter(new Current());
adapter.use5V();
}
}
16,解释器模式:特殊的设计模式(不常用,不多说)。interpreter模式是一种简单的解释器结构。用于特定语言的解释。
17,中介者模式。类之间的交互行为统一放到mediator中。对象通过mediator进行交互。
举例:媒人说亲。
抽象人对象(有媒人):
package com.design.mediator;
public abstract class Person {
private String name;
private String condition;
private Mediator mediator;
public abstract void getPartner(Person person);
public Person(String name, String condition, Mediator mediator) {
this.name = name;
this.condition = condition;
this.mediator = mediator;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCondition() {
return condition;
}
public void setCondition(String condition) {
this.condition = condition;
}
public Mediator getMediator() {
return mediator;
}
public void setMediator(Mediator mediator) {
this.mediator = mediator;
}
}
男人通过Mediator媒人注册
package com.design.mediator;
/**
* 男人
*/
public class Man extends Person {
public Man(String name, String condition, Mediator mediator) {
super(name, condition, mediator);
}
// 男人注册、找媒人搭线
public void getPartner(Person person) {
this.getMediator().setMan(this);
this.getMediator().getMeeting(person);
}
}
女人注册
package com.design.mediator;
/**
* 女人
*/
public class Woman extends Person {
public Woman(String name, String condition, Mediator mediator) {
super(name, condition, mediator);
}
// 女人注册、找媒人搭线
public void getPartner(Person person) {
this.getMediator().setWoman(this);
this.getMediator().getMeeting(person);
}
}
中介者媒人:
package com.design.mediator;
public class Mediator {
private Man man;
private Woman woman;
public void setMan(Man man) {
this.man = man;
}
public void setWoman(Woman woman) {
this.woman = woman;
}
// 媒人介绍男女相认
public void getMeeting(Person person) {
if (person instanceof Man) {
this.setMan((Man) person);
} else {
this.setWoman((Woman) person);
}
// 判断条件
if (man != null && woman != null) {
if (man.getCondition() == woman.getCondition()) {
System.out.println("合适");
} else {
System.out.println("不合适");
}
}
}
}
测试类:
package com.design.mediator;
public class Main {
public static void main(String[] args) {
// 中介媒人
Mediator mediator = new Mediator();
// 男人
Person zhangsan = new Man("张三","有钱",mediator);
// 女人
Person lixue = new Woman("李雪","有钱", mediator);
// 通过媒人找到对方。
zhangsan.getPartner(lixue);
}
}
结果:
18,职责链模式:该模式构造一系列分担不同职责的类对象来共同完成一个任务。这些类就像工作流程链条一样紧密。
例子:电脑组装,工厂A生成芯片交给工厂B,B利用芯片生产主机交给工厂C,C利用主机和显示屏组成电脑。
电脑组装抽象类:
package com.design.cor;
public abstract class Computer {
protected Computer computer;
/**
设置下一步
*/
public void setNextStep(Computer computer){
this.computer =computer;
}
/**
* 组装
*/
public abstract void buildComputer();
}
工厂A:
package com.design.cor;
public class FactoryA extends Computer {
@Override
public void buildComputer() {
System.out.println("生成芯片交给FactoryB");
if (this.computer != null) {
this.computer.buildComputer();
}
}
}
工厂B:
package com.design.cor;
public class FactoryB extends Computer {
@Override
public void buildComputer() {
System.out.println("生成芯片交给FactoryC");
if (this.computer != null) {
this.computer.buildComputer();
}
}
}
工厂C:
package com.design.cor;
public class FactoryC extends Computer {
@Override
public void buildComputer() {
System.out.println("生成完成");
if (this.computer != null) {
this.computer.buildComputer();
}
}
}
测试类:
package com.design.cor;
public class Main {
public static void main(String[] args) {
// 工厂
Computer A = new FactoryA();
Computer B = new FactoryB();
Computer C = new FactoryC();
// 设置生成顺序(这个顺序可变)
A.setNextStep(B);
B.setNextStep(C);
// 开始组装
A.buildComputer();
}
}
结果:
我们稍加修改。设置下一步的同时返回下一步:
package com.design.cor;
public abstract class Computer {
protected Computer computer;
/**
设置下一步
*/
public Computer setNextStep(Computer computer){
this.computer =computer;
// 给他返回Computer
return this.computer;
}
/**
* 组装
*/
public abstract void buildComputer();
}
package com.design.cor;
public class Main {
public static void main(String[] args) {
// 工厂
Computer A = new FactoryA();
Computer B = new FactoryB();
Computer C = new FactoryC();
// 设置生成顺序(这个顺序可变)
A.setNextStep(B).setNextStep(C);
A.buildComputer();
}
}
19,迭代模式:把对容器中包含的内部对象的访问委让给外部类,使用Iterator遍历,按顺序进行遍历访问。常见使用Iterator遍历。
两种方式,一种模仿Iterator逻辑实现。二是实现Iterator。
内部对象类(女人):
package com.design.iterator;
public class Woman {
private String name;
private String type;
public Woman(String name, String type) {
this.name = name;
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
把对容器中包含的内部对象的访问委让给外部类:
package com.design.iterator;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* 容器类,并提供一个供外部迭代的类
*/
public class MeinvList {
private List<Woman> meinvList;
private int index;
public MeinvList() {
this.meinvList = new ArrayList<>();
}
public void addWomen(Woman woman){
this.meinvList.add(woman);
}
// 向外部提供
public Itra Iterator() {
return new Itra();
}
// 通过实现Iterator实现
public class Itra implements Iterator {
@Override
public boolean hasNext() {
if (meinvList.size() <= index) {
return false;
}
return true;
}
@Override
public Object next() {
return meinvList.get(index++);
}
@Override
public void remove() {
}
}
}
上面这个类也可以自己模仿Iterator写,但不推荐。
测试类:
package com.design.iterator;
import java.util.Iterator;
public class Main {
public static void main(String[] args) {
MeinvList meinvList = new MeinvList();
Woman liuyifei = new Woman("刘亦菲","古风");
Woman tanyan = new Woman("唐嫣","气质型");
meinvList.addWomen(liuyifei);
meinvList.addWomen(tanyan);
Iterator it = meinvList.Iterator();
while (it.hasNext()) {
Woman woman = (Woman) it.next();
System.out.println("名字:" + woman.getName() + ",类型:"+woman.getType());
}
}
}
测试结果:
20,模板方法模式:用于存在多个具有同样的操作步骤的应用场景,但是某些具体的操作细节却各不相同。
通过继承实现:
抽象类:抽象方法用具体方法调用
package com.design.TemplateMethod;
public abstract class Computer {
//电脑组装抽象方法
public abstract void buildMain();
public abstract void buildScreen();
// 组装具体方法调用抽象方法
public void buildComputer() {
this.buildMain();
this.buildScreen();
}
}
通过继承实现抽象方法的具体业务:
生产苹果电脑:
package com.design.TemplateMethod;
public class AppleComputer extends Computer{
// 抽象具体业务实现
@Override
public void buildMain() {
System.out.println("苹果主机");
}
@Override
public void buildScreen() {
System.out.println("苹果显示屏");
}
}
生产thinkpad电脑:
package com.design.TemplateMethod;
public class ThinkpadComputer extends Computer{
// 抽象具体业务实现
@Override
public void buildMain() {
System.out.println("联想主机");
}
@Override
public void buildScreen() {
System.out.println("联想显示屏");
}
}
测试类:
package com.design.TemplateMethod;
public class Main {
public static void main(String[] args) {
Computer apple = new AppleComputer();
Computer thingkpad = new ThinkpadComputer();
apple.buildComputer();
thingkpad.buildComputer();
}
}
测试结果:
21,备忘录模式:(Menento)作用是保存对象的内部状态,需要时undo/rollback恢复对象以前的状态。
显示种很多场景,比如按ctrl+z可以回退、浏览器的回退等。其实可以想象,就是存储操作,一定条件下调用存储恢复。
多类(实际记得拆分出来):
package com.design;
public class MementoModel {
public static void main(String[] args)
{
Originator or=new Originator();
Caretaker cr=new Caretaker();
or.setState("S0");
System.out.println("初始状态:"+or.getState());
cr.setMemento(or.createMemento()); //保存状态
or.setState("S1");
System.out.println("新的状态:"+or.getState());
or.restoreMemento(cr.getMemento()); //恢复状态
System.out.println("恢复状态:"+or.getState());
}
}
//备忘录
class Memento
{
private String state;
public Memento(String state)
{
this.state=state;
}
public void setState(String state)
{
this.state=state;
}
public String getState()
{
return state;
}
}
//发起人
class Originator
{
private String state;
public void setState(String state)
{
this.state=state;
}
public String getState()
{
return state;
}
public Memento createMemento()
{
return new Memento(state);
}
public void restoreMemento(Memento m)
{
this.setState(m.getState());
}
}
//管理者
class Caretaker
{
private Memento memento;
public void setMemento(Memento m)
{
memento=m;
}
public Memento getMemento()
{
return memento;
}
}
结果:
22,状态模式:主要解决的是当控制一个对象状态转换的条件过于复杂。把判断转移到表示不同状态的类中。从而简化判断逻辑。
多类(实际记得拆分出来):
package com.design;
public class StatePatternClient {
public static void main(String[] args)
{
Context context=new Context(); //创建环境
context.handle(); //处理请求
context.handle();
}
}
// 环境类(通过环境设置状态)
class Context
{
private State state;
//定义环境类的初始状态
public Context()
{
this.state=new ConcreteStateA();
}
//设置新状态
public void setState(State state)
{
this.state=state;
}
//读取状态
public State getState()
{
return(state);
}
//对请求做处理
public void handle()
{
state.Handle(this);
}
}
//抽象状态类
abstract class State
{
public abstract void Handle(Context context);
}
//具体状态A类
class ConcreteStateA extends State
{
public void Handle(Context context)
{
System.out.println("当前状态是 A.");
// 状态A执行完,设置为B
context.setState(new ConcreteStateB());
}
}
//具体状态B类
class ConcreteStateB extends State
{
public void Handle(Context context)
{
System.out.println("当前状态是 B.");
// 状态B实现完,将状态设置为B
context.setState(new ConcreteStateA());
}
}
23,命令模式:将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。这样两者之间通过命令对象进行沟通,这样方便将命令对象进行储存、传递、调用、增加与管理。
举例:客人点餐。
package com.design;
/**
* 比如点餐
*/
public class CommandPattern {
public static void main(String[] args) {
Command cmd = new ConcreteCommand();
Invoker ir = new Invoker(cmd);
System.out.println("客人喊服务员");
// 客人喊服务员
ir.call();
}
}
//调用者(客人找服务员,同时服务员要执行下单并执行给厨师)
class Invoker {
private Command command;
public Invoker(Command command) {
// 客人和服务员的关系
this.command = command;
}
// public void setCommand(Command command)
// {
// this.command=command;
// }
// 客人找服务员
public void call() {
System.out.println("我点芹菜香干肉丝 +辣");
// 同时服务员要执行下单并执行给厨师
command.execute();
}
}
//抽象命令
interface Command {
public abstract void execute();
}
//具体命令(服务员)
class ConcreteCommand implements Command {
private Receiver receiver;
ConcreteCommand() {
// 服务员和厨师的关系
receiver = new Receiver();
}
public void execute() {
// 服务员通知厨师
receiver.action();
}
}
//接收者(厨师)
class Receiver {
public void action() {
System.out.println("我要做做芹菜香干肉丝 + 辣");
}
}
24,访问者模式(很难):集合对象中存在多种不同的元素,且每种元素也存在多种不同的访问者和处理方式。
例如,公园中存在多个景点,也存在多个游客,不同的游客对同一个景点的评价可能不同;
不想理解这个😭:
package com.design;
import java.util.*;
public class VisitorPattern {
public static void main(String[] args) {
ObjectStructure os = new ObjectStructure();
os.add(new ConcreteElementA());
os.add(new ConcreteElementB());
Visitor visitor = new ConcreteVisitorA();
os.accept(visitor);
System.out.println("------------------------");
visitor = new ConcreteVisitorB();
os.accept(visitor);
}
}
//抽象访问者
interface Visitor {
void visit(ConcreteElementA element);
void visit(ConcreteElementB element);
}
//具体访问者A类
class ConcreteVisitorA implements Visitor {
public void visit(ConcreteElementA element) {
System.out.println("具体访问者A访问-->" + element.operationA());
}
public void visit(ConcreteElementB element) {
System.out.println("具体访问者A访问-->" + element.operationB());
}
}
//具体访问者B类
class ConcreteVisitorB implements Visitor {
public void visit(ConcreteElementA element) {
System.out.println("具体访问者B访问-->" + element.operationA());
}
public void visit(ConcreteElementB element) {
System.out.println("具体访问者B访问-->" + element.operationB());
}
}
//抽象元素类
interface Element {
void accept(Visitor visitor);
}
//具体元素A类
class ConcreteElementA implements Element {
public void accept(Visitor visitor) {
visitor.visit(this);
}
public String operationA() {
return "具体元素A的操作。";
}
}
//具体元素B类
class ConcreteElementB implements Element {
public void accept(Visitor visitor) {
visitor.visit(this);
}
public String operationB() {
return "具体元素B的操作。";
}
}
//对象结构角色
class ObjectStructure {
private List<Element> list = new ArrayList<Element>();
public void accept(Visitor visitor) {
Iterator<Element> i = list.iterator();
while (i.hasNext()) {
((Element) i.next()).accept(visitor);
}
}
public void add(Element element) {
list.add(element);
}
public void remove(Element element) {
list.remove(element);
}
}