SEO技术

SEO技术

Products

当前位置:首页 > SEO技术 >

如何构建一个多功能的小游戏网站模板,以支持水泵站群建设?

96SEO 2026-02-19 15:47 0


基本介绍

Pattern)在一个抽象类公开定义了执行它的方法的模板。

如何构建一个多功能的小游戏网站模板,以支持水泵站群建设?

它的子类可以按需要重写方法实现但调用将以抽象类中定义的方式进行。

简单说模板方法模式定义一个操作中的算法的骨架而将一些步骤延迟到子类中使得子类可以不改变一个算法的结构就可以重定义该算法的某些特定步骤这种类型的设计模式属于行为型模式。

AbstractClass

类中实现了模板方法(template)定义了算法的骨架具体子类需要去实现

实现抽象方法

选材---添加配料---浸泡---放到豆浆机打碎通过添加不同的配料可以制作出不同口味的豆浆选材、浸泡和放到豆浆机打碎这几个步骤对于制作每种口味的豆浆都是一样的请使用

模板方法模式完成

选材---添加配料---浸泡---放到豆浆机打碎通过添加不同的配料可以制作出不同口味的豆浆

选材、浸泡和放到豆浆机打碎这几个步骤对于制作每种口味的豆浆都是一样的(红豆、花生豆浆。

)思路分析和图解(类图)

public

make(){select();addCondiments();soak();beat();}//选材void

select(){System.out.println(第一步选择好的新鲜黄豆);}//添加不同配料子类具体实现abstract

void

soak(){System.out.println(第三步黄豆和配料开始浸泡需要3个小时);}//打豆浆void

beat(){System.out.println(第四步黄豆和配料放到豆浆机去打碎);}}

红豆豆浆和花生豆浆某些具体细节不同

{System.out.println(第二步加入上等红豆);}

}public

{System.out.println(第二步加入上好的花生);}

客户端调用

{System.out.println(--------制作红豆豆浆--------);SoyaMilk

soyaMilk

RedBeanSoyaMilk();soyaMilk.make();System.out.println(--------制作红豆豆浆--------);SoyaMilk

peanutSoyaMilk

PeanutSoyaMilk();peanutSoyaMilk.make();}

在模板方法模式的父类中我们可以定义一个方法它默认不做任何事子类可以视情况要不要覆盖它该方法称为“钩子”。

还是用上面做豆浆的例子来讲解比如我们还希望制作纯豆浆不添加任何的配料请使用钩子方法对前面的模板方法进行改造

改造抽象类

{addCondiments();}soak();beat();}...//钩子方法决定是否需要添加配料boolean

{return

main(...){System.out.println(--------制作纯豆浆--------);SoyaMilk

pureSoyaMilk

PureSoyaMilk();pureSoyaMilk.make();//输出--------制作纯豆浆--------第一步选择好的新鲜黄豆第三步黄豆和配料开始浸泡需要3个小时第四步黄豆和配料放到豆浆机去打碎

public

绘制view内容dispatchDraw(canvas);//步骤4.

绘制子View//

{mOverlay.getOverlayView().dispatchDraw(canvas);}onDrawForeground(canvas);

//步骤6.

View的draw()方法中定义了一整套的绘制流程这个流程是固定的所有的Android中的View都是按照这个流程来绘制的。

其中drawBackground()这个方法在View类中是实现了具体过程的而onDraw()方法和dispatchDraw()方法在View中都是空实现即都是钩子方法。

不同的子类通过重写这些空实现来实现自身不同的绘制效果。

具体的View像TextView这些单一的View就会重写onDraw()方法由于TextView没有子View所以dispatchDraw()还是空实现而ViewGroup类含有子View需要遍历子View并绘制因此需要重写onDraw()和dispatchDraw()。

所以我们自定义View时必须且只需重写onDraw自定义ViewGroup时则需要重写onDraw()和dispatchDraw()。

模板方法模式在

基本思想是算法只存在于一个地方也就是在父类中容易修改。

需要修改算法时只要修改父类的模板方法或者已经实现的某些步骤子类就会继承这些修改实现了最大化代码复用。

父类的模板方法和已实现的某些步骤会被子类继承而直接使用。

既统一了算法也提供了很大的灵活性。

父类的模板方法确保了算法的结构保持不变同时由子类提供部分步骤的实现。

该模式的不足之处每一个不同的实现都需要一个子类实现导致类的个数增加使得系统更加庞大一般模板方法都加上

final

防止子类重写模板方法.模板方法模式使用场景当要完成在某个过程该过程要执行一系列步骤

这一系列的步骤基本相同但其个别步骤在实现时可能不同通常考虑用模板方法模式来处理

二、命令模式

Pattern在软件设计中我们经常需要向某些对象发送请求但是并不知道请求的接收者是谁也不知道被请求的操作是哪个

我们只需在程序运行时指定具体的请求接收者即可此时可以使用命令模式来进行设计命名模式使得请求发送者与请求接收者消除彼此之间的耦合让对象之间的调用关系更加灵活实现解耦。

在命令模式中会将一个请求封装为一个对象以便使用不同参数来表示不同的请求(即命名)同时命令模式也支持可撤销的操作。

通俗易懂的理解将军发布命令士兵去执行。

其中有几个角色将军命令发布者、士兵命令的具体执行者、命令(连接将军和士兵)。

Invoker

是命令角色需要执行的所有命令都在这里可以是接口或抽象类Receiver:

接收者角色知道如何实施和执行一个请求相关的操作ConcreteCommand:

execute

我们买了一套智能家电有照明灯、风扇、冰箱、洗衣机我们只要在手机上安装

app

就可以控制对这些家电工作。

这些智能家电来自不同的厂家我们不想针对每一种家电都安装一个

App分别控制我们希望只要一个

控制所有智能家电的需要则每个智能家电厂家都要提供一个统一的接口给

app

就可以考虑使用命令模式。

命令模式可将“动作的请求者”从“动作的执行者”对象中解耦出来.在我们的例子中动作的请求者是手机

代码实现

{receiver.off();}Overridepublic

void

on(){System.out.println(开灯请睁眼);}public

void

off(){System.out.println(关灯请闭眼);}

遥控器调用者角色

no){onCommands[no].execute();undoCommand

void

no){offCommands[no].execute();undoCommand

void

undoButtonClicked(){undoCommand.undo();}}

电视机对象

调用接收者的方法tv.off();}Overridepublic

