状态模式 State
状态模式:当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类 状态模式主要是解决的是控制一个对象状态转换的条件表达式过于复杂时的情况,把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。
UML
Code
package com.fangsheng.designpattern.state;
/**
* @author: fangsheng
* @createTime: 2023/2/20
* @describe: 状态模式
*/
public class StateClient {
public static void main(String[] args) {
System.out.println("**********************************************");
System.out.println();
Context c = new Context(new ConcreteStateA());
c.request();
c.request();
c.request();
c.request();
System.out.println();
System.out.println("**********************************************");
}
}
//抽象状态类
abstract class State {
public abstract void handle(Context context);
}
//具体状态类A
class ConcreteStateA extends State
{
@Override
public void handle(Context context) {
context.setState(new ConcreteStateB());
}
}
//具体状态类B
class ConcreteStateB extends State
{
@Override
public void handle(Context context) {
context.setState(new ConcreteStateA());
}
}
//上下文
class Context {
private State state;
public Context(State state)
{
this.state = state;
}
//可读写的状态属性,用于读取当前状态和设置新状态
public State getState(){
return this.state;
}
public void setState(State value){
this.state = value;
System.out.println("当前状态:" + this.state.getClass().getName());
}
public void request()
{
this.state.handle(this);
}
}
案列1
根据一天不同的时间点(状态),不同时间点下的工作状态(状态影响行为)
UML
code
package com.fangsheng.designpattern.state;
/**
* @author: fangsheng
* @createTime: 2023/2/20
* @describe:
*/
public class WorkStateClient {
public static void main(String[] args) {
System.out.println("**********************************************");
System.out.println();
//紧急项目
Work emergencyProjects = new Work();
emergencyProjects.setHour(9);
emergencyProjects.writeProgram();
emergencyProjects.setHour(10);
emergencyProjects.writeProgram();
emergencyProjects.setHour(12);
emergencyProjects.writeProgram();
emergencyProjects.setHour(13);
emergencyProjects.writeProgram();
emergencyProjects.setHour(14);
emergencyProjects.writeProgram();
emergencyProjects.setHour(17);
emergencyProjects.setWorkFinished(false);
//emergencyProjects.setWorkFinished(true);
emergencyProjects.writeProgram();
emergencyProjects.setHour(19);
emergencyProjects.writeProgram();
emergencyProjects.setHour(22);
emergencyProjects.writeProgram();
System.out.println();
System.out.println("**********************************************");
}
}
//抽象状态类
abstract class State {
public abstract void writeProgram(Work w);
}
//上午工作状态
class ForenoonState extends State {
@Override
public void writeProgram (Work w) {
if (w.getHour() < 12) {
System.out.println("当前时间:"+ w.getHour() +"点 上午工作,精神百倍");
}
else {
w.setState(new NoonState());
w.writeProgram();
}
}
}
//中午工作状态
class NoonState extends State {
@Override
public void writeProgram (Work w) {
if (w.getHour() < 13) {
System.out.println("当前时间:"+ w.getHour() +"点 饿了,午饭;犯困,午休。");
}
else {
w.setState(new AfternoonState());
w.writeProgram();
}
}
}
//下午工作状态
class AfternoonState extends State {
@Override
public void writeProgram (Work w) {
if (w.getHour() < 17) {
System.out.println("当前时间:"+ w.getHour() +"点 下午状态还不错,继续努力");
}
else {
w.setState(new EveningState());
w.writeProgram();
}
}
}
//晚间工作状态
class EveningState extends State {
@Override
public void writeProgram(Work w)
{
if (w.getWorkFinished())
{
w.setState(new RestState());
w.writeProgram();
}
else
{
if (w.getHour() < 21) {
System.out.println("当前时间:"+ w.getHour() +"点 加班哦,疲累之极");
}
else {
w.setState(new SleepingState());
w.writeProgram();
}
}
}
}
//睡眠状态
class SleepingState extends State {
@Override
public void writeProgram(Work w) {
System.out.println("当前时间:"+ w.getHour() +"点 不行了,睡着了。");
}
}
//下班休息状态
class RestState extends State {
@Override
public void writeProgram(Work w) {
System.out.println("当前时间:"+ w.getHour() +"点 下班回家了");
}
}
//工作类
class Work {
private State current;
public Work(){
current = new ForenoonState();
}
//设置状态
public void setState(State value) {
this.current = value;
}
//写代码的状态
public void writeProgram() {
this.current.writeProgram(this);
}
//当前的钟点
private int hour;
public int getHour(){
return this.hour;
}
public void setHour(int value){
this.hour = value;
}
//当前工作是否完成
private boolean workFinished = false;
public boolean getWorkFinished(){
return this.workFinished;
}
public void setWorkFinished(boolean value){
this.workFinished = value;
}
}
适配器模式 Adapter
适配器模式: 将一个类的接口转换成客户端希望的另一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。在系统中数据和行为都是正确的,但是接口不符时,我们应该考虑适配器,目的就是使控制范围之外的一个原有对象与某个接口匹配。适配器模式主要应用于希望复用一些现存的类,但是接口又与复用环境要求不一致的情况。
UML
code
package com.fangsheng.designpattern.adapter;
/**
* @author: fangsheng
* @createTime: 2023/2/20
* @describe: 适配器模式
*/
public class AdapterClient {
public static void main(String[] args) {
System.out.println("**********************************************");
System.out.println();
Target target = new Adapter();
target.request();
System.out.println();
System.out.println("**********************************************");
}
}
//需要适配的类
class Adaptee {
public void specificRequest(){
System.out.println("特殊请求!");
}
}
//客户期待的接口
class Target {
public void request(){
System.out.println("普通请求!");
}
}
//适配器类
class Adapter extends Target {
private Adaptee adaptee = new Adaptee(); //建立一个私有的Adaptee对象
@Override
public void request(){ //这样就可以把表面上调用request()方法
adaptee.specificRequest(); //变成实际调用specificRequest()
}
}
备忘录模式 Memento
备忘录模式: 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样以后就可以将该对象恢复到原先保存的状态。
UML
Originator(发起人): 负责创建一个备忘录Memento,用以记录当前时刻它的内部状态,并可使用备忘录恢复内部状态,Originator可根据需要决定Memento存储Originator的哪些内部状态。
Memento (备忘录): 负责存储Originator对象的内部状态,并可防止Originator以外的其他对象访问备忘录Memento,备忘录有两个接口,Caretaker只能看到备忘录的窄接口,它只能将备忘录传递给其他对象,Originator能够看到一个宽接口,允许它访问返回到先前状态所需要的数据。
Caretaker (管理者): 负责保存好备忘录Memento,不能对备忘录的内容进行操作或者检查。
code
package com.fangsheng.designpattern.memento;
/**
* @author: fangsheng
* @createTime: 2023/2/20
* @describe: 备忘录模式
*/
public class MementoClient {
public static void main(String[] args) {
System.out.println("**********************************************");
System.out.println();
//Originator初始状态,状态属性为"On"
Originator o = new Originator();
o.setState("On");
o.show();
Caretaker c = new Caretaker();
//保存状态时,由于有了很好的封装,可以隐藏Originator的实现细节
c.setMemento(o.createMemento());
//Originator改变了状态属性为"Off"
o.setState("Off");
o.show();
//恢复原初始状态
o.recoveryMemento(c.getMemento());
o.show();
System.out.println();
System.out.println("**********************************************");
}
}
//发起人类
class Originator {
//状态
private String state;
public String getState(){
return this.state;
}
public void setState(String value){
this.state = value;
}
//显示数据
public void show(){
System.out.println("State:"+this.state);
}
//创建备忘录
public Memento createMemento(){
return new Memento(this.state);
}
//恢复备忘录
public void recoveryMemento(Memento memento){
this.setState(memento.getState());
}
}
//备忘录类
class Memento {
private String state;
public Memento (String state){
this.state = state;
}
public String getState(){
return this.state;
}
public void setState(String value){
this.state = value;
}
}
//管理者
class Caretaker{
private Memento memento;
public Memento getMemento(){
return this.memento;
}
public void setMemento(Memento value){
this.memento = value;
}
}
案列1
package code.chapter18.memento2;
public class Test {
public static void main(String[] args){
System.out.println("**********************************************");
System.out.println();
//大战Boss前
GameRole role = new GameRole();
role.getInitState();
role.displayState();
//保存进度
RoleStateCaretaker stateAdmin = new RoleStateCaretaker();
stateAdmin.setRoleStateMemento(role.saveState());
//大战Boss时,损耗严重
role.fight();
//显示状态
role.displayState();
//游戏进度恢复
role.recoveryState(stateAdmin.getRoleStateMemento());
//显示状态
role.displayState();
System.out.println();
System.out.println("**********************************************");
}
}
//游戏角色类
class GameRole {
//生命力
private int vitality;
public int getVitality(){
return this.vitality;
}
public void setVitality(int value){
this.vitality = value;
}
//攻击力
private int attack;
public int getAttack(){
return this.attack;
}
public void setAttack(int value){
this.attack = value;
}
//防御力
private int defense;
public int getDefense(){
return this.defense;
}
public void setDefense(int value){
this.defense = value;
}
//状态显示
public void displayState(){
System.out.println("角色当前状态:");
System.out.println("体力:"+this.vitality);
System.out.println("攻击力:"+this.attack);
System.out.println("防御力:"+this.defense);
System.out.println();
}
//获得初始状态(数据通常来自本机磁盘或远程数据接口)
public void getInitState(){
this.vitality = 100;
this.attack = 100;
this.defense = 100;
}
//战斗(在与Boss大战后游戏数据损耗为0)
public void fight(){
this.vitality = 0;
this.attack = 0;
this.defense = 0;
}
//保存角色状态
public RoleStateMemento saveState(){
return new RoleStateMemento(this.vitality,this.attack,this.defense);
}
//恢复角色状态
public void recoveryState(RoleStateMemento memento){
this.setVitality(memento.getVitality());
this.setAttack(memento.getAttack());
this.setDefense(memento.getDefense());
}
}
//角色状态存储箱
class RoleStateMemento {
private int vitality;
private int attack;
private int defense;
//将生命力、攻击力、防御力存入状态存储箱对象中
public RoleStateMemento (int vitality,int attack,int defense){
this.vitality = vitality;
this.attack = attack;
this.defense = defense;
}
//生命力
public int getVitality(){
return this.vitality;
}
public void setVitality(int value){
this.vitality = value;
}
//攻击力
public int getAttack(){
return this.attack;
}
public void setAttack(int value){
this.attack = value;
}
//防御力
public int getDefense(){
return this.defense;
}
public void setDefense(int value){
this.defense = value;
}
}
//角色状态管理者
class RoleStateCaretaker{
private RoleStateMemento memento;
public RoleStateMemento getRoleStateMemento(){
return this.memento;
}
public void setRoleStateMemento(RoleStateMemento value){
this.memento = value;
}
}
组合模式Composite
组合模式: 将对象组合成树形结构以表示 ‘部分-整体 的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性。’
UML
code
package com.fangsheng.designpattern.composite;
import java.util.ArrayList;
/**
* @author: fangsheng
* @createTime: 2023/2/21
* @describe: 组合模式
*/
public class CompositeClient {
public static void main(String[] args) {
System.out.println("**********************************************");
System.out.println();
Composite root = new Composite("root");
root.add(new Leaf("Leaf A"));
root.add(new Leaf("Leaf B"));
Composite comp = new Composite("Composite X");
comp.add(new Leaf("Leaf XA"));
comp.add(new Leaf("Leaf XB"));
root.add(comp);
Composite comp2 = new Composite("Composite XY");
comp2.add(new Leaf("Leaf XYA"));
comp2.add(new Leaf("Leaf XYB"));
comp.add(comp2);
Leaf leaf = new Leaf("Leaf C");
root.add(leaf);
Leaf leaf2 = new Leaf("Leaf D");
root.add(leaf2);
root.remove(leaf2);
root.display(1);
System.out.println();
System.out.println("**********************************************");
}
}
abstract class Component{
protected String name;
public Component(String name){
this.name = name;
}
public abstract void add(Component component);
public abstract void remove(Component component);
public abstract void display(int depth);
}
class Leaf extends Component{
public Leaf(String name){
super(name);
}
@Override
public void add(Component component){
System.out.println("Cannot add to a leaf.");
}
@Override
public void remove(Component component){
System.out.println("Cannot remove from a leaf.");
}
@Override
public void display(int depth){
//叶节点的具体显示方法,此处是显示其名称和级别
for(var i=0;i<depth;i++){
System.out.print("-");
}
System.out.println(name);
}
}
class Composite extends Component{
private ArrayList<Component> children = new ArrayList<Component>();//一个子对象集合用来存储其下属的枝节点和叶节点
public Composite(String name){
super(name);
}
@Override
public void add(Component component){
children.add(component);
}
@Override
public void remove(Component component){
children.remove(component);
}
@Override
public void display(int depth){
//显示其枝节点名称
for(var i=0;i<depth;i++){
System.out.print("-");
}
System.out.println(name);
//对其下级进行遍历
for(Component item : children){
item.display(depth+2);
}
}
}
**********************************************
-root
---Leaf A
---Leaf B
---Composite X
-----Leaf XA
-----Leaf XB
-----Composite XY
-------Leaf XYA
-------Leaf XYB
---Leaf C
**********************************************
小结: 在需求中是体现部分与整体层次的结构,以及你希望用户可以忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象时,就应该考虑组合模式。
案列1
package com.fangsheng.designpattern.composite;
import java.util.ArrayList;
/**
* @author: fangsheng
* @createTime: 2023/2/21
* @describe:
*/
public class CompanyClient {
public static void main(String[] args) {
System.out.println("**********************************************");
ConcreteCompany root = new ConcreteCompany("北京总公司");
root.add(new HRDepartment("总公司人力资源部"));
root.add(new FinanceDepartment("总公司财务部"));
ConcreteCompany comp = new ConcreteCompany("上海华东分公司");
comp.add(new HRDepartment("华东分公司人力资源部"));
comp.add(new FinanceDepartment("华东分公司财务部"));
root.add(comp);
ConcreteCompany comp2 = new ConcreteCompany("南京办事处");
comp2.add(new HRDepartment("南京办事处人力资源部"));
comp2.add(new FinanceDepartment("南京办事处财务部"));
comp.add(comp2);
ConcreteCompany comp3 = new ConcreteCompany("杭州办事处");
comp3.add(new HRDepartment("杭州办事处人力资源部"));
comp3.add(new FinanceDepartment("杭州办事处财务部"));
comp.add(comp3);
System.out.println("结构图:");
root.display(1);
System.out.println("职责:");
root.lineOfDuty();
System.out.println();
System.out.println("**********************************************");
}
}
//公司抽象类
abstract class Company{
protected String name;
public Company(String name){
this.name = name;
}
public abstract void add(Company company); //增加
public abstract void remove(Company company); //移除
public abstract void display(int depth); //显示
public abstract void lineOfDuty(); //履行职责
}
//具体分公司类,树枝节点
class ConcreteCompany extends Company{
protected ArrayList<Company> children = new ArrayList<Company>();
public ConcreteCompany(String name){
super(name);
}
@Override
public void add(Company company){
children.add(company);
}
@Override
public void remove(Company company){
children.remove(company);
}
@Override
public void display(int depth) {
for(var i=0;i<depth;i++){
System.out.print("-");
}
System.out.println(name);
for(Company item : children){
item.display(depth+2);
}
}
//履行职责
@Override
public void lineOfDuty(){
for(Company item : children){
item.lineOfDuty();
}
}
}
//人力资源部,树叶节点
class HRDepartment extends Company{
public HRDepartment(String name){
super(name);
}
@Override
public void add(Company company){
}
@Override
public void remove(Company company){
}
@Override
public void display(int depth) {
for(var i=0;i<depth;i++){
System.out.print("-");
}
System.out.println(name);
}
//履行职责
@Override
public void lineOfDuty(){
System.out.println(name+" 员工招聘培训管理");
}
}
//财务部,树叶节点
class FinanceDepartment extends Company{
public FinanceDepartment(String name){
super(name);
}
@Override
public void add(Company company){
}
@Override
public void remove(Company company){
}
@Override
public void display(int depth) {
for(var i=0;i<depth;i++){
System.out.print("-");
}
System.out.println(name);
}
//履行职责
@Override
public void lineOfDuty(){
System.out.println(name+" 公司财务收支管理");
}
}
**********************************************
结构图:
-北京总公司
---总公司人力资源部
---总公司财务部
---上海华东分公司
-----华东分公司人力资源部
-----华东分公司财务部
-----南京办事处
-------南京办事处人力资源部
-------南京办事处财务部
-----杭州办事处
-------杭州办事处人力资源部
-------杭州办事处财务部
职责:
总公司人力资源部 员工招聘培训管理
总公司财务部 公司财务收支管理
华东分公司人力资源部 员工招聘培训管理
华东分公司财务部 公司财务收支管理
南京办事处人力资源部 员工招聘培训管理
南京办事处财务部 公司财务收支管理
杭州办事处人力资源部 员工招聘培训管理
杭州办事处财务部 公司财务收支管理
**********************************************
组合模式这样就定义了包含人力资源部和财务部这些基本对象和分公司,办事处等组合对象的类层次结构。基本对象可以被组合成更复杂的组合对象。而这个组合对象又可以被组合,这样不断地递归下去,客户代码中,任何用到基本对象的地方都可以使用组合对象了。
迭代器模式 Iterator
提供一种方法顺序访问一个聚合对象的各个元素,而不应该暴露该对象的内部表示 。当你需要访问一个聚集的对象,而且不管这些对象不管是什么都需要遍历的时候,就应该考虑迭代器模式
UML
code
public class Test {
public static void main(String[] args){
System.out.println("**********************************************");
System.out.println();
ConcreteAggregate bus = new ConcreteAggregate();
bus.add("大鸟");
bus.add("小菜");
bus.add("行李");
bus.add("老外");
bus.add("公交内部员工");
bus.add("小偷");
//正序迭代器
//Iterator conductor = new ConcreteIterator(bus);
//倒序迭代器
Iterator conductor = new ConcreteIteratorDesc(bus);
conductor.first();
while (!conductor.isDone()) {
System.out.println(conductor.currentItem() + ",请买车票!");
conductor.next();
}
System.out.println();
System.out.println("**********************************************");
}
}
//聚集抽象类
abstract class Aggregate{
//创建迭代器
public abstract Iterator createIterator();
}
//具体聚集类,继承Aggregate
class ConcreteAggregate extends Aggregate{
//声明一个ArrayList泛型变量,用于存放聚合对象
private ArrayList<Object> items = new ArrayList<Object>();
public Iterator createIterator(){
return new ConcreteIterator(this);
}
//返回聚集总个数
public int getCount(){
return items.size();
}
//增加新对象
public void add(Object object){
items.add(object);
}
//得到指定索引对象
public Object getCurrentItem(int index){
return items.get(index);
}
}
//迭代器抽象类
abstract class Iterator{
public abstract Object first(); //第一个
public abstract Object next(); //下一个
public abstract boolean isDone(); //是否到最后
public abstract Object currentItem(); //当前对象
}
//具体迭代器类,继承Iterator
class ConcreteIterator extends Iterator{
private ConcreteAggregate aggregate;
private int current = 0;
//初始化时将具体的聚集对象传入
public ConcreteIterator(ConcreteAggregate aggregate){
this.aggregate = aggregate;
}
//得到第一个对象
public Object first(){
return aggregate.getCurrentItem(0);
}
//得到下一个对象
public Object next() {
Object ret = null;
current++;
if (current < aggregate.getCount()) {
ret = aggregate.getCurrentItem(current);
}
return ret;
}
//判断当前是否遍历到结尾,到结尾返回true
public boolean isDone(){
return current >= aggregate.getCount() ? true : false;
}
//返回当前的聚集对象
public Object currentItem(){
return aggregate.getCurrentItem(current);
}
}
//具体迭代器类(倒序),继承Iterator
class ConcreteIteratorDesc extends Iterator{
private ConcreteAggregate aggregate;
private int current = 0;
public ConcreteIteratorDesc(ConcreteAggregate aggregate){
this.aggregate = aggregate;
current = aggregate.getCount()-1;
}
//第一个对象
public Object first(){
return aggregate.getCurrentItem(aggregate.getCount()-1);
}
//下一个对象
public Object next() {
Object ret = null;
current--;
if (current >= 0) {
ret = aggregate.getCurrentItem(current);
}
return ret;
}
//判断当前是否遍历到结尾,到结尾返回true
public boolean isDone(){
return current <0 ? true : false;
}
//返回当前的聚集对象
public Object currentItem(){
return aggregate.getCurrentItem(current);
}
}
单列模式 Singleton
单列模式:保证一个类仅有一个实列,并提供一个访问它的全局访问点。
code
/**
* 1) 单例模式保证了 系统内存中该类只存在一个对象,节省了系
* 统资源,对于一些需
* 要频繁创建销毁的对象,使用单例模式可以提高系统性能
* 2) 当想实例化一个单例类的时候,必须要记住使用相应的获取对象
* 的方法,而不是使
* 用new
* 3) 单例模式使用的场景:需要频繁的进行创建和销毁的对象、
* 创建对象时耗时过多或
* 耗费资源过多(即:重量级对象),但又经常用到的对象、工具类
* 对象、频繁访问数
* 据库或文件的对象(比如数据源、session工厂等)
*/
public class SingleTonPatterns {
public static void main(String[] args) {
// ----------------------饿汉式01 静态成员---------------------------
SingleTon instance1 = SingleTon.getInstance();
SingleTon instance2 = SingleTon.getInstance();
System.out.println(instance1==instance2);
// ----------------------饿汉式02 静态代码快---------------------------
SingleTonStatic singleTonStatic1 = SingleTonStatic.getInstance();
SingleTonStatic singleTonStatic2 = SingleTonStatic.getInstance();
System.out.println(singleTonStatic1==singleTonStatic2);
// ----------------------懒汉试 03 (线程不安全的 )---------------------------
SingleTonLazy singleTonLazy1 = SingleTonLazy.getInstance();
SingleTonLazy singleTonLazy2 = SingleTonLazy.getInstance();
System.out.println(singleTonLazy1==singleTonLazy2);
// ----------------------懒汉试 04 (线程安全但是效率太低 同步代码块)---------------------------
SingleTonLazySync singleTonLazySync1 = SingleTonLazySync.getInstance();
SingleTonLazySync singleTonLazySync2 = SingleTonLazySync.getInstance();
System.out.println(singleTonLazySync1==singleTonLazySync2);
// ----------------------懒汉试 05 (线程不安全安全 同步代码块)---------------------------
SingleTonLazySyncMethod singleTonLazySyncMethod1 = SingleTonLazySyncMethod.getInstance();
SingleTonLazySyncMethod singleTonLazySyncMethod2 = SingleTonLazySyncMethod.getInstance();
System.out.println(singleTonLazySyncMethod1==singleTonLazySyncMethod2);
// ----------------------懒汉试 06 (线程安全 双重检查机制, 推荐使用的方式)---------------------------
SingleTonLazyCheck singleTonLazyCheck1 = SingleTonLazyCheck.getInstance();
SingleTonLazyCheck singleTonLazyCheck2 = SingleTonLazyCheck.getInstance();
System.out.println(singleTonLazyCheck1==singleTonLazyCheck2);
// ----------------------懒汉试 07 (线程安全 静态内部内的方式)---------------------------
SingleTonLazyInnerClass singleTonLazyInnerClass1 = SingleTonLazyInnerClass.getInstance();
SingleTonLazyInnerClass singleTonLazyInnerClass2 = SingleTonLazyInnerClass.getInstance();
System.out.println(singleTonLazyInnerClass1==singleTonLazyInnerClass2);
// ----------------------枚举 08 (线程安全 枚举的方式)---------------------------
SingleTonEnum singleTonEnum01 = SingleTonEnum.INSTANCE;
SingleTonEnum singleTonEnum2 = SingleTonEnum.INSTANCE;;
System.out.println(singleTonLazyInnerClass1==singleTonLazyInnerClass2);
singleTonEnum01.say();
}
}
// 枚举 08 (线程安全 枚举的方式)
enum SingleTonEnum{
INSTANCE;
public void say(){
System.out.println("hello");
}
}
// 懒汉试 07 (线程安全 静态内部内的方式)
class SingleTonLazyInnerClass{
private static volatile SingleTonLazyInnerClass singleTon;
//私有化构造方法
private SingleTonLazyInnerClass(){
}
// 写一个静态内部内
private static class SingTonInstance{
private static final SingleTonLazyInnerClass INSTANCE= new SingleTonLazyInnerClass();
}
//提供一个静态的公有方法,直接返回SingletonInstance.INSTANCE
public static synchronized SingleTonLazyInnerClass getInstance() {
return SingTonInstance.INSTANCE;
}
}
// 懒汉试 06 (线程安全 双重检查机制, 推荐使用的方式)
class SingleTonLazyCheck{
private static volatile SingleTonLazyCheck singleTon;
//私有化构造方法
private SingleTonLazyCheck(){
}
// 提供一个静态的方法供外部调用
public static SingleTonLazyCheck getInstance(){
if (singleTon==null){
synchronized (SingleTonLazyCheck.class){
if (singleTon==null){ //如果第一个线程进来创建对象后 volatile 后刷新主内存的数据
singleTon = new SingleTonLazyCheck();
}
}
}
return singleTon;
}
}
// 懒汉试 05 (线程不安全安全 同步代码块)
class SingleTonLazySyncMethod{
private static SingleTonLazySyncMethod singleTon;
//私有化构造方法
private SingleTonLazySyncMethod(){
}
// 提供一个静态的方法供外部调用
public static SingleTonLazySyncMethod getInstance(){
if (singleTon==null){
synchronized (SingleTonLazySyncMethod.class){
singleTon = new SingleTonLazySyncMethod();
}
}
return singleTon;
}
}
// 懒汉试 04 (线程安全但是效率太低 同步代码块)
class SingleTonLazySync{
private static SingleTonLazySync singleTon;
//私有化构造方法
private SingleTonLazySync(){
}
// 提供一个静态的方法供外部调用
public static synchronized SingleTonLazySync getInstance(){
if (singleTon==null){
singleTon = new SingleTonLazySync();
}
return singleTon;
}
}
// 懒汉试 03 (线程不安全的 )
class SingleTonLazy{
private static SingleTonLazy singleTon;
//私有化构造方法
private SingleTonLazy(){
}
// 提供一个静态的方法供外部调用
public static SingleTonLazy getInstance(){
if (singleTon==null){
singleTon = new SingleTonLazy();
}
return singleTon;
}
}
// 饿汉式 01 静态变量
class SingleTon{
private static final SingleTon singleTon = new SingleTon();
//私有化构造方法
private SingleTon(){
}
// 提供一个静态的方法供外部调用
public static SingleTon getInstance(){
return singleTon;
}
}
// 静态代码快模式 02
class SingleTonStatic{
private static SingleTonStatic singleTon = null;
{
singleTon = new SingleTonStatic();
}
//私有化构造方法
private SingleTonStatic(){
}
// 提供一个静态的方法供外部调用
public static SingleTonStatic getInstance(){
return singleTon;
}
}
桥接模式 Bridge
桥接模式: 将抽象部分与他的实现部分分离,使他们可以独立的变化,这并不是说,让抽象类与其派生类分离,实现指的是抽象类和它的派生类用来实现自己的对象。桥接模式的核心是尽可能用聚合/组合的关系代替继承。
UML
code
package com.fangsheng.designpattern.bridge;
/**
* @author: fangsheng
* @createTime: 2023/2/23
* @describe: 桥接模式
*/
public class BridgeClient {
public static void main(String[] args) {
System.out.println("**********************************************");
System.out.println();
Abstraction ab;
ab = new RefinedAbstraction();
ab.setImplementor(new ConcreteImplementorA());
ab.operation();
ab.setImplementor(new ConcreteImplementorB());
ab.operation();
System.out.println();
System.out.println("**********************************************");
}
}
abstract class Implementor{
public abstract void operation();
}
class ConcreteImplementorA extends Implementor{
@Override
public void operation(){
System.out.println("具体实现A的方法执行");
}
}
class ConcreteImplementorB extends Implementor{
@Override
public void operation(){
System.out.println("具体实现B的方法执行");
}
}
abstract class Abstraction{
protected Implementor implementor;
public void setImplementor(Implementor implementor){
this.implementor = implementor;
}
public abstract void operation();
}
class RefinedAbstraction extends Abstraction{
@Override
public void operation(){
System.out.print("具体的Abstraction");
implementor.operation();
}
}
案列1
public class Test {
public static void main(String[] args) {
System.out.println("**********************************************");
System.out.println();
HandsetBrand ab;
ab = new HandsetBrandM();
ab.setHandsetSoft(new HandsetGame());
ab.run();
ab.setHandsetSoft(new HandsetAddressList());
ab.run();
HandsetBrand ab2;
ab2 = new HandsetBrandN();
ab2.setHandsetSoft(new HandsetGame());
ab2.run();
ab2.setHandsetSoft(new HandsetAddressList());
ab2.run();
//向扩展开放,增加的功能
HandsetBrand ab3;
ab3 = new HandsetBrandS();
ab3.setHandsetSoft(new HandsetMusicPlay());
ab3.run();
System.out.println();
System.out.println("**********************************************");
}
}
//手机软件
abstract class HandsetSoft{
//运行
public abstract void run();
}
//手机游戏
class HandsetGame extends HandsetSoft{
public void run(){
System.out.println("手机游戏");
}
}
//手机通讯录
class HandsetAddressList extends HandsetSoft{
public void run(){
System.out.println("通讯录");
}
}
//手机品牌
abstract class HandsetBrand{
protected HandsetSoft soft;
//设置手机软件
public void setHandsetSoft(HandsetSoft soft){
this.soft=soft;
}
//运行
public abstract void run();
}
//手机品牌M
class HandsetBrandM extends HandsetBrand{
public void run(){
System.out.print("品牌M");
soft.run();
}
}
//手机品牌N
class HandsetBrandN extends HandsetBrand{
public void run(){
System.out.print("品牌N");
soft.run();
}
}
//手机音乐播放
class HandsetMusicPlay extends HandsetSoft{
public void run(){
System.out.print("音乐播放");
}
}
//手机品牌S
class HandsetBrandS extends HandsetBrand{
public void run(){
System.out.print("品牌S");
soft.run();
}
}
命令模式 Command
命令模式:将一个请求封装成一个对象, 从而可以使你使用不同的请求,对客户进行参数化,对请求排队或者记录请求日志,以及支持可撤销的操作。
UML
code
package com.fangsheng.designpattern.command;
/**
* @author: fangsheng
* @createTime: 2023/2/23
* @describe: 命令模式
*/
public class CommandClient {
public static void main(String[] args) {
System.out.println("**********************************************");
System.out.println();
Receiver receiver = new Receiver();
Command command = new ConcreteCommand(receiver);
Invoker invoker = new Invoker();
invoker.setCommand(command);
invoker.executeCommand();
System.out.println();
System.out.println("**********************************************");
}
}
//抽象命令类
abstract class Command {
protected Receiver receiver;
public Command(Receiver receiver){
this.receiver = receiver;
}
//执行命令
public abstract void excuteCommand();
}
//具体命令类
class ConcreteCommand extends Command{
public ConcreteCommand(Receiver receiver){
super(receiver);
}
@Override
public void excuteCommand(){
receiver.action();
}
}
class Invoker{
private Command command;
public void setCommand(Command command){
this.command = command;
}
public void executeCommand(){
command.excuteCommand();
}
}
class Receiver{
public void action(){
System.out.println("执行请求!");
}
}
案列1
public class Test {
public static void main(String[] args) {
System.out.println("**********************************************");
//开店前的准备
Barbecuer boy = new Barbecuer();//烤肉厨师
Command bakeMuttonCommand1 = new BakeMuttonCommand(boy); //烤羊肉串
Command bakeChickenWingCommand1 = new BakeChickenWingCommand(boy); //烤鸡翅
Waiter girl = new Waiter(); //服务员
System.out.println("开门营业,顾客点菜");
girl.setOrder(bakeMuttonCommand1); //下单烤羊肉串
girl.setOrder(bakeMuttonCommand1); //下单烤羊肉串
girl.setOrder(bakeMuttonCommand1); //下单烤羊肉串
girl.setOrder(bakeMuttonCommand1); //下单烤羊肉串
girl.setOrder(bakeMuttonCommand1); //下单烤羊肉串
girl.cancelOrder(bakeMuttonCommand1); //取消一串羊肉串订单
girl.setOrder(bakeChickenWingCommand1); //下单烤鸡翅
System.out.println("点菜完毕,通知厨房烧菜");
girl.notifyCommand(); //通知厨师
System.out.println();
System.out.println("**********************************************");
}
}
//抽象命令类
abstract class Command {
protected Barbecuer receiver;
public Command(Barbecuer receiver){
this.receiver = receiver;
}
//执行命令
public abstract void excuteCommand();
}
//烤羊肉命令类
class BakeMuttonCommand extends Command{
public BakeMuttonCommand(Barbecuer receiver){
super(receiver);
}
public void excuteCommand(){
receiver.bakeMutton();
}
}
//烤鸡翅命令类
class BakeChickenWingCommand extends Command{
public BakeChickenWingCommand(Barbecuer receiver){
super(receiver);
}
public void excuteCommand(){
receiver.bakeChickenWing();
}
}
//服务员类
class Waiter{
private ArrayList<Command> orders = new ArrayList<Command>();
//设置订单
public void setOrder(Command command){
String className=command.getClass().getSimpleName();
if (className.equals("BakeChickenWingCommand")){
System.out.println("服务员:鸡翅没有了,请点别的烧烤。");
}
else{
this.orders.add(command);
System.out.println("增加订单:"+className+" 时间:"+getNowTime());
}
}
//取消订单
public void cancelOrder(Command command){
String className=command.getClass().getSimpleName();
orders.remove(command);
System.out.println("取消订单:"+className+" 时间:"+getNowTime());
}
//通知执行
public void notifyCommand(){
for(Command command : orders)
command.excuteCommand();
}
private String getNowTime(){
SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
return formatter.format(new Date()).toString();
}
}
//烤肉串者
class Barbecuer{
//烤羊肉
public void bakeMutton(){
System.out.println("烤羊肉串!");
}
//烤鸡翅
public void bakeChickenWing(){
System.out.println("烤鸡翅!");
}
}
责任链模式 Chain of Responsibility
责任链模式:使多个对象都有机会来处理请求,从而避免请求的发送者和接受者之间的耦合关系,将这个对象连成一条链,并沿着这条链传递请求,知道请求被一个对象处理为止。
UML
code
package com.fangsheng.designpattern.chain;
/**
* @author: fangsheng
* @createTime: 2023/2/23
* @describe: 责任链模式
*/
public class ChainOfResponsibilityClient {
public static void main(String[] args) {
System.out.println("**********************************************");
System.out.println();
Handler h1 = new ConcreteHandler1();
Handler h2 = new ConcreteHandler2();
Handler h3 = new ConcreteHandler3();
h1.setSuccessor(h2);
h2.setSuccessor(h3);
int[] requests = { 2, 5, 14, 22, 18, 3, 27, 20 };
for(int request : requests) {
h1.handleRequest(request);
}
System.out.println();
System.out.println("**********************************************");
}
}
abstract class Handler{
protected Handler successor;
//设置继任者
public void setSuccessor(Handler successor){
this.successor = successor;
}
public abstract void handleRequest(int request);
}
class ConcreteHandler1 extends Handler{
@Override
public void handleRequest(int request){
if (request >=0 && request < 10){
System.out.println(this.getClass().getSimpleName()+" 处理请求 "+request);
}
else if (successor != null){
successor.handleRequest(request);
}
}
}
class ConcreteHandler2 extends Handler{
@Override
public void handleRequest(int request){
if (request >=10 && request < 20){
System.out.println(this.getClass().getSimpleName()+" 处理请求 "+request);
}
else if (successor != null){
successor.handleRequest(request);
}
}
}
class ConcreteHandler3 extends Handler{
@Override
public void handleRequest(int request){
if (request >=20 && request < 30){
System.out.println(this.getClass().getSimpleName()+" 处理请求 "+request);
}
else if (successor != null){
successor.handleRequest(request);
}
}
}
案列1
public class Test {
public static void main(String[] args) {
System.out.println("**********************************************");
CommonManager manager = new CommonManager("金利");
Director director = new Director("宗剑");
GeneralManager generalManager = new GeneralManager("钟精励");
manager.setSuperior(director);
director.setSuperior(generalManager);
Request request = new Request();
request.setRequestType("请假");
request.setRequestContent("小菜请假");
request.setNumber(1);
manager.requestApplications(request);
Request request2 = new Request();
request2.setRequestType("请假");
request2.setRequestContent("小菜请假");
request2.setNumber(4);
manager.requestApplications(request2);
Request request3 = new Request();
request3.setRequestType("加薪");
request3.setRequestContent("小菜请求加薪");
request3.setNumber(5000);
manager.requestApplications(request3);
Request request4 = new Request();
request4.setRequestType("加薪");
request4.setRequestContent("小菜请求加薪");
request4.setNumber(10000);
manager.requestApplications(request4);
System.out.println();
System.out.println("**********************************************");
}
}
//申请
class Request {
//申请类别
private String requestType;
public String getRequestType(){
return this.requestType;
}
public void setRequestType(String value){
this.requestType = value;
}
//申请内容
private String requestContent;
public String getRequestContent(){
return this.requestContent;
}
public void setRequestContent(String value){
this.requestContent = value;
}
//数量
private int number;
public int getNumber(){
return this.number;
}
public void setNumber(int value){
this.number = value;
}
}
//管理者抽象类
abstract class Manager{
protected String name;
public Manager(String name){
this.name = name;
}
//设置管理者上级
protected Manager superior;
public void setSuperior(Manager superior){
this.superior = superior;
}
//请求申请
public abstract void requestApplications(Request request);
}
//普通经理
class CommonManager extends Manager{
public CommonManager(String name){
super(name);
}
public void requestApplications(Request request){
if (request.getRequestType()=="请假" && request.getNumber()<=2)
System.out.println(this.name+":"+request.getRequestContent()+" 数量:"+request.getNumber()+"天,被批准");
else {
if (this.superior != null)
this.superior.requestApplications(request);
}
}
}
//总监
class Director extends Manager{
public Director(String name){
super(name);
}
public void requestApplications(Request request){
if (request.getRequestType()=="请假" && request.getNumber()<=5)
System.out.println(this.name+":"+request.getRequestContent()+" 数量:"+request.getNumber()+"天,被批准");
else {
if (this.superior != null)
this.superior.requestApplications(request);
}
}
}
//总经理
class GeneralManager extends Manager{
public GeneralManager(String name){
super(name);
}
public void requestApplications(Request request){
if (request.getRequestType()=="请假"){
System.out.println(this.name+":"+request.getRequestContent()+" 数量:"+request.getNumber()+"天,被批准");
}
else if (request.getRequestType()=="加薪" && request.getNumber()<=5000){
System.out.println(this.name+":"+request.getRequestContent()+" 数量:"+request.getNumber()+"元,被批准");
}
else if (request.getRequestType()=="加薪" && request.getNumber()>5000){
System.out.println(this.name+":"+request.getRequestContent()+" 数量:"+request.getNumber()+"元,再说吧");
}
}
}
中介者模式 Mediator
中介这模式:用一个中介者对象来封装一系列的对象交互,中介者使各个对象不需要显式地相互引用,从而使其耦合松散,而且可以独立的改变他们之间的交互。
UML
code
package com.fangsheng.designpattern.mediator;
/**
* @author: fangsheng
* @createTime: 2023/2/23
* @describe: 中介者模式
*/
public class MediatorClient {
public static void main(String[] args) {
System.out.println("**********************************************");
ConcreteMediator m = new ConcreteMediator();
ConcreteColleague1 c1 = new ConcreteColleague1(m);
ConcreteColleague2 c2 = new ConcreteColleague2(m);
m.setColleague1(c1);
m.setColleague2(c2);
c1.send("吃过饭了吗?");
c2.send("没有呢,你打算请客?");
System.out.println();
System.out.println("**********************************************");
}
}
//中介者类
abstract class Mediator{
//定义一个抽象的发送消息方法,得到同事对象和发送信息
public abstract void send(String message,Colleague colleague);
}
abstract class Colleague {
protected Mediator mediator;
//构造方法,得到中介者对象
public Colleague(Mediator mediator){
this.mediator = mediator;
}
}
class ConcreteColleague1 extends Colleague {
public ConcreteColleague1(Mediator mediator) {
super(mediator);
}
public void send(String message) {
this.mediator.send(message, this);
}
public void notify(String message) {
System.out.println("同事1得到信息:" + message);
}
}
class ConcreteColleague2 extends Colleague {
public ConcreteColleague2(Mediator mediator) {
super(mediator);
}
public void send(String message)
{
this.mediator.send(message, this);
}
public void notify(String message){
System.out.println("同事2得到信息:" + message);
}
}
class ConcreteMediator extends Mediator{
private ConcreteColleague1 colleague1;
private ConcreteColleague2 colleague2;
public void setColleague1(ConcreteColleague1 value) {
this.colleague1 = value;
}
public void setColleague2(ConcreteColleague2 value) {
this.colleague2 = value;
}
@Override
public void send(String message, Colleague colleague)
{
if (colleague == colleague1) {
colleague2.notify(message);
}
else {
colleague1.notify(message);
}
}
}
享元模式 Flyweight
享元模式、: 运用共享技术,有效的支持大量细粒度的对象,如果一个应用程序使用了大量的对象,而这些大量的对象造成了很大的储存开销时,就应该考虑使用,还有就是这些大量的对象大部分是不怎么变化的,对象内部有很多相通不变的属性,方法等元素,只有少量的需要经常变的,此时就可以考虑使用共享模式。
UML
code
package com.fangsheng.designpattern.flyweight;
import java.util.Hashtable;
/**
* @author: fangsheng
* @createTime: 2023/2/25
* @describe: 享元模式
*/
public class FlyweightClient {
public static void main(String[] args) {
System.out.println("**********************************************");
int extrinsicstate = 22;
FlyweightFactory f = new FlyweightFactory();
Flyweight fx = f.getFlyweight("X");
fx.operation(--extrinsicstate);
Flyweight fy = f.getFlyweight("Y");
fy.operation(--extrinsicstate);
Flyweight fz = f.getFlyweight("Z");
fz.operation(--extrinsicstate);
Flyweight uf = new UnsharedConcreteFlyweight();
uf.operation(--extrinsicstate);
System.out.println();
System.out.println("**********************************************");
}
}
abstract class Flyweight {
public abstract void operation(int extrinsicstate);
}
//需要共享的具体Flyweight子类
class ConcreteFlyweight extends Flyweight {
@Override
public void operation(int extrinsicstate){
System.out.println("具体Flyweight:"+extrinsicstate);
}
}
//不需要共享的Flyweight子类
class UnsharedConcreteFlyweight extends Flyweight {
@Override
public void operation(int extrinsicstate){
System.out.println("不共享的具体Flyweight:"+extrinsicstate);
}
}
//享元工厂
class FlyweightFactory {
private Hashtable<String,Flyweight> flyweights = new Hashtable<String,Flyweight>();
public FlyweightFactory(){
flyweights.put("X", new ConcreteFlyweight());
flyweights.put("Y", new ConcreteFlyweight());
flyweights.put("Z", new ConcreteFlyweight());
}
public Flyweight getFlyweight(String key) {
return (Flyweight)flyweights.get(key);
}
}
案列 1
public class Test {
public static void main(String[] args) {
System.out.println("**********************************************");
WebSiteFactory f = new WebSiteFactory();
WebSite fx = f.getWebSiteCategory("产品展示");
fx.use(new User("小菜"));
WebSite fy = f.getWebSiteCategory("产品展示");
fy.use(new User("大鸟"));
WebSite fz = f.getWebSiteCategory("产品展示");
fz.use(new User("娇娇"));
WebSite fl = f.getWebSiteCategory("博客");
fl.use(new User("老顽童"));
WebSite fm = f.getWebSiteCategory("博客");
fm.use(new User("桃谷六仙"));
WebSite fn = f.getWebSiteCategory("博客");
fn.use(new User("南海鳄神"));
System.out.println("网站分类总数为:"+f.getWebSiteCount());
System.out.println("**********************************************");
}
}
//用户
class User{
private String name;
public User(String value){
this.name=value;
}
public String getName(){
return this.name;
}
}
//抽象的网站类
abstract class WebSite{
public abstract void use(User user);
}
//具体网站类
class ConcreteWebSite extends WebSite {
private String name = "";
public ConcreteWebSite(String name) {
this.name = name;
}
public void use(User user) {
System.out.println("网站分类:" + name+" 用户:"+user.getName());
}
}
//网站工厂
class WebSiteFactory {
private Hashtable<String,WebSite> flyweights = new Hashtable<String,WebSite>();
//获得网站分类
public WebSite getWebSiteCategory(String key)
{
if (!flyweights.contains(key))
flyweights.put(key, new ConcreteWebSite(key));
return (WebSite)flyweights.get(key);
}
//获得网站分类总数
public int getWebSiteCount()
{
return flyweights.size();
}
}
小结: 案列1中网站是有成千上万个的,但是但部分网站的是大同小异的,网站排版, 包含的元素都是不怎变的,但是浏览的人是不同的,我们就可以把不变的共享出来,变的user我们作为外部的状态传进去,大致就是此类的思想。
解释器模式 Interpreter
解释器模式: 给定一个语言,定义它的一种文法表示,文法就是语义规则,(列如同样是数字 1,在数学中表示一个量,在音乐中表示 哆)并定义一个解释器,这个解释器就是用解释语言中的句子的, 如果一种特定类型的问题发生的频率比较高你,那么就可能值得将该问题的各个实列表述为一个简单语言中的句子,这样就乐意构建一个解释器,该解释器就是是通过解析这些句子来解决我们的问题。列如java中的正则表达式就是一种解释器模式
UML
code
package com.fangsheng.designpattern.interpreter;
import java.util.ArrayList;
/**
* @author: fangsheng
* @createTime: 2023/2/25
* @describe: 解释器模式
*/
public class InterpreterClient {
public static void main(String[] args) {
System.out.println("**********************************************");
Context context = new Context();
ArrayList<AbstractExpression> list = new ArrayList<AbstractExpression>();
list.add(new TerminalExpression());
list.add(new NonterminalExpression());
list.add(new TerminalExpression());
list.add(new TerminalExpression());
for (AbstractExpression exp : list) {
exp.interpret(context);
}
System.out.println();
System.out.println("**********************************************");
}
}
//抽象表达式类
abstract class AbstractExpression {
//解释操作
public abstract void interpret(Context context);
}
//终结符表达式
class TerminalExpression extends AbstractExpression {
@Override
public void interpret(Context context) {
System.out.println("终端解释器");
}
}
//非终结符表达式
class NonterminalExpression extends AbstractExpression {
@Override
public void interpret(Context context) {
System.out.println("非终端解释器");
}
}
class Context {
private String input;
public String getInput(){
return this.input;
}
public void setInput(String value){
this.input = value;
}
private String output;
public String getOutput(){
return this.output;
}
public void setOutput(String value){
this.output = value;
}
}
案列1
public class Test {
public static void main(String[] args) {
System.out.println("**********************************************");
PlayContext context = new PlayContext();
//音乐-上海滩
System.out.println("音乐-上海滩:");
context.setPlayText("T 500 O 2 E 0.5 G 0.5 A 3 E 0.5 G 0.5 D 3 E 0.5 G 0.5 A 0.5 O 3 C 1 O 2 A 0.5 G 1 C 0.5 E 0.5 D 3 ");
Expression expression=null;
while (context.getPlayText().length() > 0) {
String str = context.getPlayText().substring(0, 1);
switch (str) {
case "O":
expression = new Scale();
break;
case "C":
case "D":
case "E":
case "F":
case "G":
case "A":
case "B":
case "P":
expression = new Note();
break;
case "T":
expression = new Speed();
break;
}
expression.interpret(context);
}
System.out.println();
System.out.println();
System.out.println("**********************************************");
}
}
//演奏内容
class PlayContext {
private String playText;
public String getPlayText(){
return this.playText;
}
public void setPlayText(String value){
this.playText = value;
}
}
//抽象表达式类
abstract class Expression {
//解释器
public void interpret(PlayContext context)
{
if (context.getPlayText().length() == 0) {
return;
}
else {
String playKey = context.getPlayText().substring(0, 1);
//System.out.println("playKey:"+playKey);
context.setPlayText(context.getPlayText().substring(2));
double playValue = Double.parseDouble(context.getPlayText().substring(0, context.getPlayText().indexOf(" ")));
context.setPlayText(context.getPlayText().substring(context.getPlayText().indexOf(" ") + 1));
this.excute(playKey, playValue);
}
}
//执行
public abstract void excute(String key, double value);
}
//音符类
class Note extends Expression {
public void excute(String key, double value) {
String note = "";
switch (key) {
case "C":
note = "1";
break;
case "D":
note = "2";
break;
case "E":
note = "3";
break;
case "F":
note = "4";
break;
case "G":
note = "5";
break;
case "A":
note = "6";
break;
case "B":
note = "7";
break;
}
System.out.print(note+" ");
}
}
//音阶类
class Scale extends Expression {
public void excute(String key, double value) {
String scale = "";
switch ((int)value) {
case 1:
scale = "低音";
break;
case 2:
scale = "中音";
break;
case 3:
scale = "高音";
break;
}
System.out.print(scale+" ");
}
}
//音速类
class Speed extends Expression {
public void excute(String key, double value) {
String speed;
if (value < 500)
speed = "快速";
else if (value >= 1000)
speed = "慢速";
else
speed = "中速";
System.out.print(speed+" ");
}
}
访问者模式 Visitor
访问者模式: 表示一个作用于某个对象结构中的各个元素的操作。它使你可以在不改变各个元素的类的前提下定义作用于这些元素的新操作。访问者模式的目的就是要把处理从数据结构分离出来,很多系统可以按照算法和数据结构分开,如果这样的系统唷比较稳定的数据结构,又有易于变化的算法的话,使用访问者模式就是比较合适的,因为访问者模式使得算法操作的增加变得容易。反之,如果系统的数据结构对象易于变化,经常要有新的数据对象增加进来,就不适合使用访问者模式。
UML
code
package com.fangsheng.designpattern.visitor;
import java.util.ArrayList;
/**
* @author: fangsheng
* @createTime: 2023/2/25
* @describe: 访问者模式
*/
public class VisitorClient {
public static void main(String[] args) {
System.out.println("**********************************************");
//类似于具体的一个容器,一种数据结构,里面存放了数据
ObjectStructure o = new ObjectStructure();
//添加进元素 A B
o.attach(new ConcreteElementA());
o.attach(new ConcreteElementB());
//创建具体的访问者,类似于算法
ConcreteVisitor1 v1 = new ConcreteVisitor1();
ConcreteVisitor2 v2 = new ConcreteVisitor2();
//将访问者(算法传进容器,或说数据结构中,然后遍历里面的每一个元素,并调用传入的算法进行计算或处理。)
o.accept(v1);
o.accept(v2);
System.out.println();
System.out.println("**********************************************");
}
}
abstract class Visitor {
public abstract void visitConcreteElementA(ConcreteElementA concreteElementA);
public abstract void visitConcreteElementB(ConcreteElementB concreteElementB);
}
class ConcreteVisitor1 extends Visitor {
@Override
public void visitConcreteElementA(ConcreteElementA concreteElementA) {
System.out.println(concreteElementA.getClass().getSimpleName()+"被"+this.getClass().getSimpleName()+"访问");
}
@Override
public void visitConcreteElementB(ConcreteElementB concreteElementB) {
System.out.println(concreteElementB.getClass().getSimpleName()+"被"+this.getClass().getSimpleName()+"访问");
}
}
class ConcreteVisitor2 extends Visitor {
@Override
public void visitConcreteElementA(ConcreteElementA concreteElementA) {
System.out.println(concreteElementA.getClass().getSimpleName()+"被"+this.getClass().getSimpleName()+"访问");
}
@Override
public void visitConcreteElementB(ConcreteElementB concreteElementB) {
System.out.println(concreteElementB.getClass().getSimpleName()+"被"+this.getClass().getSimpleName()+"访问");
}
}
abstract class Element {
public abstract void accept(Visitor visitor);
}
class ConcreteElementA extends Element {
@Override
public void accept(Visitor visitor) {
visitor.visitConcreteElementA(this);
}
public void operationA(){
}
}
class ConcreteElementB extends Element {
@Override
public void accept(Visitor visitor) {
visitor.visitConcreteElementB(this);
}
public void operationB(){
}
}
class ObjectStructure {
private ArrayList<Element> elements = new ArrayList<Element>();
public void attach(Element element) {
elements.add(element);
}
public void detach(Element element) {
elements.remove(element);
}
public void accept(Visitor visitor) {
for(Element e : elements) {
e.accept(visitor);
}
}
}
案列 1
public class Test {
public static void main(String[] args) {
System.out.println("**********************************************");
System.out.println("《大话设计模式》代码样例");
System.out.println();
ObjectStructure o = new ObjectStructure();
// 理解为容器中添加数据(一种数据结构)
o.attach(new Man());//元素
o.attach(new Woman());//元素
//成功时的反应 (一种具体的算法)
Success v1 = new Success();
o.display(v1); //实现计算
//失败时的反应 (一种具体的算法)
Failing v2 = new Failing();
o.display(v2);
//恋爱时的反应
Amativeness v3 = new Amativeness();
o.display(v3);
//婚姻时的反应 (一种具体的算法)
Marriage v4 = new Marriage();
o.display(v4);
System.out.println();
System.out.println("**********************************************");
}
}
//状态抽象类
abstract class Action{
//得到男人结论或反应
public abstract void getManConclusion(Man concreteElementA);
//得到女人结论或反应
public abstract void getWomanConclusion(Woman concreteElementB);
}
//人类抽象类
abstract class Person {
//接受
public abstract void accept(Action visitor);
}
//成功
class Success extends Action{
public void getManConclusion(Man concreteElementA){
System.out.println(concreteElementA.getClass().getSimpleName()
+" "+this.getClass().getSimpleName()+"时,背后多半有一个伟大的女人。");
}
public void getWomanConclusion(Woman concreteElementB){
System.out.println(concreteElementB.getClass().getSimpleName()
+" "+this.getClass().getSimpleName()+"时,背后大多有一个不成功的男人。");
}
}
//失败
class Failing extends Action{
public void getManConclusion(Man concreteElementA){
System.out.println(concreteElementA.getClass().getSimpleName()
+" "+this.getClass().getSimpleName()+"时,闷头喝酒,谁也不用劝。");
}
public void getWomanConclusion(Woman concreteElementB){
System.out.println(concreteElementB.getClass().getSimpleName()
+" "+this.getClass().getSimpleName()+"时,眼泪汪汪,谁也劝不了。");
}
}
//恋爱
class Amativeness extends Action{
public void getManConclusion(Man concreteElementA){
System.out.println(concreteElementA.getClass().getSimpleName()
+" "+this.getClass().getSimpleName()+"时,凡事不懂也要装懂。");
}
public void getWomanConclusion(Woman concreteElementB){
System.out.println(concreteElementB.getClass().getSimpleName()
+" "+this.getClass().getSimpleName()+"时,遇事懂也装作不懂。");
}
}
//结婚
class Marriage extends Action{
public void getManConclusion(Man concreteElementA){
System.out.println(concreteElementA.getClass().getSimpleName()
+" "+this.getClass().getSimpleName()+"时,感慨道:恋爱游戏终结时,‘有妻徒刑’遥无期。");
}
public void getWomanConclusion(Woman concreteElementB){
System.out.println(concreteElementB.getClass().getSimpleName()
+" "+this.getClass().getSimpleName()+"时,欣慰曰:爱情长跑路漫漫,婚姻保险保平安。");
}
}
//男人类
class Man extends Person {
public void accept(Action visitor) {
visitor.getManConclusion(this);
}
}
//女人类
class Woman extends Person {
public void accept(Action visitor) {
visitor.getWomanConclusion(this);
}
}
//对象结构
class ObjectStructure {
private ArrayList<Person> elements = new ArrayList<Person>();
//增加
public void attach(Person element) {
elements.add(element);
}
//移除
public void detach(Person element) {
elements.remove(element);
}
//查看显示
public void display(Action visitor) {
for(Person e : elements) {
e.accept(visitor);
}
}
}
心得(仁者见仁智者见智):
设计模式目的
:减少重复代码,提高代码的灵活性,可维护性,健壮性,便于扩展。
好的设计模式的共性就是遵守六大设计原则
,六大设计原则就是前人的经验总结,六大设计模式一言以蔽之就是:高内聚,低耦合。
而所有设计模式前提
是 - 我认为是事先对业务要有足够的了解,其次
能够对业务中的对象抽取出来,哪些是变的,动态的,哪些是不变的,静态的, 然后
对各种共性的抽象(抽象类,比如有共性的属性和方法),对各种个性的抽象(接口,有特殊的方法等)。最后
就是将前面各种抽象出的类或者接口,以及具体的实现进行各种联系 (运用继承,实现。组合,聚合 …)起来。
分析(业务) -> 抽象(动静) -> 组合 (龙珠合体)