SOLID
- 单一职责原则(Single Responsibility Principle,SRP):一个类只负责单一的功能,避免一个类承担过多的职责,从而提高代码的可维护性。
- 开放封闭原则(Open Closed Principle,OCP):软件实体应该对扩展开放,对修改关闭,也就是说,应该通过增加代码而不是修改代码来扩展软件功能,从而提高代码的可维护性和扩展性。
- 里氏替换原则(Liskov Substitution Principle,LSP):子类应该能够替换父类并且不影响程序的正确性,也就是说,子类必须能够完全实现父类的功能,从而提高代码的可扩展性。
- 接口隔离原则(Interface Segregation Principle,ISP):客户端不应该依赖于它不需要的接口,也就是说,应该尽量将接口细化,将不同的功能分离开来,从而提高代码的灵活性和可复用性。
- 依赖倒置原则(Dependency Inversion Principle,DIP):高层模块不应该依赖于低层模块,它们应该依赖于抽象,而不是具体实现,也就是说,应该通过接口或者抽象类来实现模块之间的松耦合,从而提高代码的可维护性和可扩展性。
找出会变的地方,把他们从不变的地方抽离出来(策略模式运用了)
策略模式
将不同的算法或行为封装成独立的策略对象,使它们可以相互替换,从而使系统更加灵活和可扩展。
提高代码的可复用性和可维护性:
- 如果每一个上下文都有该方法,我只需要设置成员变量即可,代码都写在策略中。不同的策略实现不同的方法
- 如果使用继承去获得该策略,那么有的上下文他不需要(有的鸭子不会叫)就需要覆盖
- 如果使用接口,接口可以扩展上下文,但每一个上下文都需要实现同样的方法,代码没有复用
- 拉取出变化的部分,重新建立一个类,并针对接口编程。最后把拉出来的作为成员变量插入
实现过程:
- 策略接口:定义一个抽象策略接口,该接口定义了算法的公共方法。(Fly)
- 具体策略:然后针对每种算法,创建一个具体的策略类,实现该接口。(FlyWings、NoWay)
- 环境类:最后,我们还需要创建一个上下文类,该类包含一个策略成员变量,可以在运行时设置具体的策略。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| interface SortingStrategy { void sort(int[] array); }
class BubbleSort implements SortingStrategy { public void sort(int[] array) { } }
class QuickSort implements SortingStrategy { public void sort(int[] array) { } }
class SortingContext { private SortingStrategy strategy;
public void setStrategy(SortingStrategy strategy) { this.strategy = strategy; }
public void sort(int[] array) { strategy.sort(array); } }
public class Client { public static void main(String[] args) { int[] array = {5, 2, 8, 4, 7}; SortingContext context = new SortingContext();
context.setStrategy(new BubbleSort()); context.sort(array);
context.setStrategy(new QuickSort()); context.sort(array); } }
|
观察者模式
一(主题)对多(观察者);主题变化时需要通知所有人
普通写法:
1 2 3 4 5 6
| { person1.update(); person2.update(); ... }
|
观察者模式:定义一个数组保存全部Observe,观察者在创建时加入主题数组,主题在变化时通知数组全部人
我想要数组中每一个不同的观察者统一调用同一个函数,自然而然想到使用接口。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| interface Subject { void registerObserver(Observer observer); void removeObserver(Observer observer); void notifyObservers(); @Override public void notifyObservers() { for (Observer observer : observers) { observer.update(temperature, humidity, pressure); } } }
interface Observer { void update(float temperature, float humidity, float pressure); }
class CurrentConditionsDisplay implements Observer { private float temperature; private float humidity; private Subject weatherData;
public CurrentConditionsDisplay(Subject weatherData) { this.weatherData = weatherData; weatherData.registerObserver(this); }
|
”趣学架构“中的非主链路的统计、打点,使用观察者模式实现
装饰者模式
装饰器类将对象包装,通过构造函数传递给装饰器;装饰器和被装饰对象需要实现相同的接口,并在实现中进行叠加
1 2 3 4 5 6
| public Decorator(Beverage beverage) { this.beverage = beverage; } public double getCost() { return beverage.getCost() + 0.10; }
|
- 允许你在运行时动态地扩展一个对象的功能。
- 组合而非继承
- 包装原始对象而不影响其原始结构和行为(通过成员变量引用访问到原始对象
has-a的关系
)
- 抽象组件(Component):定义了被装饰者和装饰者的共同接口。
- 具体组件(ConcreteComponent):实现了抽象组件接口,并定义了被装饰者的基本行为。
- 抽象装饰者(Decorator):定义了装饰者的接口,并持有一个被装饰者的引用。
has-a
- 具体装饰者(ConcreteDecorator):实现了抽象装饰者的接口,并向被装饰者添加新的行为和责任。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
| interface Beverage { String getDescription(); double getCost(); }
class Espresso implements Beverage { public String getDescription() { return "Espresso"; }
public double getCost() { return 1.99; } }
abstract class CondimentDecorator implements Beverage { protected Beverage beverage;
public CondimentDecorator(Beverage beverage) { this.beverage = beverage; }
public String getDescription() { return beverage.getDescription(); }
public abstract double getCost(); }
class Milk extends CondimentDecorator { public Milk(Beverage beverage) { super(beverage); }
public String getDescription() { return beverage.getDescription() + ", Milk"; }
public double getCost() { return beverage.getCost() + 0.10; } }
class Mocha extends CondimentDecorator { public Mocha(Beverage beverage) { super(beverage); }
public String getDescription() { return beverage.getDescription() + ", Mocha"; }
public double getCost() { return beverage.getCost() + 0.20; } }
public class Test { public static void main(String[] args) { Beverage beverage = new Espresso(); System.out.println(beverage.getDescription() + " $" + beverage.getCost());
Beverage beverage2 = new Espresso(); beverage2 = new Milk(beverage2); beverage2 = new Mocha(beverage2); System.out.println(beverage2.getDescription() + " $" + beverage2.getCost()); } }
|
Java I/O库
SQL查询通常由多个组件构成,如SELECT、FROM、WHERE、JOIN等。我们可以使用装饰者模式来构建这些组件,并动态地添加额外的功能,例如缓存、日志记录等。 Filter 和 SeqScan的关系
单例模式
全局变量可以提供全局访问,但不能确保唯一。
public的类,但private的构造方法,通过static方法访问private构造方法,构造一个static变量
饿汉模式
全局直接初始化
1 2 3 4 5 6 7 8 9
| public class Singleton { private static Singleton instance = new Singleton(); private Singleton() {} public static Singleton getInstance() { return instance; } }
|
懒汉模式
synchronized
1 2 3 4 5 6 7 8 9 10 11 12
| public class Singleton { private static Singleton instance; private Singleton() {} public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
|
双重检查
volatile:强制立即写入内存,并强制内存读取,而不是缓存
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public class Singleton { private static volatile Singleton instance; private Singleton() {} public static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance = new Singleton(); } } } return instance; } }
|
享元模式
共享对象来减少内存使用和提高性能
字符串池、Integer常量池、数据库连接池
状态模式
当一个对象的行为取决于其状态,并且它必须在运行时根据状态改变其行为时。
订单处理系统:订单有多种状态,如新建订单、已支付、已发货、已收货、已完成等。每种状态下,订单可以执行的操作都可能不同。
以下是一个基于Java的状态模式示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
| interface OrderState { void next(Order order); void prev(Order order); void printStatus(); }
class New implements OrderState { public void next(Order order) { order.setState(new Paid()); }
public void prev(Order order) { System.out.println("The order is in its root state."); }
public void printStatus() { System.out.println("New order."); } }
class Paid implements OrderState { public void next(Order order) { order.setState(new Shipped()); }
public void prev(Order order) { order.setState(new New()); }
public void printStatus() { System.out.println("Order paid."); } }
class Shipped implements OrderState { public void next(Order order) { order.setState(new Delivered()); }
public void prev(Order order) { order.setState(new Paid()); }
public void printStatus() { System.out.println("Order shipped."); } }
class Delivered implements OrderState { public void next(Order order) { System.out.println("This order is already delivered."); }
public void prev(Order order) { order.setState(new Shipped()); }
public void printStatus() { System.out.println("Order delivered."); } }
class Order { private OrderState state;
public Order() { this.state = new New(); }
public void setState(OrderState state) { this.state = state; }
public void next() { state.next(this); }
public void prev() { state.prev(this); }
public void printStatus() { state.printStatus(); } }
public class Main { public static void main(String[] args) { Order order = new Order();
order.printStatus();
order.next(); order.printStatus();
order.next(); order.printStatus();
order.prev(); order.printStatus(); } }
|
在这个例子中,OrderState
接口定义了next
、prev
和printStatus
三个方法,表示订单的下一个状态、上一个状态和打印当前状态。New
、Paid
、Shipped
和Delivered
类分别实现了OrderState
接口,代表了订单的四种状态。Order
类就是所谓的上下文,它持有一个OrderState
对象,代表当前的状态。
模板方法模式
定义一个操作中的骨架,标准化流程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| import com.google.common.base.Stopwatch; import java.util.Arrays; import java.util.concurrent.TimeUnit;
public abstract class ServiceTemplate<T, R> { private final Logger logger = new LoggerImpl();
public R process(T request) { logger.info("start invoke, request=" + request); Stopwatch stopwatch = Stopwatch.createStarted(); try { validParam(request); R response = doProcess(request); long timeCost = stopwatch.elapsed(TimeUnit.MILLISECONDS); logger.info("end invoke, response=" + response + ", costTime=" + timeCost); return response; } catch (Exception e) { logger.error("error invoke, exception:" + Arrays.toString(e.getStackTrace())); return null; } }
protected abstract void validParam(T request);
protected abstract R doProcess(T request); }
|
责任链
责任链:沿着这条链传递请求,直到有一个对象处理它为止,具体由哪个对象处理则在运行时动态决定的情况。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
| abstract class Handler { protected Handler successor;
public void setSuccessor(Handler successor) { this.successor = successor; }
public abstract void handleRequest(double amount); }
class NoDiscountHandler extends Handler { public void handleRequest(double amount) { System.out.println("No discount applied."); } }
class LowDiscountHandler extends Handler { public void handleRequest(double amount) { if (amount < 1000) { System.out.println("Low discount applied. Amount: " + amount); } else if (successor != null) { successor.handleRequest(amount); } } }
class HighDiscountHandler extends Handler { public void handleRequest(double amount) { if (amount >= 1000) { System.out.println("High discount applied. Amount: " + amount); } else if (successor != null) { successor.handleRequest(amount); } } }
class HandlerChain { private Handler head; private Handler tail;
public HandlerChain add(Handler handler) { if (head == null) { head = handler; tail = handler; } else { tail.setSuccessor(handler); tail = handler; } return this; }
public void handleRequest(double amount) { if (head != null) { head.handleRequest(amount); } } }
public class ChainDemo { public static void main(String[] args) { HandlerChain chain = new HandlerChain(); chain.add(new LowDiscountHandler()) .add(new HighDiscountHandler()) .add(new NoDiscountHandler());
chain.handleRequest(500); chain.handleRequest(1500); } }
|
流程引擎
见 ”趣学架构“