void

调用接收者的方法tv.on();}Overridepublic

void

LightReceiver();//创建电灯的开关命令ICommand

onCommand

LightOnCommand(receiver);ICommand

offCommand

LightOffCommand(receiver);//创建遥控器RemoteController

controller

RemoteController();//给遥控器设置相关命令controller.setCommand(0,onCommand,offCommand);System.out.println(----按下开灯按钮----);controller.onButtonClicked(0);System.out.println(----按下关灯按钮----);controller.offButtonClicked(0);System.out.println(----按下撤销按钮----);controller.undoButtonClicked();System.out.println(----------开始操作电视机----------);TVReceiver

tvReceiver

TVOnCommand(tvReceiver);ICommand

tvOffCommand

TVOffCommand(tvReceiver);controller.setCommand(1,tvOnCommand,tvOffCommand);controller.onButtonClicked(1);controller.offButtonClicked(1);controller.undoButtonClicked();}

常见应用

实际上Thread的使用就是一个简单的命令模式先看下Thread的使用

new

Thread的start()方法即命令的调用者同时Thread的内部会调用Runnable的run()这里Thread又

充当了具体的命令角色最后的Runnable则是接受者了负责最后的功能处理。

Android

另一个比较典型的常用到命令模式就是Handler了这里就不贴代码了简单分析下各个类的角

接收者Handler执行消息的处理操作。

调用者Looper调用消息的的处理方法。

命令角色Message消息类。

知识小结

将发起请求的对象与执行请求的对象解耦。

发起请求的对象是调用者调用者只要调用命令对象的execute()方法就可以让接收者工作而不必知道具体的接收者对象是谁、是如何实现的命令对象会负责让接收者执行请求的动作也就是说”请求发起者”和“请求执行者”之间的解耦是通过命令对象实现的命令对象起到了纽带桥梁的作用。

容易设计一个命令队列。

只要把命令对象放到列队就可以多线程的执行命令容易实现对请求的撤销和重做命令模式不足可能导致某些系统有过多的具体命令类增加了系统的复杂度这点在在使用的时候要注意空命令也是一种设计模式它为我们省去了判空的操作。

在上面的实例中如果没有用空命令我们每按下一个按键都要判空这给我们编码带来一定的麻烦。

命令模式经典的应用场景界面的一个按钮都是一条命令、模拟

CMDDOS

Pattern封装一些作用于某种数据结构的各元素的操作它可以在不改变数据结构的前提下定义作用于这些元素的新的操作。

主要将数据结构与数据操作分离解决数据结构和操作耦合性问题访问者模式的基本工作原理是在被访问的类里面加一个对外提供接待访问者的接口访问者模式主要应用场景是需要对一个对象结构中的对象进行很多不同操作(这些操作彼此没有关联)同时需要避免让这些操作污染这些对象的类可以选用访问者模式解决

Visitor

声明的操作是每个操作实现的部分.ObjectStructure

定义一个

将观众分为男人和女人对歌手进行测评当看完某个歌手表演后得到他们对该歌手不同的评价(评价

成功、失败

将人分为男人和女人对歌手进行测评当看完某个歌手表演后得到他们对该歌手不同的评价(评价

成功、失败

{System.out.println(man.getName(),这个男人给的评价是很成功);}Overridevoid

getWomanResult(Woman

{System.out.println(woman.getName(),这个女人给的评价是很成功);}

}public

{System.out.println(man.getName(),这个男人给的评价是失败了);}Overridevoid

getWomanResult(Woman

{System.out.println(woman.getName(),这个女人给的评价是失败了);}

抽象接收者(Element角色)

这里使用到了双分派即首先在客户端程序中将具体的状态作为参数传递到Woman或者Man中第一次分派*

然后Woman类调用了作为参数的具体方法中方法getWomanResult同时将自己this作为参数传入完成了第二次分派*/

public

person){persons.add(person);}//删除public

void

person){persons.remove(person);}//显示测评结果public

void

{//创建objectStructureObjectStructure

objectStructure

ObjectStructure();objectStructure.attach(new

Man(张三));objectStructure.attach(new

Man(李四));objectStructure.attach(new

success

Success();objectStructure.display(success);//失败Action

fail

Fail();objectStructure.display(fail);}

双分派

上面提到了双分派所谓双分派是指不管类怎么变化我们都能找到期望的方法运行。

双分派意味着得到执行的操作取决于请求的种类和两个接收者的类型以上述实例为例假设我们要添加一个

Wait

{System.out.println(man.getName(),这个男人给的评价是待定);}Overridevoid

getWomanResult(Woman

{System.out.println(woman.getName(),这个女人给的评价是待定);}

main(...){//待定Action

Wait();objectStructure.display(wait);

知识小结

访问者模式符合单一职责原则、让程序具有优秀的扩展性、灵活性非常高访问者模式可以对功能进行统一可以做报表、UI、拦截器与过滤器适用于数据结构相对稳定的系统缺点具体元素对访问者公布细节也就是说访问者关注了其他类的内部细节这是迪米特法则所不建议的,

这样造成了具体元素变更比较困难违背了依赖倒转原则。

访问者依赖的是具体元素而不是抽象元素因此如果一个系统有比较稳定的数据结构又有经常变化的功能需求那么访问者模式就是比较合适的.

四、迭代器模式

Pattern是常用的设计模式属于行为型模式如果我们的集合元素是用不同的方式实现的有数组还有

java

的集合类或者还有其他方式当客户端要遍历这些集合元素的时候就要使用多种遍历方式而且还会暴露元素的内部结构可以考虑使用迭代器模式解决。

迭代器模式提供一种遍历集合元素的统一接口用一致的方法遍历集合元素不需要知道集合对象的底层表示即不暴露其内部的结构。

Iterator

编写程序展示一个学校院系结构需求是这样要在一个页面中展示出学校的院系组成一个学校

有多个学院

将学院看做是学校的子类系是学院的子类这样实际上是站在组织大小来进行分层次的实际上我们的要求是在一个页面中展示出学校的院系组成一个学校有多个学院一个学院有多个系因此这种方案不能很好实现的遍历的操作解决方案

迭代器模式

编写程序展示一个学校院系结构需求是这样要在一个页面中展示出学校的院系组成一个学校有多个学院

代码实现

departmentList;//信息工程学院是以List方式存放系int

index

InfoCollegeIterator(ListDepartment

departmentList)

(indexdepartmentList.size()-1){return

false;}index

departmentList.get(index);return

department;}//删除方法默认空实现Overridepublic

void

ComputerCollegeIterator(Department[]

departments)

(positiondepartments.length||departments[position]null){return

false;}return

department;}//删除方法默认空实现Overridepublic

void

Department[5];addDepartment(Java,java专业);addDepartment(PHP,PHP专业);addDepartment(大数据,大数据专业);}Overridepublic

String

Department(name,desc);departments[numOfDepartment]

1;}Overridepublic

