策略模式、模板方法模式、观察者模式、迭代模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
1、策略模式( Strategy )
定义个策略接口,不同的实现类提供不同的具体策略算法, 同时它们之间可以互相替换。
IStrategy 接口定义了策略方法,Strategy1 和 Strategy2 通过实现 IStrategy 提供不同的策略,而 User 组合了 IStrategy ,可以通过给 User 对象设置不同具体实现类来让其获得不同的策略。
实现示例代码:
/**
*商人
*/
public class BusinessMan{
privateTransportationStrategy strategy;
public BusinessMan(TransportationStrategy strategy) {
this.strategy =strategy;
}
public void changetStrategy(TransportationStrategy strategy) {
this.strategy =strategy;
}
public void transport() {
this.strategy.go();
}
}
/**
*交通方式策略
*/
@FunctionalInterface
public interface TransportationStrategy{
void go();
}
/**
*乘飞机
*/
public class TransportationAirplane implements TransportationStrategy{
private static final Logger LOGGER = LoggerFactory.getLogger(TransportationAirplane.class);
@Override
public void go() {
LOGGER.info("乘飞机从北京去广州");
}
}
/**
*乘火车
*/
public class TransportationTrain implements TransportationStrategy{
private static final Logger LOGGER = LoggerFactory.getLogger(TransportationTrain.class);
@Override
public void go() {
LOGGER.info("乘高铁从北京去上海");
}
}
/**
*驾车
*/
public class TransportationVehicle implements TransportationStrategy{
private static final Logger LOGGER = LoggerFactory.getLogger(TransportationVehicle.class);
@Override
public void go() {
LOGGER.info("驾车从北京去天津");
}
}
/**
* Strategy
*/
public class Application{
public static void main(String[] args) {
BusinessMan man= new BusinessMan(newTransportationAirplane());
man.transport();
man.changetStrategy(newTransportationTrain());
man.transport();
man.changetStrategy(newTransportationVehicle());
man.transport();
}
}
2、模板方法模式( Template )
定义一个操作的算法骨架, 并将一些步骤延迟到子类中。
AbsTemplate 抽象类中定义了一系列的方法,其中外界唯一能调用的 operation() 方法是 final 的(即不可重写),在该方法中分别调用了 first() 、second() 、third() 方法(即搭好算法框架),子类通过继承抽象类重写不同的方法来添加各自的行为。
实现示例代码:
/**
*学生
*/
public class Student{
private LearningMethod method;
public Student(LearningMethod method) {
this.method =method;
}
/**
*学习
*
*@param description 状态
*@paramadviser
请教对象
*/
public void learn(String description, String adviser) {
method.learn(description, adviser);
}
/**
*更换学习方法
*
*@param method
*/
public void changeMethod(LearningMethod method) {
this.method =method;
}
}
/**
*学习方法的抽象类
*/
public abstract class LearningMethod{
private static final Logger LOGGER = LoggerFactory.getLogger(LearningMethod.class);
/**
*预习效果
*
*@return
*/
protected abstract String preLearning();
/**
*状态
*
*@param description 学习状态
*/
protected abstract void Learning(String description);
/**
*请教对象
*
*@param adviser 请教对象
*/
protected abstract void afterLearning(String adviser);
/**
*学习过程
*
*@param description 听课状态
*@paramadviser
请假对象
*/
public void learn(String description, String adviser) {
String preLearningResult=preLearning();
LOGGER.info("{}", preLearningResult);
Learning(description);
afterLearning(adviser);
}
}
/**
*消极的学习方法
*/
public class NegativeLearinngMethod extends LearningMethod{
private static final Logger LOGGER = LoggerFactory.getLogger(NegativeLearinngMethod.class);
@Override
protected String preLearning() {
return "几乎没有预习,对上课要学的内容一无所知";
}
@Override
protected void Learning(String description) {
LOGGER.info("学习状态:{}", description);
}
@Override
protected void afterLearning(String adviser) {
if (!adviser.equals("")) {
LOGGER.info("只有很少的知识点没有听懂,于是找{}提问", adviser);
}
}
}
/**
*积极的学习方法
*/
public class PositiveLearningMethod extends LearningMethod{
private static final Logger LOGGER = LoggerFactory.getLogger(PositiveLearningMethod.class);
@Override
protected String preLearning() {
return "预习到位,为听课打下很好的基础";
}
@Override
protected void Learning(String description) {
LOGGER.info("学习状态:{}", description);
}
@Override
protected void afterLearning(String adviser) {
if (!adviser.equals("")) {
LOGGER.info("只有很少的知识点没有听懂,于是找{}提问", adviser);
}
}
}
/**
* Template method
*/
public class Application{
private static final Logger LOGGER = LoggerFactory.getLogger(Application.class);
public static void main(String[] args) {
Student student= new Student(newPositiveLearningMethod());
student.learn("上课走神", "同学");
LOGGER.info("更换学习方法");
student.changeMethod(newNegativeLearinngMethod());
student.learn("认证听讲", "老师");
}
}
3、观察者模式( Observer )
定义了一种一对多的依赖关系,让多个观察者对象同时监听某一主题对象,在它的状态发生变化时,会通知所有的观察者。
先将 Observer 注册到 Observable ,那么当 Observable 状态改变时会通知它持有的所有 Observer ,对了,最好 Observable 中的 mList 的泛型是 WeakReference
实现示例代码:
/**
*一天中的几个时间点
*/
public enum TimePoint{
MORNING("早晨"), NOON("中午"), AFTERNOON("下午"), EVENING("晚上");
privateString name;
TimePoint(String name) {
this.name =name;
}
@Override
public String toString() {
returnname;
}
}
/**
*时间观察者接口
*/
public interface TimeObserver{
void update(TimePoint time);
}
/**
*时间
*/
public class Time{
private static final Logger LOGGER = LoggerFactory.getLogger(Time.class);
privateTimePoint point;
private List
public Time() {
this.point = TimePoint.MORNING;
observers= new ArrayList<>();
}
public void addObserver(TimeObserver observer) {
observers.add(observer);
}
public void removeObserver(TimeObserver observer) {
observers.remove(observer);
}
public void passing() {
TimePoint[] points = TimePoint.values();
point= points[(point.ordinal()
+ 1) % points.length];
LOGGER.info("时间来到了{}", point);
notifyObservers();
}
public void notifyObservers() {
for (TimeObserver observer :observers) {
observer.update(point);
}
}
}
/**
*北方人
*/
public class Northern implements TimeObserver{
private static final Logger LOGGER = LoggerFactory.getLogger(Northern.class);
@Override
public void update(TimePoint time) {
LOGGER.info("北方人吃饭了");
switch(time) {
case MORNING:
LOGGER.info("煎饼果子");
break;
case NOON:
LOGGER.info("炸酱面");
break;
case AFTERNOON:
LOGGER.info("牛奶");
break;
case EVENING:
LOGGER.info("包子");
break;
default:
break;
}
}
}
/**
*南方人
*/
public class Southern implements TimeObserver{
private static final Logger LOGGER = LoggerFactory.getLogger(Southern.class);
@Override
public void update(TimePoint time) {
LOGGER.info("南方人吃饭了");
switch(time) {
case MORNING:
LOGGER.info("热干面");
break;
case NOON:
LOGGER.info("米饭");
break;
case AFTERNOON:
LOGGER.info("茶");
break;
case EVENING:
LOGGER.info("鱼");
break;
default:
break;
}
}
}
/**
* Observer
*/
public class Application{
public static void main(String[] args) {
Time time= newTime();
time.addObserver(newNorthern());
time.addObserver(newSouthern());
time.passing();
time.passing();
time.passing();
time.passing();
time.passing();
time.passing();
time.passing();
time.passing();
time.passing();
}
}
4、命令模式( Command )
将一个请求封装成为一个对象, 使可以用不同的请求对客户进行参数化。
Action 封装了具体行为,Command 封装了 Action 并提供空方法 execute() ,它的子类通过重写该方法可在方法里调用 mAction 不同行为达到封装命令的目的,最后 Client 封装了一系列的 Command 对象,并可以通过 notify() 方法一个接着一个调用所持有 Command 对象们的 execute() 方法达到给 Action 传达命令的目的。
实现示例代码:
/**
*字体颜色
*/
public enum Color{
RED("红"), BLACK("黑");
private String name;
Color(String name) {
this.name =name;
}
@Override
public String toString() {
returnname;
}
}
/**
*字体大小
*/
public enum Size{
LARGE("大"), SMALL("小");
private String name;
Size(String
name) {
this.name =name;
}
@Override
public String toString() {
returnname;
}
}
/**
*字体抽象类
*/
public abstract class AbstractFont{
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractFont.class);
privateSize size;
privateColor color;
public Size getSize() {
returnsize;
}
public void setSize(Size size) {
this.size =size;
}
public Color getColor() {
returncolor;
}
public void setColor(Color color) {
this.color =color;
}
@Override
public abstract String toString();
/**
*打印当前状态
*/
public void printStatus() {
LOGGER.info("字体当前状态为:\t字体大小:{}\t颜色:{}", getSize(), getColor());
}
}
/**
*字体
*/
public class RegularScript extends AbstractFont{
public RegularScript() {
setColor(Color.BLACK);
setSize(Size.SMALL);
}
@Override
public String toString() {
return "楷体";
}
}
/**
*命令抽象类
*/
public abstract class Command{
public abstract void execute();
public abstract void undo();
public abstract void redo();
@Override
public abstract String toString();
}
/**
*设置字体为大号
*/
public class Enlarge extends Command{
private finalAbstractFont font;
private finalSize oriSize;
public Enlarge(AbstractFont font) {
this.font =font;
oriSize= font.getSize();
}
@Override
public void execute() {
font.setSize(Size.LARGE);
}
@Override
public void undo() {
font.setSize(oriSize);
}
@Override
public void redo() {
execute();
}
@Override
public String toString() {
return "设置字体为大号";
}
}
/**
*设置字体颜色为红色的命令
*/
public class Rubify extends Command{
private finalAbstractFont font;
private finalColor oriColor;
public Rubify(AbstractFont font) {
this.font =font;
oriColor= font.getColor();
}
@Override
public void execute() {
font.setColor(Color.RED);
}
@Override
public void undo() {
font.setColor(oriColor);
}
@Override
public void redo() {
execute();
}
@Override
public String toString() {
return "设置字体为红色";
}
}
/**
*打字员
*/
public final class Typist{
private static final Logger LOGGER = LoggerFactory.getLogger(Typist.class);
private Deque
private Deque
public void cast(Command command, AbstractFont font) {
LOGGER.info("{}正在处理字体,命令为:{},处理的字体为:{}", this, command, font);
command.execute();
undoStack.offerLast(command);
}
public void undo() {
if (!undoStack.isEmpty()) {
Command previousCommand= undoStack.pollLast();
redoStack.offerLast(previousCommand);
LOGGER.info("{}正在进行撤销操作,命令为:{}", this, previousCommand);
previousCommand.undo();
}else{
LOGGER.info("没有可以撤销的操作了");
}
}
public void redo() {
if (!redoStack.isEmpty()) {
Command previousCommand= redoStack.pollLast();
undoStack.offerLast(previousCommand);
LOGGER.info("{}正在进行重做操作,命令为:{}", this, previousCommand);
previousCommand.redo();
}else{
LOGGER.info("没有可以重做的操作了");
}
}
@Override
public String toString() {
return "打字员";
}
}
/**
* Command
*/
public class Application{
public static void main(String[] args) {
Typist sizeTypist= newTypist();
Typist colorTypist= newTypist();
RegularScript font= newRegularScript();
Command rubify= newRubify(font);
Command enlarge= newEnlarge(font);
font.printStatus();
// 设置字体颜色
colorTypist.cast(rubify, font);
font.printStatus();
// 设置字体大小
sizeTypist.cast(enlarge, font);
font.printStatus();
// 撤销颜色更改
colorTypist.undo();
font.printStatus();
colorTypist.undo();
// 撤销大小更改
sizeTypist.undo();
font.printStatus();
sizeTypist.undo();
// 字体颜色重做
colorTypist.redo();
font.printStatus();
colorTypist.redo();
// 大小重做
sizeTypist.redo();
font.printStatus();
sizeTypist.redo();
}
}