6大设计原则:
1. 单一职责原则
2. 里氏替换原则
public interface A {
void method();
}
public class AImpl implements A {
public void method() {
}
public void methodSub() {
}
}
// 使用方
public class Test {
public static void main(String[] args) {
AImpl obj = new AImpl();
// 外部调用时obj对象的类不能替换成A,则违反了LSP
obj.methodSub();
}
}
3. 依赖倒置原则
-
模块间的依赖通过抽象发生(接口或抽象类)
-
接口或抽象类不依赖于实现类
-
实现类依赖接口或抽象类
4. 接口隔离原则
Interface Segregation Principle
-
Clients should not be forced to depend upon interfaces that they don't use. (客户端不应该依赖它不需要的接口。)
-
The dependency of one class to another one should depend on the smallest possible interface. (类间的依赖关系应该建立在最小的接口上。)
-
接口职能单一,服务定制,设计有度
-
接口要高内聚,减少交互
5. 迪米特法则
6. 开闭原则
28大设计模式
1. 单例模式
最简单常用的模式,不展开了
public Sun {
private static final Sun sun = new Sun();
public static Sun getInstance() {
return sun;
}
public void light() {
System.out.println("太阳发光");
}
}
2. 工厂方法模式
public interface Food {
void name();
}
public class Bread implements Food {
@Override
public void name() {
System.out.println("我是面包");
}
}
public class Cookie implements Food {
@Override
public void name() {
System.out.println("我是饼干");
}
}
public class FoodFactory {
public <T extends Food> T productFood(Class<T> cls) {
T t = null;
try {
t = cls.newInstance();
} catch (Exception e) {
System.out.println("我不会生产这个");
e.printStackTrace();
}
return t;
}
public static void main(String[] args) {
FoodFactory factory = new FoodFactory();
Bread bread = factory.productFood(Bread.class);
bread.name();
Cookie cookie = factory.productFood(Cookie.class);
cookie.name();
}
}
3. 抽象工厂模式
Provide an interface for creating families of related or dependent objects without specifying their concrete classes.(为创建一组相关或相互依赖的对象提供一个接口,而且无须指定它们 的具体类。)
public interface Food {
void name();
}
public class SweetBread implements Food {
@Override
public void name() {
System.out.println("我是甜面包");
}
}
public class SaltyBread implements Food {
@Override
public void name() {
System.out.println("我是咸面包");
}
}
public class Cookie implements Food {
@Override
public void name() {
System.out.println("我是饼干");
}
}
public abstract class FoodFactory {
<T extends Bread> T productFood(Class<T> cls);
}
public class BreadFactory extends FoodFactory {
public <T extends Bread> T productFood(Class<T> cls) {
T t = null;
try {
t = cls.newInstance();
} catch (Exception e) {
System.out.println("我不会生产这个");
e.printStackTrace();
}
return t;
}
public static void main(String[] args) {
FoodFactory factory = new BreadFactory();
SweetBread bread1 = factory.productFood(SweetBread.class);
bread1.name();
SaltyBread bread2 = factory.productFood(SaltyBread.class);
cookie2.name();
}
}
4. 模板方法模式
对于业务模型的业务动作模板化;基本方法在子类中实现,模板方法在父类中调度
public abstract class Car {
public abstract void start();
public abstract void drive();
public abstract void stop();
public void run() {
start();
drive();
stop();
}
}
public class HongQiCar extends Car {
@Override
public void start() {
System.out.println("红旗车启动");
}
@Override
public void drive() {
System.out.println("红旗车行驶");
}
@Override
public void stop() {
System.out.println("红旗车停止");
}
public static void main(String[] args) {
Car car = new HongQiCar();
car.run();
}
}
5. 建造者模式
建造者模式(Builder Pattern)也叫做生成器模式
public abstract class CarModel {
/**
* 装备顺序
*/
private ArrayList<String> sequence = new ArrayList<String>();
/**
* 发动
*/
public abstract void engine();
/**
* 喇叭
*/
public abstract void horn();
/**
* 挂挡
*/
public abstract void gearbox();
/**
* 加油
*/
public abstract void gas();
/**
* 停车
*/
public abstract void stop();
/**
* 介绍
*/
public void drive() {
for (String step : sequence) {
if ("engine".equals(step)) {
engine();
} else if ("horn".equals(step)) {
horn();
} else if ("gearbox".equals(step)) {
gearbox();
} else if ("gas".equals(step)) {
gas();
} else if ("stop".equals(step)) {
stop();
}
}
}
/**
* 设置装配顺序
*/
public void setSequence(ArrayList<String> sequence) {
this.sequence = sequence;
}
}
public abstract class CarBuilder {
// 顺序
public abstract void setSequence(ArrayList<String> sequence);
// 设置顺序后,获取模型
public abstract CarModel getCarModel();
}
public class HongqiCarModel extends CarModel {
@Override
public void engine() {
System.out.println("红旗车无钥匙启动汽车");
}
@Override
public void horn() {
System.out.println("红旗车按响喇叭");
}
@Override
public void gearbox() {
System.out.println("红旗车挂前进挡");
}
@Override
public void gas() {
System.out.println("红旗车加速");
}
@Override
public void stop() {
System.out.println("红旗车刹车停车");
}
}
public class HoneqiCarBuilder extends CarBuilder {
private HongqiCarModel carModel = new HongqiCarModel();
@Override
public void setSequence(ArrayList<String> sequence) {
carModel.setSequence(sequence);
}
@Override
public CarModel getCarModel() {
return carModel;
}
public static void main(String[] args) {
}
}
public class HongqiDirector {
private HoneqiCarBuilder honeqiCarBuilder = new HoneqiCarBuilder();
/**
* A型号车需要先鸣笛才能开
* @return
*/
public HongqiCarModel getHongqiModelA() {
ArrayList<String> sequence = new ArrayList<>();
sequence.add("horn");
sequence.add("engine");
sequence.add("gearbox");
sequence.add("gas");
sequence.add("stop");
HoneqiCarBuilder builder = new HoneqiCarBuilder();
builder.setSequence(sequence);
return (HongqiCarModel) builder.getCarModel();
}
/**
* A型号车不需要先鸣笛能开
* @return
*/
public HongqiCarModel getHongqiModelB() {
ArrayList<String> sequence = new ArrayList<>();
sequence.add("engine");
sequence.add("gearbox");
sequence.add("gas");
sequence.add("stop");
HoneqiCarBuilder builder = new HoneqiCarBuilder();
builder.setSequence(sequence);
return (HongqiCarModel) builder.getCarModel();
}
}
6. 代理模式
- 高扩展性,不侵入实现层的源码
- 职能清晰
缺点:
- 代理在实际项目使用过程中,还是不要下放给所有人,实际经验中,AOP的随意使用,经常造成各种问题,特殊场景下的报错、代码可读性降低(大项目中,新人不知道哪里把数据修改了,代码不易理解,修改引入缺陷,测试不好覆盖场景)
public interface ITask {
void doJob();
}
public class TaskImpl implements ITask {
@Override
public void doJob() {
System.out.println("doing job");
}
}
// 动态代理
public class DynamicProxy implements InvocationHandler {
private Object object;
public DynamicProxy(Object object) {
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before do job...");
Object result = method.invoke(object, args);
System.out.println("after do job...");
return result;
}
}
// 静态代理
public class StaticProxy implements ITask {
private ITask task;
public StaticProxy(final ITask task) {
this.task = task;
}
@Override
public void doJob() {
System.out.println("before do job...");
task.doJob();
System.out.println("after do job...");
}
}
public class TestProxy {
public static void main(String[] args){
ITask task = new TaskImpl();
StaticProxy p1 = new StaticProxy(task);
task.doJob();
System.out.println("********************************");
p1.doJob();
System.out.println("********************************");
ITask dynamic = (ITask)Proxy.newProxyInstance(ITask.class.getClassLoader(), task.getClass().getInterfaces(), new DynamicProxy(task));
dynamic.doJob();
}
}
Java中有JDK动态代理和cglib动态代理,可自行研究;动态代理是非常常见和使用的设计模式,对于业务前后统一的处理都可使用此模式;也叫AOP(Aspect Oriented Programming面向切面编程),还有一些名词:切面 Aspect,切入点 JoinPoint,通知 Advice,织入 Weave;概念一大堆,大家还是要从实际场景去考虑我们引入代理到底带来了什么,失去什么,是否合适当前的场景;从个人浅显的工作经验上来看,AOP下放给开发在业务中使用时,经常是弊大于利,谈虎色变
7. 原型模式
- 对于构造函数消耗的性能非常多且实例化的内容是一致的对象能够大幅提高性能
- 双刃剑:逃避构造函数约束(成也萧何,败也萧何,千万注意此点对业务的影响)
缺点:
- 仅深拷贝本对象(属性如果是对象则为浅拷贝)
- clone和final一山不容二虎,成员变量加final后直接编译报错
public class Thing implements Cloneable {
private ArrayList<String> arrayList = new ArrayList<String>();
@Override
public Thing clone() {
Thing thing = null;
try {
thing = (Thing) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return thing;
}
public void setValue(String value) {
this.arrayList.add(value);
}
public ArrayList<String> getValue() {
return this.arrayList;
}
}
public class Test {
public static void main(String[] args) {
Thing t = new Thing();
// 仅深拷贝当前对象,内部的List为浅拷贝
Thing clone = t.clone();
}
}
8. 中介者模式
9. 命令模式
public abstract class Receiver {
public abstract void doSomething();
}
public class ReceiverImpl1 extends Receiver {
@Override
public void doSomething() {
System.out.println("On my building");
}
}
public class Invoker {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void action() {
this.command.execute();
}
}
public abstract class Command {
public abstract void execute();
}
public class CommandImpl1 extends Command {
private Receiver receiver;
public CommandImpl1(Receiver receiver) {
this.receiver = receiver;
}
public void execute() {
this.receiver.doSomething();
}
}
public class Test {
public static void main(String[] args) {
Invoker invoker = new Invoker();
// 定义接收者
Receiver receiver = new ReceiverImpl1();
// 定义一个发送给接收者的命令
Command command = new CommandImpl1(receiver);
// 把命令交给调用者去执行
invoker.setCommand(command); invoker.action();
}
}
10. 责任链模式
11. 装饰模式
- 装饰类和被装饰类可以独立发展,而不会相互耦合。
- 装饰模式是继承关系的一个替代方案
- 动态扩展类的功能
缺点:
- 不要套太多,套娃太深,复杂度太高,排查和理解耗时
public class Decoratee {
public Decoratee() {
whatIHave = new ArrayList<>();
whatIHave.add("锦");
whatIHave();
}
private List<String> whatIHave;
public void gain(String str) {
whatIHave.add(str);
}
public void whatIHave() {
if(whatIHave.size() == 0) {
System.out.println("我什么都没有!!!");
} else {
System.out.print("我有");
for(String have : whatIHave) {
System.out.print(have+" ");
}
System.out.println();
}
}
}
public class Decorator {
private Decoratee decoratee;
public Decorator(Decoratee decoratee) {
this.decoratee = decoratee;
}
public void decorate() {
decoratee.gain("花");
decoratee.whatIHave();
}
public static void main(String[] args){
Decorator decorator = new Decorator(new Decoratee());
decorator.decorate();
}
}
12. 策略模式
- 策略自由切换,方便横向扩展
- 避免多重条件判断
缺点:
- 策略类数量多时,需要有诸葛亮一样的人来运筹帷幄,复用性也低
- 所有策略都得对外暴露
public interface AttackStrategy {
/**
* 五行法术攻击
*/
void fiveElementsMagicAttack();
}
public class AttackStrategyGold implements AttackStrategy {
@Override
public void fiveElementsMagicAttack() {
System.out.println("使用金系法术攻击");
}
}
public class AttackStrategyWood implements AttackStrategy {
@Override
public void fiveElementsMagicAttack() {
System.out.println("使用木系法术攻击");
}
}
public class AttackStrategyWater implements AttackStrategy {
@Override
public void fiveElementsMagicAttack() {
System.out.println("使用水系法术攻击");
}
}
public class AttackStrategyFire implements AttackStrategy {
@Override
public void fiveElementsMagicAttack() {
System.out.println("使用火系法术攻击");
}
}
public class AttackStrategySoil implements AttackStrategy {
@Override
public void fiveElementsMagicAttack() {
System.out.println("使用土系法术攻击");
}
}
public class Context {
AttackStrategy attackStrategy;
public Context(AttackStrategy attackStrategy) {
this.attackStrategy = attackStrategy;
System.out.println("指挥部制定攻击策略");
}
public AttackStrategy getAttackStrategy() {
return attackStrategy;
}
}
public class Battle {
public static String[] enemy = {"金系敌人", "木系敌人", "水系敌人", "火系敌人", "土系敌人"};
public static void main(String[] args) {
for (int i=0; i<5; i++) {
System.out.println("---------------------------");
attack();
}
}
private static void attack() {
int idx = (int)(Math.random() * 5);
Context headquarters;
System.out.println("我方遭遇:" + enemy[idx]);
switch (enemy[idx]) {
case "金系敌人":
headquarters = new Context(new AttackStrategyFire());
break;
case "木系敌人":
headquarters = new Context(new AttackStrategyGold());
break;
case "水系敌人":
headquarters = new Context(new AttackStrategySoil());
break;
case "火系敌人":
headquarters = new Context(new AttackStrategyWater());
break;
case "土系敌人":
headquarters = new Context(new AttackStrategyWood());
break;
default:
headquarters = new Context(new AttackStrategyGold());
}
headquarters.getAttackStrategy().fiveElementsMagicAttack();
}
}
13. 适配器模式
- 适配器模式可以让两个没有任何关系的类在一起运行,只要适配器这个角色能够搞定 他们就成
- 降低了类的存在感,简化使用
- 提供类的复用和灵活性
缺点:
- 个人人为也不算缺点吧,项目初期不用考虑这个模式,大多在维护阶段去使用,去适配未知的场景(就像在中国是220的电,做的充电器就按220的做,以后去了未知的地区,再考虑做新的,因为电压,插口大小都是未知的)
- 而且是不符合原有设计的时候才会发生,使用此改造也可能代码比较大的改造量
public interface DC5V {
int outDC5v();
}
public class ChargeAdapter extends AC220V implements DC5V {
@Override
public int outDC5v() {
int i = outAC220v();
i = i / 44;
System.out.println("转换成"+i+"V直流电!");
return i;
}
}
public class AC220V {
int outAC220v() {
int v = 220;
System.out.println("输出220v交流电!!!");
return v;
}
}
public class Mobile {
void charge(DC5V charger) {
int i = charger.outDC5v();
System.out.println("charging...");
}
public static void main(String[] args) {
Mobile mobile = new Mobile();
mobile.charge(new ChargeAdapter());
}
}
14. 迭代器模式
public interface Iterator {
//遍历到下一个元素
public Object next();
//是否已经遍历到尾部
public boolean hasNext();
//删除当前指向的元素
public boolean remove();
}
Java本身已经提供了很强大的基础API,所以我们基本不需要自己再去写这些
15. 组合模式
16. 观察者模式
/**
* 被观察者
*/
public interface Observable {
// 增加一个观察者
void addObserver(Observer observer);
// 删除一个观察者
void deleteObserver(Observer observer);
// 既然要观察,我发生改变了他也应该有所动作,通知观察者
void notifyObservers(String context);
}
/**
* 观察者
*/
public interface Observer {
void action(String info);
}
/**
* 具体的被观察对象
*/
public class Student implements Observable {
private String name;
public Student(String name) {
this.name = name;
}
private List<Observer> observers = new ArrayList<>();
@Override
public void addObserver(Observer observer) {
observers.add(observer);
}
@Override
public void deleteObserver(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers(String context) {
for (Observer observer : observers) {
observer.action(context);
}
}
public void quWangBa() {
System.out.println(name + "去网吧");
notifyObservers(name + "去网吧");
}
}
/**
* 具体的建观察者
*/
public class Father implements Observer {
@Override
public void action(String info) {
System.out.println("由于" + info + "被父亲知道,父亲教了他一套军体拳");
}
}
/**
* 具体的观察者
*/
public class Teacher implements Observer {
@Override
public void action(String info) {
System.out.println("由于" + info + "被老师知道,老师要求其写检讨,并通报批评");
}
}
public class Client {
public static void main(String[] args) {
Father father = new Father();
Teacher teacher = new Teacher();
Student student = new Student("张三");
student.addObserver(teacher);
student.addObserver(father);
student.quWangBa();
}
}
17. 门面模式
门面模式(Facade Pattern)也叫做外观模式,是一种比较常用的封装模式,其定义如
下:
Provide a unified interface to a set of interfaces in a subsystem.Facade defines a higher-level
interface that makes the subsystem easier to use.(要求一个子系统的外部与其内部的通信必须通
过一个统一的对象进行。门面模式提供一个高层次的接口,使得子系统更易于使用。)
个人理解门面模式是定义一个统一的规范,不论用什么方式实现,出入的“门面”是固定的,且不暴露门面内部的逻辑
public class Facade {
private Worker worker = new Worker();
public void doSomething() {
// 对外暴露的方法固定,内部的实现目前是工人1去做,后续需要调整可以是其他的工人去做
worker.doSomething();
}
}
public class Worker {
public void doSomething() {
}
}
优点:
1. 减少系统的互相依赖
2. 提高门面内部的灵活性和自主性
3. 提高安全性(这个其实也是减少互相依赖带来的好处,减少了代码的侵入)
缺点:
不符合开闭原则,对修改关闭,对扩展开放,facade类定义好后,出现问题的话,唯一能做的一件事就是修改门面代码,这会影响所有人,所以很多时候,在门面对于一部分场景正确,但对一部分场景错误时,经常会开“后门”,再开一扇门,搞的次数多了,越来越复杂,越来越难以理解,越来越难维护。
门面如果能让优秀的人定义好的话,可以减少低水平开发人员对系统冲击,最差就是将其实现的代码重写,不会对整体造成影响;正如缺点中讲的,也是双刃剑,慎之又慎。
18. 备忘录模式
备忘录就像我们处理数据库事务一样,可以对操作进行回滚
public class Originator {
private String state;
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public Memento createMemento() {
return new Memento(this.state);
}
public void restoreMemento(Memento memento) {
this.state = memento.getState();
}
public static void main(String[] args) {
Caretaker caretaker = new Caretaker();
Originator originator = new Originator();
originator.setState("小明正在写PPT");
System.out.println("老板让小明去接待客户");
System.out.println("小明先记录备忘录");
caretaker.setMemento(originator.createMemento());
originator.setState("小明正在接待客户");
System.out.println("小明接待完客户,继续去写PPT");
originator.restoreMemento(caretaker.getMemento());
System.out.println(originator.getState());
}
}
public class Memento {
private String state;
public Memento(String state) {
this.state = state;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
public class Caretaker {
private Memento memento;
public Memento getMemento() {
return memento;
}
public void setMemento(Memento memento) {
this.memento = memento;
}
}
应用场景
- 保存恢复数据的场景
- 数据旁路处理的场景
- 实际应用过程大多会进行变形,所以其实没有很标准的落地形式,算一种抽象定义
注意点
- 备忘录的生命周期管理,防止出现内存泄漏,业务脏数据等问题
- 备忘录创建的性能问题,大量且频繁创建销毁,要考虑内存和CPU的消耗
- 单纯的整对象备份,可以用Cloneable代替Memento类
大话西游中,周星驰在洞口月光下对着月光宝盒大喊“波若波若蜜”,来回穿梭时光回去救白晶晶,结果频繁操作,旁边的观察者吴孟达一脸懵逼,然后程序不稳定,穿越回了500年前...
18. 访问者模式
public abstract class Element {
// 定义业务逻辑
public abstract void doSomething();
// 允许谁来访问
public abstract void accept(IVisitor visitor);
}
public class ConcreteElement1 extends Element {
// 完善业务逻辑
public void doSomething() {
// 业务处理
}
// 允许那个访问者访问
public void accept(IVisitor visitor) {
visitor.visit(this);
}
}
public class ConcreteElement2 extends Element {
// 完善业务逻辑
public void doSomething() {
// 业务处理
}
// 允许那个访问者访问
public void accept(IVisitor visitor) {
visitor.visit(this);
}
}
public interface IVisitor {
// 可以访问哪些对象
void visit(ConcreteElement1 el1);
void visit(ConcreteElement2 el2);
}
public class Visitor implements IVisitor {
// 访问el1元素
public void visit(ConcreteElement1 el1) {
el1.doSomething();
}
// 访问el2元素
public void visit(ConcreteElement2 el2) {
el2.doSomething();
}
}
public class Client {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
// 获得元素对象
Element el = createElement();
// 接受访问者访问
el.accept(new Visitor());
}
}
public static Element createElement() {
Random rand = new Random();
if (rand.nextInt(100) > 50) {
return new ConcreteElement1();
} else {
return new ConcreteElement2();
}
}
}
优点:
- 符合单一职责原则
- 可扩展性
- 灵活性
缺点:
- 违背依赖倒置原则(访问者依赖具体元素,而非抽象元素),很多时候我们在设计开发时会说,不是抽象的,那我抽象不就行了,但除了从代码上是抽象类或者接口,业务上真的是抽象的吗?我们口中的抽象真的是抽象吗?
- 维护麻烦,对于元素增加、修改、删除都是麻烦事
19. 状态模式
Allow an object to alter its behavior when its internal state changes.The object will appear to change its class.(当一个对象内在状态改变时允许其改变行为,这个对象看起来像改变了其类。)
优点:
- 结构清晰
- 类符合单一职责和开闭原则,每个状态一个子类
缺点:
- 有很多状态会扩展出很多子类
public abstract class LiftState {
// 定义一个环境角色,也就是封装状态的变化引起的功能变化
protected Context context;
public void setContext(Context _context) {
this.context = _context;
}
// 电梯开门
public abstract void open();
// 电梯关门
public abstract void close();
// 电梯运行
public abstract void run();
// 电梯停止
public abstract void stop();
}
public class OpenningState extends LiftState {
@Override
public void open() {
System.out.println("ACTION:电梯开门...");
}
@Override
public void close() {
// 状态修改
super.context.setLiftState(Context.CLOSEING_STATE);
// 动作委托为CloseState来执行
super.context.getLiftState().close();
}
@Override
public void run() {
// 无此动作
System.out.println("ERROR:开门状态不能运行");
}
@Override
public void stop() {
System.out.println("NO ACTION:原本就停着");
}
}
public class ClosingState extends LiftState {
@Override
public void close() {
System.out.println("ACTION:电梯门关闭...");
}
@Override
public void open() {
super.context.setLiftState(Context.OPENNING_STATE);
// 置为敞门状态
super.context.getLiftState().open();
}
@Override
public void run() {
super.context.setLiftState(Context.RUNNING_STATE);
// 设置为运行状态
super.context.getLiftState().run();
}
@Override
public void stop() {
super.context.setLiftState(Context.STOPPING_STATE);
// 设置为停止状态
super.context.getLiftState().stop();
}
}
public class RunningState extends LiftState {
@Override
public void close() {
// do nothing
System.out.println("NO ACTION:运行时电梯门肯定是关闭的");
}
@Override
public void open() {
// do nothing
System.out.println("ERROR:运行时不能开门");
}
@Override
public void run() {
System.out.println("ACTION:电梯运行...");
}
@Override
public void stop() {
super.context.setLiftState(Context.STOPPING_STATE);
// 环境设置为停止状态
super.context.getLiftState().stop();
}
}
public class StoppingState extends LiftState {
@Override
public void close() {
// do nothing;
System.out.println("NO ACTION:停止时门是关着的");
}
@Override
public void open() {
super.context.setLiftState(Context.OPENNING_STATE);
super.context.getLiftState().open();
}
@Override
public void run() {
super.context.setLiftState(Context.RUNNING_STATE);
super.context.getLiftState().run();
}
@Override
public void stop() {
System.out.println("ACTION:电梯停止了...");
}
}
public class Context {
// 定义出所有的电梯状态
public final static OpenningState OPENNING_STATE = new OpenningState();
public final static ClosingState CLOSEING_STATE = new ClosingState();
public final static RunningState RUNNING_STATE = new RunningState();
public final static StoppingState STOPPING_STATE = new StoppingState();
// 定义一个当前电梯状态,默认电梯是停止的
private LiftState liftState;
public LiftState getLiftState() {
return liftState;
}
public void setLiftState(LiftState liftState) {
this.liftState = liftState;
// 把当前的环境通知到各个实现类中
this.liftState.setContext(this);
}
public void open() {
this.liftState.open();
}
public void close() {
this.liftState.close();
}
public void run() {
this.liftState.run();
}
public void stop() {
this.liftState.stop();
}
public static void main(String[] args) {
Context ctx = new Context();
// 给一个初始状态
ctx.setLiftState(STOPPING_STATE);
ctx.open();
ctx.close();
ctx.run();
ctx.stop();
}
}
状态模式的实际应用场景其实很多,但是现实项目中终究一言难尽,设计模式是好的设计模式,但是最后在落地中,大家口中的shishan代码大部分由于业务状态引起,例如订单状态,各种券的状态等等,业务设计上没有完善的状态机,需求又经常调整场景破坏状态机,状态不由单一字段控制(当A表的a字段=1,B表的b字段=2时需要业务动作x),对于重大项目项目管理和测试又只允许增量修改,导致if写的到处都是,没人知道完整状态机,新人老人避之不及,吐槽程序shishan,这种情况都是大家一起造成的;希望大家在工作中能够遇到完善需求,完善设计,高效扩展,规范开发的项目,能离shishan远一些
-- 有缘登山,寒山不寒