ComputerCollegeIterator(departments);}

public

departmentList;//信息工程学院是以List方式存放系int

index

InfoCollegeIterator(ListDepartment

departmentList)

(indexdepartmentList.size()-1){return

false;}index

departmentList.get(index);return

department;}//删除方法默认空实现Overridepublic

void

printCollege(){//从collegeList去除所有学院//java

中的List已经实现了iteratorIteratorCollege

iterator

(College)iterator.next();System.out.println(c.getName());printDepartment(c.createIterator());}}//输出

学院输出系public

(iterator.hasNext()){Department

(Department)iterator.next();System.out.println(d.getName()

d.getDesc());}}

ComputerColleage();InfoColleage

infoColleage

InfoColleage();collegeList.add(computerColleage);collegeList.add(infoColleage);OutputImpl

output

OutputImpl(collegeList);output.printCollege();}

JDK源码ArrayList

ArrayList();a.add(jack);a.add(tom);IteratorString

iterator

(iterator.hasNext()){System.out.println(iterator.next());}}

内部类

提供一个统一的方法遍历对象客户不用再考虑聚合的类型使用一种方法就可以遍历对象了。

隐藏了聚合的内部结构客户端要遍历聚合的时候只能取到迭代器而不会知道聚合的具体组成。

提供了一种设计思想就是一个类应该只有一个引起变化的原因叫做单一责任原则。

在聚合类中我们把迭代器分开就是要把管理对象集合和遍历对象集合的责任分开这样一来集合改变的话只影响到聚合对象。

而如果遍历方式改变的话只影响到了迭代器。

当要展示一组相似对象或者遍历一组相同对象时使用,

适合使用迭代器模式

观察者模式类似订牛奶业务奶站/气象局Subject用户/第三方网站Observer

registerObserver

通知所有的注册的用户根据不同需求可以是更新数据让用户来取也可能是实施推送

看具体需求定Observer接收输入观察者模式对象之间多对一依赖的一种设计方案被依赖的对象为

Observer

气象站可以将每天测量到的温度湿度气压等等以公告的形式发布出去(比如发布到自己的网站或第三方)。

需要设计开放型

API便于其他第三方也能接入气象站获取数据。

提供温度、气压和湿度的接口测量数据更新时要能实时的通知给第三方

传统方案

***);System.out.println(***Today

mPressure:

***);System.out.println(***Today

mHumidity:

currentConditions;//加入新的第三方public

currentConditions)

updatecurrentConditions.update(getTemperature(),

getPressure(),

currentConditionsdataChange();}

客户端测试

currentConditionsCurrentConditions

currentConditions

WeatherData(currentConditions);//更新天气情况weatherData.setData(30,

150,

40);//天气情况变化System.out.println(天气情况变化);weatherData.setData(40,

160,

其他第三方接入气象站获取数据的问题无法在运行时动态的添加第三方

(新浪网站)违反

中当增加一个第三方都需要创建一个对应的第三方的公告板对象并加入到

dataChange,

{notifyObservers();}Overridepublic

void

{observers.add(observer);}Overridepublic

void

(observers.contains(observer)){observers.remove(observer);}}Overridepublic

void

{observer.update(getTemperature(),getPressure(),getHumidity());}}}

Observer接收输入

***);System.out.println(***Today

mPressure:

***);System.out.println(***Today

mHumidity:

***);System.out.println(***百度数据

气压:

***);System.out.println(***百度数据

湿度:

BaiduSite();//注册到weatherDatasubject.registerObserver(observer);subject.registerObserver(observer2);//通知各个注册的观察者((WeatherData)subject).setData(10f,20f,30f);}

JDK源码Observable

{//构造函数初始化一个观察者list来保存观察者observers

new

ArrayList();}//添加观察者带同步字段的所以是线程安全的public

synchronized

{observers.add(o);}}//删除观察者public

synchronized

{observers.remove(o);}//通知所以观察者无参数public

void

