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();
}
}
Interface Segregation Principle
最简单常用的模式,不展开了
public Sun {
private static final Sun sun = new Sun();
public static Sun getInstance() {
return sun;
}
public void light() {
System.out.println("太阳发光");
}
}
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 productFood(Class 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();
}
}
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 productFood(Class cls);
}
public class BreadFactory extends FoodFactory {
public T productFood(Class 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();
}
}
对于业务模型的业务动作模板化;基本方法在子类中实现,模板方法在父类中调度
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();
}
}
建造者模式(Builder Pattern)也叫做生成器模式
public abstract class CarModel {
/**
* 装备顺序
*/
private ArrayList sequence = new ArrayList();
/**
* 发动
*/
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 sequence) {
this.sequence = sequence;
}
}
public abstract class CarBuilder {
// 顺序
public abstract void setSequence(ArrayList 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 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 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 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();
}
}
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面向切面编程)
缺点:
public class Thing implements Cloneable {
private ArrayList arrayList = new ArrayList();
@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 getValue() {
return this.arrayList;
}
}
public class Test {
public static void main(String[] args) {
Thing t = new Thing();
// 仅深拷贝当前对象,内部的List为浅拷贝
Thing clone = t.clone();
}
}
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();
}
}
缺点:
public class Decoratee {
public Decoratee() {
whatIHave = new ArrayList<>();
whatIHave.add("锦");
whatIHave();
}
private List 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();
}
}
缺点:
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();
}
}
缺点:
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());
}
}
public interface Iterator {
//遍历到下一个元素
public Object next();
//是否已经遍历到尾部
public boolean hasNext();
//删除当前指向的元素
public boolean remove();
}
Java本身已经提供了很强大的基础API,所以我们基本不需要自己再去写这些
/**
* 被观察者
*/
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 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();
}
}
门面模式(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类定义好后,出现问题的话,唯一能做的一件事就是修改门面代码,这会影响所有人,所以很多时候,在门面对于一部分场景正确,但对一部分场景错误时,经常会开“后门”,再开一扇门,搞的次数多了,越来越复杂,越来越难以理解,越来越难维护。
门面如果能让优秀的人定义好的话,可以减少低水平开发人员对系统冲击,最差就是将其实现的代码重写,不会对整体造成影响;正如缺点中讲的,也是双刃剑,慎之又慎。
备忘录就像我们处理数据库事务一样,可以对操作进行回滚
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;
}
}
应用场景
注意点
大话西游中,周星驰在洞口月光下对着月光宝盒大喊“波若波若蜜”,来回穿梭时光回去救白晶晶,结果频繁操作,旁边的观察者吴孟达一脸懵逼,然后程序不稳定,穿越回了500年前...
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();
}
}
}
优点:
缺点:
-- 有缘登山,寒山不寒