{notifyObservers(null);}//通知所有观察者带参数public

void

arrLocal;//加synchronized字段保证多线程下操作没有问题synchronized

(this)

(!hasChanged())//这里做了是否发生改变的判断是为了防止出现无意义的更新return;arrLocal

Observer[observers.size()]);//ArrayList转换成一个临时的数组这样就防止了通知添加移除同时发生可能导致的异常clearChanged();///清除改变状态设置为false}//遍历逐一通知for

(int

{observers.clear();}//设置被观察者为改变状态设置为trueprotected

synchronized

true;}//清除改变状态设置为falseprotected

synchronized

观察者模式设计后会以集合的方式来管理用户(Observer)包括注册移除和通知。

这样我们增加观察者(这里可以理解成一个新的公告板)就不需要去修改核心类

WeatherData

原则。

解除观察者与主题之间的耦合。

让耦合的双方都依赖于抽象而不是依赖具体。

从而使得各自的变化都不会影响另一边的变化。

易于扩展对同一主题新增观察者时无需修改原有代码。

依赖关系并未完全解除抽象主题仍然依赖抽象观察者。

使用观察者模式时需要考虑一下开发效率和运行效率的问题程序中包括一个被观察者、多个观察者开发、调试等内容会比较复杂而且在Java中消息的通知一般是顺序执行那么一个观察者卡顿会影响整体的执行效率在这种情况下一般会采用异步实现。

可能会引起多余的数据通知。

六、中介者模式

Pattern用一个中介对象来封装一系列的对象交互。

中介者使各个对象不需要显式地相互引用从而使其耦合松散而且可以独立地改变它们之间的交互中介者模式属于行为型模式使代码易于维护比如

MVC

就是抽象中介者,定义了同事对象到中介者对象的接口Colleague

实现抽象方法,

HashMap,并接受某个同事对象消息完成相应的任务ConcreteColleague

应用案例一智能家庭管理问题

等主人要看电视时各个设备可以协同工作自动完成看电视的准备工作比如流程为闹铃响起-咖啡机开始做咖啡-窗帘自动落下-电视机开始播放

传统方式解决

当各电器对象有多种状态改变时相互之间的调用关系会比较复杂各个电器对象彼此联系你中有我我中有你不利于松耦合.各个电器对象之间所传递的消息(参数)容易混乱当系统增加一个新的电器对象时或者执行流程改变时代码的可维护性、扩展性都不理想考虑中介者模式

代码实现

{this.GetMediator().GetMessage(stateChange,

this.name);}public

{SendMessage(stateChange);}Overridepublic

void

{this.GetMediator().GetMessage(stateChange,

this.name);}}public

{this.GetMediator().GetMessage(stateChange,

this.name);}public

minutes!);System.out.println(Coffee

}public

{this.GetMediator().GetMessage(stateChange,

this.name);}public

{colleagueMap.put(colleagueName,

colleague);if

colleagueName);}}//具体中介者的核心方法//1.

根据得到消息完成对应任务//2.

中介者在这个方法协调各个具体的同事对象完成任务Overridepublic

void

(colleagueMap.get(colleagueName)

instanceof

(colleagueMap.get(interMap.get(CoffeeMachine)))).StartCoffee();((TV)

(colleagueMap.get(interMap.get(TV)))).StartTv();}

else

(colleagueMap.get(interMap.get(TV)))).StopTv();}}

else

(colleagueMap.get(colleagueName)

instanceof

(colleagueMap.get(interMap.get(Curtains)))).UpCurtains();}

else

(colleagueMap.get(colleagueName)

instanceof

(colleagueMap.get(colleagueName)

instanceof

{//如果是以窗帘发出的消息这里处理...}}Overridepublic

void

getMessage会根据接收到的同事对象发出的消息来协调调用其它的同事对象

完成任务

TV);//让闹钟发出消息alarm.SendAlarm(0);coffeeMachine.FinishCoffee();alarm.SendAlarm(1);}

知识小结

多个类相互耦合会形成网状结构,使用中介者模式将网状结构分离为星型结构进行解耦减少类间依赖降低了耦合符合迪米特原则中介者承担了较多的责任一旦中介者出现了问题整个系统就会受到影响如果设计不当中介者对象本身变得过于复杂这点在实际使用时要特别注意

七、备忘录模式

Pattern在不破坏封装性的前提下捕获一个对象的内部状态并在该对象之外保存这个状态。

这样以后就可将该对象恢复到原先保存的状态可以这里理解备忘录模式现实生活中的备忘录是用来记录某些要去做的事情或者是记录已经达成的共同意见的事情以防忘记了。

而在软件层面备忘录模式有着相同的含义备忘录对象主要用来记录一个对象的某种状态或者某些数据当要做回退时可以从备忘录对象里获取原来的数据进行恢复操作备忘录模式属于行为型模式

基本原理

state;}//编写一个方法可以保存一个状态对象Memento//

Memento

Memento(state);}//通过备忘录对象恢复状态public

String

memento){mementoList.add(memento);}//获取到第index个Originator的备忘录对象public

Memento

Caretaker();originator.setState(

状态#1

);//保存了当前的状态caretaker.add(originator.saveStateMemento());originator.setState(

状态#2

);caretaker.add(originator.saveStateMemento());originator.setState(

状态#3

);caretaker.add(originator.saveStateMemento());System.out.println(当前的状态是originator.getState());//希望恢复到状态1System.out.println(恢复到状态1originator.getStateFromMemento(caretaker.get(0)));}

应用案例一游戏角色状态恢复问题

这样当我们游戏的对象很多时不利于管理开销也很大.传统的方式是简单地做备份new

出另外一个对象出来再把需要备份的数据放到这个新对象但这就暴露了对象内部的细节解决方案

备忘录模式

Memento(vit,def);}//恢复gameRole的状态public

void

recoverGameRoleFromMemento(Memento

memento){this.vit

memento.getDef();}//显示当前游戏角色的状态public

void

display(){System.out.println(游戏角色当前的攻击力this.vit当前游戏角色的防御力this.def);}}

Caretaker:

GameRole();gameRole.setVit(100);gameRole.setDef(100);System.out.println(和boss大战前的状态);gameRole.display();//把当前状态保存caretakerCaretaker

caretaker

Caretaker();caretaker.setMemento(gameRole.createMemento());System.out.println(和boss开始大战);gameRole.setDef(30);gameRole.setVit(30);gameRole.display();System.out.println(大战后使用备忘录恢复元气);gameRole.recoverGameRoleFromMemento(caretaker.getMemento());gameRole.display();}

和boss开始大战

给用户提供了一种可以恢复状态的机制可以使用户能够比较方便地回到某个历史的状态实现了信息的封装使得用户不需要关心状态的保存细节如果类的成员变量过多势必会占用比较大的资源而且每一次保存都会消耗一定的内存,

3、Windows

1、在编译原理中一个算术表达式通过词法分析器形成词法单元而后这些词法单元再通过语法

分析器构建语法分析树最终形成一颗抽象的语法分析树。

这里的词法分析器和语法分析器都可以

2、解释器模式Interpreter

Pattern是指给定一个语言(表达式)定义它的文法的一种表示

3、应用场景

应用可以将一个需要解释执行的语言中的句子表示为一个抽象语法树一些重复出现的问题可以用一种简单的语言来表达一个简单语法需要解释的场景

4、这样的例子还有比如编译器、运算表达式计算、正则表达式、机器人等

基本原理

是环境角色,含有解释器之外的全局信息.AbstractExpression:

抽象表达式

声明一个抽象的解释操作,这个方法为抽象语法树中所有的节点所共享TerminalExpression:

为终结符表达式,

实现与文法中的终结符相关的解释操作NonTermialExpression:

Context

编写一个方法接收表达式的形式然后根据用户输入的数值进行解析得到结果问题分析如果加入新的运算符比如

表达式

interpreter(HashMapString,Integer

var);

抽象运算符号解析器这里每个运算符号都只和自己左右两个数字有关系*

但左右两个数字有可能也是一个解析的结果无论何种类型都是Expression类的实现类*/

public

是让他的子类来实现的因此interpreter是一个默认实现Overridepublic

int

super.left.interpreter(var)super.right.interpreter(var);}

}/***

super.left.interpreter(var)-super.right.interpreter(var);}

计算器

VarExpression(String.valueOf(charArray[i]));//

取出右表达式

VarExpression(String.valueOf(charArray[i]));stack.push(new

SubExpression(left,

VarExpression(String.valueOf(charArray[i])));break;}}//当遍历完整个

charArray

this.expression.interpreter(var);}}

客户端测试代码

Calculator(expStr);System.out.println(运算结果

expStr

{System.out.print(请输入表达式);return

(new

InputStreamReader(System.in))).readLine();}//

获得值映射public

(!map.containsKey(String.valueOf(ch)))

String.valueOf(ch)

InputStreamReader(System.in))).readLine();map.put(String.valueOf(ch),

map;}}

当有一个语言需要解释执行可将该语言中的句子表示为一个抽象语法树就可以考虑使用解释器模式

应用场景编译器、运算表达式计算、正则表达式、机器人等使用解释器可能带来的问题解释器模式会引起类膨胀、解释器模式采用递归调用方法将会导致调试非

九、状态模式

Pattern它主要用来解决对象在多种状态转换时需要对外输出不同的行为的问题。

状态和行为是一一对应的状态之间可以相互转换当一个对象的内在状态改变时允许改变其行为这个对象看起来像是改变了其类

基本原理

可以抽奖、不能抽奖、发放奖品和奖品领完活动的四个状态转换关系图(右图)

代码实现

activity;}//已经扣除了积分不能再扣Overridepublic

void

{System.out.println(已经扣取过了积分);}//可以抽奖,

boolean

{System.out.println(正在抽奖请稍等);Random

new

contextactivity.setState(activity.getDispenseState());return

true;}

{System.out.println(很遗憾没有抽中奖品);//

改变状态为不能抽奖activity.setState(activity.getNoRafflleState());return

false;}}//

{System.out.println(没中奖不能发放奖品);}}public

class

初始化时传入活动引用扣除积分后改变其状态RaffleActivity

activity;public

activity;}//当前状态是可以扣积分的扣除后将状态设置成抽象状态Overridepublic

void

积分成功您可以抽奖了);activity.setState(activity.getCanRaffleState());}Overridepublic

boolean

{System.out.println(扣了积分才能抽奖喔);return

void

初始化时传入活动引用发放奖品后改变其状态RaffleActivity

activity;public

{System.out.println(不能扣除积分);}Overridepublic

boolean

{System.out.println(不能抽奖);return

void

改变状态为不能抽奖activity.setState(activity.getNoRafflleState());}

else

{System.out.println(很遗憾奖品发送完了);//

改变状态为奖品发送完毕,

后面我们就不可以抽奖activity.setState(activity.getDispensOutState());//System.out.println(抽奖活动结束);//System.exit(0);}}

}public

DispenseOutState(RaffleActivity

activity)

{System.out.println(奖品发送完了请下次再参加);}Overridepublic

boolean

{System.out.println(奖品发送完了请下次再参加);return

void

{System.out.println(奖品发送完了请下次再参加);}

Context角色

DispenseOutState(this);//构造器//1.

RaffleActivity(int

{state.deduceMoney();}//抽奖public

void

{//领取奖品state.dispensePrize();}}public

State

state;}//这里请大家注意每领取一次奖品count--public

int

参加抽奖第一步点击扣除积分activity.debuctMoney();//

源码剖析借贷平台

RuntimeException(操作流程不允许);//抽象类默认实现了

State

接口的所有方法//该类的所有方法其子类(具体的状态类)可以有选择的进行重写Overridepublic

void

StateEnum.FEED_BACKED.getValue();}

}public

FeedBackState());}Overridepublic

String

StateEnum.GENERATE.getValue();}}public

class

FeedBackState());}Overridepublic

String

StateEnum.NOT_PAY.getValue();}}public

class

FeedBackState());}Overridepublic

String

StateEnum.PAID.getValue();}}public

class

NotPayState。

//至于应该变成哪个状态有流程图来决定context.setState(new

void

FeedBackState());}Overridepublic

String

StateEnum.PUBLISHED.getValue();}}public

class

PublishState());}Overridepublic

String

StateEnum.REVIEWED.getValue();}

上下文环境

getCurrentState();}Overridepublic

void

getCurrentState();}Overridepublic

void

getCurrentState();}Overridepublic

void

getCurrentState();}Overridepublic

void

state.notPeopleAcceptEvent(this);

getCurrentState();}Overridepublic

void

getCurrentState();}Overridepublic

void

getCurrentState();}Overridepublic

void

PublishStatecontext.setState(new

PublishState());System.out.println(context.getCurrentState());//

//publish

paycontext.acceptOrderEvent(context);//

//not

paidcontext.payOrderEvent(context);//

失败,

{context.checkFailEvent(context);System.out.println(流程正常..);}

catch

System.out.println(e.getMessage());//

}}}

代码有很强的可读性。

状态模式将每个状态的行为封装到对应的一个类中方便维护。

将容易产生问题的

if-else

语句删除了如果把每个状态的行为都放到一个类中每次调用方法时都要判断当前是什么状态不但会产出很多

if-else

语句而且容易出错符合“开闭原则”。

容易增删状态会产生很多类。

每个状态都要一个对应的类当状态过多时会产生很多类加大维护难度应用场景当一个事件或者对象有很多种状态状态之间会相互转换对不同的状态要求有不同的行为的时候

十、策略模式

Pattern中定义算法族策略组分别封装起来让他们之间可以互相替换此模式让算法的变化独立于使用算法的客户这算法体现了几个设计原则第一、把变化的代码从不变的代码中分离出来第二、针对接口编程而不是具体类定义了策略接口第三、多用组合/聚合少用继承客户通过组合方式使用策略

context

的问题其实是继承带来的问题对类的局部改动尤其超类的局部改动会影响其他部分。

会有溢出效应为了改进

fly

{System.out.println(自由飞翔飞翔能力max);}

}public

GoodFlyBehavior();}Overridevoid

display()

{System.out.println(野鸭子);}}public

class

{System.out.println(北京鸭);}}public

class

WildDuck();wildDuck.display();wildDuck.fly();PekingDuck

pekingDuck

PekingDuck();pekingDuck.display();pekingDuck.fly();}

应用案例二旅游出行

先看下面的图片我们去旅游选择出行模式有很多种可以骑自行车、可以坐汽车、可以坐火车、可以坐飞

作为一个程序猿开发需要选择一款开发工具当然可以进行代码开发的工具有很多可以选择

Idea进行开发也可以使用eclipse进行开发也可以使用其他的一些开发工具。

该模式定义了一系列算法并将每个算法封装起来使它们可以相互替换且算法的变化不会影响

使用算法的客户。

策略模式属于对象行为模式它通过对算法进行封装把使用算法的责任和算法

抽象策略Strategy类这是一个抽象角色通常由一个接口或抽象类实现。

此角色给出所有的具体策略类所需的接口。

具体策略Concrete

Strategy类实现了抽象策略定义的接口提供具体的算法实现或行为。

环境Context类持有一个策略类的引用最终给客户端调用。

三案例实现

一家百货公司在定年度的促销活动。

针对不同的节日春节、中秋节、圣诞节推出不同的促销活

类图如下

{System.out.println(满200元减50元);}

public

{System.out.println(满1000元加一元换购任意200元以下商品);}

定义环境角色Context用于连接上下文即把促销活动推销给客户这里可以理解为销售员

public

userService;PostMapping(/login)public

LoginResp

loginReq){if(loginReq.getType().equals(account)){System.out.println(用户名密码登录);//执行用户密码登录逻辑return

new

if(loginReq.getType().equals(sms)){System.out.println(手机号验证码登录);//执行手机号验证码登录逻辑return

new

(loginReq.getType().equals(we_chat)){System.out.println(微信登录);//执行用户微信登录逻辑return

new

LoginResp();loginResp.setSuccess(false);System.out.println(登录失败);return

loginResp;}

注意我们重点讲的是设计模式并不是登录的逻辑所以以上代码并没有真正的实现登录功能

(2)问题分析

业务层代码大量使用到了if...else在后期阅读代码的时候会非常不友好大量使用if...else性能也不高如果业务发生变更比如现在新增了QQ登录方式这个时候需要修改业务层代码违反了开闭原则

解决使用工厂方法设计模式策略模式解决

改造之后不在service中写业务逻辑让service调用工厂然后通过service传递不同的参数来获

2具体实现

具体的策略AccountGranter、SmsGranter、WeChatGranter

/***

ConcurrentHashMap();Autowiredprivate

LoginTypeConfig

setApplicationContext(ApplicationContext

applicationContext)

{loginTypeConfig.getTypes().forEach((k,

{granterPool.put(k,

applicationContext.getBean(y));});}/***

对外提供获取具体策略**

granterPool.get(grantType);return

tokenGranter;}}

factory.getGranter(loginReq.getType());if(granter

null){LoginResp

LoginResp();loginResp.setSuccess(false);return

loginResp;}LoginResp

大家可以看到我们使用了设计模式之后业务层的代码就清爽多了如果后期有新的需求改动比如加入了QQ登录我们只需要添加对

举一反三

其实像这样的需求在日常开发中非常常见场景有很多以下的情景都可以使用工厂模式策略模式解决比

支付宝支付微信支付银行卡支付现金支付

(LegacyMergeSort.userRequested)legacyMergeSort(a,

a.length,

comparator);System.out.println(Arrays.toString(data));

降序排序//方式

在Android中使用ListView时都需要设置一个Adapter而这个Adapter根据我们实际的需求可以

用ArrayAdapter、SimpleAdapter等等这里就运用到策略模式。

知识小结

策略模式的关键是分析项目中变化部分与不变部分策略模式的核心思想是多用组合/聚合

少用继承用行为类组合而不是行为的继承。

更有弹性体现了“对修改关闭对扩展开放”原则客户端增加行为不用修改原有代码只要添加一种策略或者行为

Strategy

改变它使它易于切换、易于理解、易于扩展需要注意的是每添加一个策略就要增加一个类当策略过多是会导致类数目庞大

十一、职责链模式

责任链模式为请求创建了一个接收者对象的链(简单示意图)。

这种模式对请求的发送者和接收者进行解耦。

职责链模式通常每个接收者都包含对另一个接收者的引用。

如果一个对象不能处理该请求那么它会把相同的请求传给下一个接收者依此类推。

这种类型的设计模式属于行为型模式

Handler

(request.getPrice()5000){System.out.println(请求编号idrequest.getId()

this.name处理);}else

{System.out.println(this.name无法处理交给上一级处理

approver.name);approver.processRequest(request);}}}public

class

(request.getPrice()5000request.getPrice()10000){System.out.println(请求编号idrequest.getId()

this.name处理);}else

{System.out.println(this.name无法处理交给上一级处理

approver.name);approver.processRequest(request);}}

}public

ViceSchoolMasterApprover(String

name)

(request.getPrice()10000request.getPrice()30000){System.out.println(请求编号idrequest.getId()

this.name处理);}else

{System.out.println(this.name无法处理交给上一级处理

approver.name);approver.processRequest(request);}}}public

class

(request.getPrice()30000){System.out.println(请求编号idrequest.getId()

this.name处理);}else

{System.out.println(this.name无法处理交给下一级处理

approver.name);approver.processRequest(request);}}}

客户端调用

PurchaseRequest(1,1,13200);//创建相关的审批人DepartmentApprover

departmentApprover

DepartmentApprover(主任);CollegeApprover

collegeApprover

CollegeApprover(院长);ViceSchoolMasterApprover

new

ViceSchoolMasterApprover(副校长);SchoolMasterApprover

schoolMasterApprover

SchoolMasterApprover(校长);//需要将各个审批节点的下一级设置好departmentApprover.setApprover(collegeApprover);collegeApprover.setApprover(viceSchoolMasterApprover);viceSchoolMasterApprover.setApprover(schoolMasterApprover);schoolMasterApprover.setApprover(departmentApprover);//处理请求departmentApprover.processRequest(request);}

主任无法处理交给上一级处理

在现实生活中常常会出现这样的事例一个请求有多个对象可以处理但每个对象的处理条件或

例如公司员工请假可批假的领导有部门负责人、副总经理、总经理等但每个领导能批准的天

数不同员工必须根据自己要请假的天数去找不同的领导签名也就是说员工必须记住每个领导的

姓名、电话和地址等信息这增加了难度。

这样的例子还有很多如找领导出差报销、生活中

又名职责链模式为了避免请求发送者与多个请求处理者耦合在一起将所有请求的处理者通过前

一对象记住其下一个对象的引用而连成一条链当有请求发生时可将请求沿着这条链传递直到

比较常见的springmvc中的拦截器web开发中的filter过滤器

基本结构

抽象处理者Handler角色定义一个处理请求的接口包含抽象处理方法和一个后继连接。

具体处理者Concrete

Handler角色实现抽象处理者的处理方法判断能否处理本次请求如果可以处理请求则处理否则将该请求转给它的后继者。

客户类Client角色创建处理链并向链头的具体处理者对象提交请求它不关心处理细节和请求的传递过程。

案例实现

com.itheima.designpattern.chain;/***

抽象处理者*/

com.itheima.designpattern.chain;import

class

{System.out.println(校验订单基本信息);//校验handler.process(order);}}/***

补充订单信息*/

{System.out.println(补充订单信息);handler.process(order);}}/***

计算金额*/

{System.out.println(计算金额-优惠券、VIP、活动打折);handler.process(order);}}/***

订单入库*/

OrderValidition();//补充订单信息Handler

orderFill

OrderAmountCalcuate();//订单落库Handler

orderCreate

OrderCreate();//设置责任链路orderValidition.setNext(orderFill);orderFill.setNext(orderAmountCalcuate);orderAmountCalcuate.setNext(orderCreate);//开始执行orderValidition.process(new

OrderInfo());}}

降低了对象之间的耦合度该模式降低了请求发送者和接收者的耦合度。

增强了系统的可扩展性可以根据需要增加新的请求处理类满足开闭原则。

增强了给对象指派职责的灵活性当工作流程发生变化可以动态地改变链内的成员或者修改它们的次序也可动态地新增或者删除责任。

责任链简化了对象之间的连接一个对象只需保持一个指向其后继者的引用不需保持其他所有处理者的引用这避免了使用众多的

if···else

语句。

责任分担每个类只需要处理自己该处理的工作不能处理的传递给下一个对象完成明确各类的责任范围符合类的单一职责原则。

不能保证每个请求一定被处理。

由于一个请求没有明确的接收者所以不能保证它一定会被处理该请求可能一直传到链的末端都得不到处理。

对比较长的职责链请求的处理可能涉及多个处理对象系统性能将受到一定影响。

职责链建立的合理性要靠客户端来保证增加了客户端的复杂性可能会由于职责链的错误设置而导致系统出错如可能会造成循环调用。

举一反三

将请求和处理分开实现解耦提高系统的灵活性简化了对象使对象不需要知道链的结构性能会受到影响特别是在链比较长的时候因此需控制链中最大节点数量一般通过在

Handler

setNext()方法中判断是否已经超过阀值超过则不允许该链建立避免出现超长链无意识地破坏系统性能调试不方便。

采用了类似递归的方式调试时逻辑可能比较复杂最佳应用场景有多个对象可以处理同一个请求时比如多级请求、请假/加薪等审批流程、Java

Web中



SEO优化服务概述

作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。

百度官方合作伙伴 白帽SEO技术 数据驱动优化 效果长期稳定

SEO优化核心服务

网站技术SEO

  • 网站结构优化 - 提升网站爬虫可访问性
  • 页面速度优化 - 缩短加载时间,提高用户体验
  • 移动端适配 - 确保移动设备友好性
  • HTTPS安全协议 - 提升网站安全性与信任度
  • 结构化数据标记 - 增强搜索结果显示效果

内容优化服务

  • 关键词研究与布局 - 精准定位目标关键词
  • 高质量内容创作 - 原创、专业、有价值的内容
  • Meta标签优化 - 提升点击率和相关性
  • 内容更新策略 - 保持网站内容新鲜度
  • 多媒体内容优化 - 图片、视频SEO优化

外链建设策略

  • 高质量外链获取 - 权威网站链接建设
  • 品牌提及监控 - 追踪品牌在线曝光
  • 行业目录提交 - 提升网站基础权威
  • 社交媒体整合 - 增强内容传播力
  • 链接质量分析 - 避免低质量链接风险

SEO服务方案对比

服务项目 基础套餐 标准套餐 高级定制
关键词优化数量 10-20个核心词 30-50个核心词+长尾词 80-150个全方位覆盖
内容优化 基础页面优化 全站内容优化+每月5篇原创 个性化内容策略+每月15篇原创
技术SEO 基本技术检查 全面技术优化+移动适配 深度技术重构+性能优化
外链建设 每月5-10条 每月20-30条高质量外链 每月50+条多渠道外链
数据报告 月度基础报告 双周详细报告+分析 每周深度报告+策略调整
效果保障 3-6个月见效 2-4个月见效 1-3个月快速见效

SEO优化实施流程

我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:

1

网站诊断分析

全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。

2

关键词策略制定

基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。

3

技术优化实施

解决网站技术问题,优化网站结构,提升页面速度和移动端体验。

4

内容优化建设

创作高质量原创内容,优化现有页面,建立内容更新机制。

5

外链建设推广

获取高质量外部链接,建立品牌在线影响力,提升网站权威度。

6

数据监控调整

持续监控排名、流量和转化数据,根据效果调整优化策略。

SEO优化常见问题

SEO优化一般需要多长时间才能看到效果?
SEO是一个渐进的过程,通常需要3-6个月才能看到明显效果。具体时间取决于网站现状、竞争程度和优化强度。我们的标准套餐一般在2-4个月内开始显现效果,高级定制方案可能在1-3个月内就能看到初步成果。
你们使用白帽SEO技术还是黑帽技术?
我们始终坚持使用白帽SEO技术,遵循搜索引擎的官方指南。我们的优化策略注重长期效果和可持续性,绝不使用任何可能导致网站被惩罚的违规手段。作为百度官方合作伙伴,我们承诺提供安全、合规的SEO服务。
SEO优化后效果能持续多久?
通过我们的白帽SEO策略获得的排名和流量具有长期稳定性。一旦网站达到理想排名,只需适当的维护和更新,效果可以持续数年。我们提供优化后维护服务,确保您的网站长期保持竞争优势。
你们提供SEO优化效果保障吗?
我们提供基于数据的SEO效果承诺。根据服务套餐不同,我们承诺在约定时间内将核心关键词优化到指定排名位置,或实现约定的自然流量增长目标。所有承诺都会在服务合同中明确约定,并提供详细的KPI衡量标准。

SEO优化效果数据

基于我们服务的客户数据统计,平均优化效果如下:

+85%
自然搜索流量提升
+120%
关键词排名数量
+60%
网站转化率提升
3-6月
平均见效周期

行业案例 - 制造业

  • 优化前:日均自然流量120,核心词无排名
  • 优化6个月后:日均自然流量950,15个核心词首页排名
  • 效果提升:流量增长692%,询盘量增加320%

行业案例 - 电商

  • 优化前:月均自然订单50单,转化率1.2%
  • 优化4个月后:月均自然订单210单,转化率2.8%
  • 效果提升:订单增长320%,转化率提升133%

行业案例 - 教育

  • 优化前:月均咨询量35个,主要依赖付费广告
  • 优化5个月后:月均咨询量180个,自然流量占比65%
  • 效果提升:咨询量增长414%,营销成本降低57%

为什么选择我们的SEO服务

专业团队

  • 10年以上SEO经验专家带队
  • 百度、Google认证工程师
  • 内容创作、技术开发、数据分析多领域团队
  • 持续培训保持技术领先

数据驱动

  • 自主研发SEO分析工具
  • 实时排名监控系统
  • 竞争对手深度分析
  • 效果可视化报告

透明合作

  • 清晰的服务内容和价格
  • 定期进展汇报和沟通
  • 效果数据实时可查
  • 灵活的合同条款

我们的SEO服务理念

我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。

提交需求或反馈

Demand feedback