设计模式
设计模式概述
- 设计模式是什么?
- 是软件设计中常见问题的典型解决方案。 每个模式就像一张蓝图, 你可以通过对其进行定制来解决代码中的特定设计问题。
- 通俗点讲就是专治程序常见病
- 设计模式优势
- 对常见问题的解决方案进行总结, 可以达到快速解决问题的作用, 很多人都跳过的坑, 避坑指南.
- 方便软件工程师交流, 别人一说, 就知道怎么回事
- 什么时候使用
- 程序演变过程中有稳定的部分, 也有变化的部分. 如果程序一直不变或者一直都在变化就不适合使用设计模式.
设计模式的分类
- 创建型模式: 提供创建对象的机制,使你编写的代码更灵活, 复用性更强.
- 结构型模式: 介绍如何将对象和类组装成较大的结构, 并同时保持结构的灵活和高效。
- 行为模式: 负责对象间的高效沟通和职责委派。
设计模式详细介绍
- 创建型模式
-
单例模式: 保证一个类只有一个实例, 并且提供一个访问该实例的全局访问点. 全局共享这一个实例.
-
饿汉式
/** * 饿汉式单例模式 */ public class Singleton { // 构造器私有 private Singleton() {} // 类加载时, 立即加载这个对象, 没有延时加载优势 private static Singleton INSTANCE= new Singleton(); // 方法没有同步 调用效率高 public static Singleton getInstance() { return INSTANCE; } }
-
懒汉式
/** * 懒汉式单例模式 */ class LazySingleton { private LazySingleton(){} private static LazySingleton INSTANCE; // 并发效率低 public static synchronized LazySingleton getInstance() throws InterruptedException { if (INSTANCE== null) { INSTANCE= new LazySingleton(); } return INSTANCE; } }
-
静态内部类
/** * 静态内部类单例模式 */ class innerStaticSingleton { private innerStaticSingleton() {} private static class innerStaticSingletonClass { private static final innerStaticSingleton INSTANCE = new innerStaticSingleton(); } public static innerStaticSingleton getInstance() { return innerStaticSingletonClass.INSTANCE; } }
-
-
简单工厂模式: 也叫静态工厂模式, 一般使用静态方法, 通过接收的参数的不同来返回不同的对象实例.
-
产品接口
public interface Car { void run(); }
-
实现类-1
public class BYD implements Car { @Override public void run() { System.out.println("比亚迪在路上跑"); } }
-
实现类-2
public class GL implements Car { @Override public void run() { System.out.println("吉利车在路上跑"); } }
-
简单工厂
public class CarSimpleFactory { public static Car createCar(String name) { if ("比亚迪".equals(name)) { return new BYD(); } else if ("吉利".equals(name)) { return new GL(); } else { return null; } } }
-
客户端生产产品
public class Client { public static void main(String[] args) throws InterruptedException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { Car BYD = CarSimpleFactory.createCar("比亚迪"); Car GL = CarSimpleFactory.createCar("吉利"); BYD.run(); GL.run(); } } // outPut 比亚迪在路上跑 吉利车在路上跑
-
-
工厂方法模式: 在父类中提供一个创建对象的方法, 允许子类决定实例化对象的类型。
UML图
使用场景: 无法预知对象确切类别及其依赖关系时, 希望用户能扩展你软件库或框架的内部组件,复用现有对象来节省系统资源.-
产品接口
-
创建对象的父类
public interface CarMethodFactory { Car createCar(); }
-
工厂方法-1
public class GLFactory implements CarMethodFactory { @Override public Car createCar() { return new GL(); } }
-
工厂方法-2
public class BYDFactory implements CarMethodFactory { @Override public Car createCar() { return new BYD(); } }
-
客户端调用
public class Client { public static void main(String[] args) throws InterruptedException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { new BYDFactory().createCar().run(); new GLFactory().createCar().run(); } } // output 比亚迪在路上跑 吉利车在路上跑
-
-
抽象方法: 创建一系列相关的对象, 而无需指定其具体类。
-
产品部件接口-1
public interface Button { void paint(); }
1.1 产品部件实现-1
public class MacOSButton implements Button { @Override public void paint() { System.out.println("创建了Mac版的按钮"); } }
1.2 产品部件实现-2
public class WindowsButton implements Button { @Override public void paint() { System.out.println("创建了windows版的按钮"); } }
-
产品部件接口-2
public interface CheckBox { void paint(); }
2.1 产品部件实现-1
public class MacOSCheckBox implements CheckBox { @Override public void paint() { System.out.println("创建了Mac版的复选框"); } }
2.2 产品部件实现-2
public class WindowsCheckBox implements CheckBox { @Override public void paint() { System.out.println("创建了Windows版的复选框"); } }
-
产品接口
public interface GUI_Factory { Button buttons(); CheckBox checkBoxs(); }
-
产品接口实现-1
public class MacOSFactory implements GUI_Factory { @Override public Button buttons() { return new MacOSButton(); } @Override public CheckBox checkBoxs() { return new MacOSCheckBox(); } }
-
产品接口实现-2
public class WindowsFactory implements GUI_Factory { @Override public Button buttons() { return new WindowsButton(); } @Override public CheckBox checkBoxs() { return new WindowsCheckBox(); } }
-
通过Application进行封装
public class Application { private Button button; private CheckBox checkBox; public Application(GUI_Factory gui_factory) { button = gui_factory.buttons(); checkBox = gui_factory.checkBoxs(); } public void paint () { button.paint(); checkBox.paint(); } }
-
客户端调用
public class DemoClient { private static Application configApplication () { Application application; GUI_Factory gui_factory; String osName = System.getProperty("os.name"); if (osName.contains("mac")) { gui_factory = new MacOSFactory(); } else { gui_factory = new WindowsFactory(); } application = new Application(gui_factory); return application; } public static void main(String[] args) { Application application = DemoClient.configApplication(); application.paint(); } }
-
-
建造者模式: 能够分步骤创建复杂对象。 该模式允许你使用相同的创建代码生成不同类型和形式的对象。
-
通用建造者接口
/** * 该接口列出创建一辆车所有的步骤 */ public interface Builder { // 设置汽车的类型 void setCarType(CarType type); // 汽车是几座的 void setSeat(int seat); // 引擎 void setEngine(Engine engine); // 广播 void setTransmission(Transmission transmission); // 行车电脑 void setTripComouter(TripComputer tripComputer); // GPS导航 void setGPSNavigation(GPSNavigator gpsNavigator); }
-
汽车建造者
/** * 实际的builders 实现定义好的通用接口 */ public class CarBuilder implements Builder { private CarType type; private int seat; private Engine engine; private Transmission transmission; private TripComputer tripComputer; private GPSNavigator gpsNavigator; public Car getResult() { return new Car(type, seat, engine, transmission, tripComputer, gpsNavigator); } @Override public void setCarType(CarType type) { this.type = type; } @Override public void setSeat(int seat) { this.seat = seat; } @Override public void setEngine(Engine engine) { this.engine = engine; } @Override public void setTransmission(Transmission transmission) { this.transmission = transmission; } @Override public void setTripComouter(TripComputer tripComputer) { this.tripComputer = tripComputer; } @Override public void setGPSNavigation(GPSNavigator gpsNavigator) { this.gpsNavigator = gpsNavigator; } }
-
定制汽车构建者
/** * 建造者模式可以手动定制创建car */ public class CarManualBuilder implements Builder { private CarType type; private int seat; private Engine engine; private Transmission transmission; private TripComputer tripComputer; private GPSNavigator gpsNavigator; @Override public void setCarType(CarType type) { this.type = type; } @Override public void setSeat(int seat) { this.seat = seat; } @Override public void setEngine(Engine engine) { this.engine = engine; } @Override public void setTransmission(Transmission transmission) { this.transmission = transmission; } @Override public void setTripComouter(TripComputer tripComputer) { this.tripComputer = tripComputer; } @Override public void setGPSNavigation(GPSNavigator gpsNavigator) { this.gpsNavigator = gpsNavigator; } public Manual getResult() { return new Manual(type, seat, engine, transmission, tripComputer, gpsNavigator); } }
-
汽车产品
/** * 要创建的汽车产品 */ public class Car { private final CarType carType; private final int seats; private final Engine engine; private final Transmission transmission; private final TripComputer tripComputer; private final GPSNavigator gpsNavigator; private double fuel = 0; public double getFuel() { return fuel; } public void setFuel(double fuel) { this.fuel = fuel; } public Car(CarType carType, int seats, Engine engine, Transmission transmission, TripComputer tripComputer, GPSNavigator gpsNavigator) { this.carType = carType; this.seats = seats; this.engine = engine; this.transmission = transmission; this.tripComputer = tripComputer; if (this.tripComputer != null) { this.tripComputer.setCar(this); } this.gpsNavigator = gpsNavigator; } public CarType getCarType() { return carType; } public int getSeats() { return seats; } public Engine getEngine() { return engine; } public Transmission getTransmission() { return transmission; } public TripComputer getTripComputer() { return tripComputer; } public GPSNavigator getGpsNavigator() { return gpsNavigator; } }
-
定制产品
/** * 定制产品 */ public class Manual { private final CarType carType; private final int seats; private final Engine engine; private final Transmission transmission; private final TripComputer tripComputer; private final GPSNavigator gpsNavigator; public Manual(CarType carType, int seats, Engine engine, Transmission transmission, TripComputer tripComputer, GPSNavigator gpsNavigator) { this.carType = carType; this.seats = seats; this.engine = engine; this.transmission = transmission; this.tripComputer = tripComputer; this.gpsNavigator = gpsNavigator; } public String print() { String info = ""; info += "Type of car: " + carType + "\n"; info += "Count of seats: " + seats + "\n"; info += "Engine: volume - " + engine.getVolume() + "; mileage - " + engine.getMileage() + "\n"; info += "Transmission: " + transmission + "\n"; if (this.tripComputer != null) { info += "Trip Computer: Functional" + "\n"; } else { info += "Trip Computer: N/A" + "\n"; } if (this.gpsNavigator != null) { info += "GPS Navigator: Functional" + "\n"; } else { info += "GPS Navigator: N/A" + "\n"; } return info; } }
-
汽车类型
/** * 枚举类型来表示汽车的种类 */ public enum CarType { CITY_CAR, SPORTS_CAR, SUV }
-
汽车引擎
/** * 汽车引擎模型 */ public class Engine { private final double volume; private double mileage; private boolean started; public Engine(double volume, double mileage) { this.volume = volume; this.mileage = mileage; } public void on() { started = true; } public void off() { started = false; } public boolean isStarted() { return started; } public void go(double mileage) { if (started) { this.mileage += mileage; } else { System.err.println("Cannot go(), you must start engine first!"); } } public double getVolume() { return volume; } public double getMileage() { return mileage; } }
-
导航
/** * 导航模型 */ public class GPSNavigator { private String route; public GPSNavigator() { this.route = "LK南, 少林大酒店"; } public GPSNavigator(String manualRoute) { this.route = manualRoute; } public String getRoute() { return route; } }
-
广播
public enum Transmission { SINGLE_SPEED, MANUAL, AUTOMATIC, SEMI_AUTOMATIC }
-
行车记录仪
/** * 行车记录仪模型 */ public class TripComputer { private Car car; public void setCar(Car car) { this.car = car; } public void showFuelLevel() { System.out.println("Fuel level: " + car.getFuel()); } public void showStatus() { if (this.car.getEngine().isStarted()) { System.out.println("Car is started"); } else { System.out.println("Car isn't started"); } } }
-
装配者
/** * 装配者 */ public class Director { public void constructSportsCar(Builder builder) { builder.setCarType(CarType.SPORTS_CAR); builder.setSeat(2); builder.setEngine(new Engine(3.0, 0)); builder.setTransmission(Transmission.SEMI_AUTOMATIC); builder.setTripComouter(new TripComputer()); builder.setGPSNavigation(new GPSNavigator()); } public void constructCityCar(Builder builder) { builder.setCarType(CarType.CITY_CAR); builder.setSeat(2); builder.setEngine(new Engine(1.2, 0)); builder.setTransmission(Transmission.AUTOMATIC); builder.setTripComouter(new TripComputer()); builder.setGPSNavigation(new GPSNavigator()); } public void constructSUV(Builder builder) { builder.setCarType(CarType.SUV); builder.setSeat(4); builder.setEngine(new Engine(2.5, 0)); builder.setTransmission(Transmission.MANUAL); builder.setGPSNavigation(new GPSNavigator()); } }
-
客户端
/** * 模拟构建sportsCar和定制car */ public class DemoClient { public static void main(String[] args) { CarBuilder carBuilder = new CarBuilder(); Director director = new Director(); director.constructSportsCar(carBuilder); Car car = carBuilder.getResult(); System.out.println("getResult:" + car.getCarType()); CarManualBuilder manualBuilder = new CarManualBuilder(); director.constructSportsCar(manualBuilder); Manual manuCar = manualBuilder.getResult(); System.out.println("\nCar manual built:\n" + manuCar.print()); } } // output getResult:SPORTS_CAR Car manual built: Type of car: SPORTS_CAR Count of seats: 2 Engine: volume - 3.0; mileage - 0.0 Transmission: SEMI_AUTOMATIC Trip Computer: Functional GPS Navigator: Functional
-
-
原型模式: 能够复制已有对象, 而又无需使代码依赖它们所属的类。
- 深克隆
public class Prototype implements Cloneable { private Integer fieldId; private String fieldName; private Map<String, Double> scores; public Prototype(Integer fieldId, String fieldName, Map<String, Double> scores) { this.fieldId = fieldId; this.fieldName = fieldName; this.scores = scores; } public Integer getFieldId() { return fieldId; } public void setFieldId(Integer fieldId) { this.fieldId = fieldId; } public String getFieldName() { return fieldName; } public void setFieldName(String fieldName) { this.fieldName = fieldName; } public Map<String, Double> getScores() { return scores; } public void setScores(Map<String, Double> scores) { this.scores = scores; } @Override public String toString() { return "Prototype{" + "fieldId=" + fieldId + ", fieldName='" + fieldName + '\'' + ", scores=" + scores + '}'; } @Override protected Object clone() throws CloneNotSupportedException { Prototype filePrototype = null; try { // 下面一行代码实现基本类型的深克隆 filePrototype = (Prototype) super.clone(); // 下面一行代码实现引用类型的深拷贝 filePrototype.scores = (Map<String, Double>) ((HashMap)this.scores).clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return filePrototype; } }
- 深克隆
-
- 结构型模式
-
适配器模式: 使接口不兼容的对象能够相互合作。
-
圆孔
public class RoundHole { private double radius; public RoundHole(double radius) { this.radius = radius; } public double getRadius() { return radius; } public boolean fits(RoundPeg peg) { boolean result; // 圆孔的半径大于园钉的半径才Ok result = (this.getRadius() >= peg.getRadius()); return result; } }
-
圆钉
public class RoundPeg { private double radius; public RoundPeg(double radius) { this.radius = radius; } public double getRadius() { return radius; } public RoundPeg() { } }
-
方钉
public class SquarePeg { private double width; public SquarePeg(double width) { this.width = width; } public double getWidth() { return width; } public double getSquare() { double result; result = Math.pow(this.width, 2); return result; } }
-
方钉到圆孔的适配器
public class SquarePegAdapter extends RoundPeg { private SquarePeg peg; public SquarePegAdapter( SquarePeg peg) { this.peg = peg; } @Override public double getRadius() { double result; result = (Math.sqrt(Math.pow((peg.getWidth() / 2), 2) * 2)); return result; } }
-
客户端测试
public class Demo { public static void main(String[] args) { RoundHole hole = new RoundHole(5); RoundPeg rpeg = new RoundPeg(5); if (hole.fits(rpeg)) { System.out.println("Round peg r5 fits round hole r5."); } SquarePeg smallSqPeg = new SquarePeg(2); SquarePeg largeSqPeg = new SquarePeg(20); SquarePegAdapter smallSqPegAdapter = new SquarePegAdapter(smallSqPeg); SquarePegAdapter largeSqPegAdapter = new SquarePegAdapter(largeSqPeg); if (hole.fits(smallSqPegAdapter)) { System.out.println("Square peg w2 fits round hole r5."); } if (!hole.fits(largeSqPegAdapter)) { System.out.println("Square peg w20 does not fit into round hole r5."); } } }
-
-
代理模式: 能提供真实服务对象的替代品给客户端使用。 代理接收客户端的请求并进行一些处理 (访问控制和缓存等), 然后再将请求传递给服务对象。
UML图
-
定义接口
public interface Star { // 面谈 void talk(); // 卖票 void ticks(); // 唱歌 void sing(); // 收钱 void collectMoney(); }
-
具体实现
public class RealStar implements Star { @Override public void talk() { System.out.println("RealStar面谈"); } @Override public void ticks() { System.out.println("卖票"); } @Override public void sing() { System.out.println("RealStar(周杰伦) 在唱冰雨"); } @Override public void collectMoney() { System.out.println("RealStar开始收钱"); } }
-
定义StarHandler
public class StarHandler implements InvocationHandler { RealStar realStar; public StarHandler(RealStar realStar) { this.realStar = realStar; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object obj = null; if (method.getName().equals("sing")) { obj =method.invoke(realStar, args); } else { System.out.println("都是代理在做事儿"); } return obj; } }
-
客户端调用
public class Demo { public static void main(String[] args) { RealStar realStar = new RealStar(); StarHandler handler = new StarHandler(realStar); Star star = (Star) Proxy.newProxyInstance(Demo.class.getClassLoader(), new Class[]{Star.class}, handler); star.talk(); star.sing(); } } // output 都是代理在做事儿 RealStar(周杰伦) 在唱冰雨
-
-
桥接模式: 可将一个大类或一系列紧密相关的类拆分为抽象和实现两个独立的层次结构, 从而能在开发时分别使用。
-
所有设备的通用接口
/** * 所有设备的通用接口 */ public interface Device { boolean isEnabled(); void enable(); void disable(); int getVolume(); void setVolume(int percent); int getChannel(); void setChannel(int channel); void printStatus(); }
-
实现-1
/** * 收音机 */ public class Radio implements Device { private boolean on = false; private int volume = 30; private int channel = 1; @Override public boolean isEnabled() { return on; } @Override public void enable() { on = true; } @Override public void disable() { on = false; } @Override public int getVolume() { return volume; } @Override public void setVolume(int percent) { if (volume > 100) { this.volume = 100; } else if (volume < 0) { this.volume = 0; } else { this.volume = volume; } } @Override public int getChannel() { return channel; } @Override public void setChannel(int channel) { this.channel = channel; } @Override public void printStatus() { System.out.println("------------------------------------"); System.out.println("| 我是收音机."); System.out.println("| 我的状态是: " + (on ? "开着了" : "关了")); System.out.println("| 当前的音量是 " + volume + "%"); System.out.println("| 当前的频道是 " + channel); System.out.println("------------------------------------\n"); } }
-
实现-2
/** * 电视 */ public class Tv implements Device { private boolean on = false; private int volume = 30; private int channel = 1; @Override public boolean isEnabled() { return on; } @Override public void enable() { on = true; } @Override public void disable() { on = false; } @Override public int getVolume() { return volume; } @Override public void setVolume(int percent) { if (volume > 100) { this.volume = 100; } else if (volume < 0) { this.volume = 0; } else { this.volume = volume; } } @Override public int getChannel() { return channel; } @Override public void setChannel(int channel) { this.channel = channel; } @Override public void printStatus() { System.out.println("------------------------------------"); System.out.println("| 我是电视机."); System.out.println("| 我的状态:" + (on ? "开着了" : "关了")); System.out.println("| 当前的音量是 " + volume + "%"); System.out.println("| 当前的频道是 " + channel); System.out.println("------------------------------------\n"); } }
-
所有远程控制器的通用接口
/** * 所有远程控制器的通用接口 */ public interface Remote { void power(); void volumeDown(); void volumeUp(); void channelDown(); void channelUp(); }
-
实现-1
/** * 基础控制器 */ public class BasicRemote implements Remote { protected Device device; public BasicRemote() { } public BasicRemote(Device device) { this.device = device; } @Override public void power() { System.out.println("Remote: power toggle"); if (device.isEnabled()) { device.disable(); } else { device.enable(); } } @Override public void volumeDown() { System.out.println("Remote: volume down"); device.setVolume(device.getVolume() - 10); } @Override public void volumeUp() { System.out.println("Remote: volume up"); device.setVolume(device.getVolume() + 10); } @Override public void channelDown() { System.out.println("Remote: channel down"); device.setChannel(device.getChannel() - 1); } @Override public void channelUp() { System.out.println("Remote: channel up"); device.setChannel(device.getChannel() + 1); } }
-
实现-2
/** * 高级远程控制器 */ public class AdvancedRemote extends BasicRemote { public AdvancedRemote(Device device) { super.device = device; } public void mute() { System.out.println("Remote: mute"); device.setVolume(0); } }
-
客户端测试
public class Demo { public static void main(String[] args) { testDevice(new Tv()); testDevice(new Radio()); } public static void testDevice(Device device) { System.out.println("Tests with basic remote."); BasicRemote basicRemote = new BasicRemote(device); basicRemote.power(); device.printStatus(); System.out.println("Tests with advanced remote."); AdvancedRemote advancedRemote = new AdvancedRemote(device); advancedRemote.power(); advancedRemote.mute(); device.printStatus(); } } // output Remote: power toggle ------------------------------------ | 我是电视机. | 我现在的状态是开着 | 当前的音量是 30% | 当前的频道是 1 ------------------------------------ Tests with advanced remote. Remote: power toggle Remote: mute ------------------------------------ | 我是电视机. | 我现在的状态是关了 | 当前的音量是 30% | 当前的频道是 1 ------------------------------------ Tests with basic remote. Remote: power toggle ------------------------------------ | 我是收音机. | 我现在的状态是开着了 | 当前的音量是 30% | 当前的频道是 1 ------------------------------------ Tests with advanced remote. Remote: power toggle Remote: mute ------------------------------------ | 我是收音机. | 我现在的状态是关了 | 当前的音量是 30% | 当前的频道是 1 ------------------------------------
-
-
装饰模式: 允许你通过将对象放入包含行为的特殊封装对象中来为原对象绑定新的行为。
-
定义通用接口
// 定义通用接口 public interface ICar { void move(); }
-
具体构建角色(真实对象)
public class Car implements ICar { @Override public void move() { System.out.println("陆地上跑"); } }
-
装饰角色
public class SuperCar implements ICar{ protected ICar car; public SuperCar(ICar car) { this.car = car; } @Override public void move() { car.move(); } }
-
装饰者
public class SuperCarDecorater extends SuperCar { public SuperCarDecorater(ICar car) { super(car); } @Override public void move() { super.move(); fly(); } public void fly() { System.out.println("天上飞"); } }
-
客户端调用
public class Client { public static void main(String[] args) { Car car = new Car(); car.move(); System.out.println("添加新的功能=============="); SuperCarDecorater superCarDecorater = new SuperCarDecorater(car); superCarDecorater.move(); } } // output 陆地上跑 添加新的功能============== 陆地上跑 天上飞
-
-
组合模式: 可以使用它将对象组合成树状结构, 并且能像使用独立对象一样使用它们。
-
抽象构建
public interface AbstractFile { void killVirus(); }
-
叶节点-1
// 叶节点 public class ImageFile implements AbstractFile { private String name; public ImageFile(String name) { this.name = name; } @Override public void killVirus() { System.out.println("图像文件" + name + "进行查杀!"); } }
-
叶节点-2
// 叶节点 public class TextFile implements AbstractFile { private String name; public TextFile(String name) { this.name = name; } @Override public void killVirus() { System.out.println("文本文件" + name + "进行查杀!"); } }
-
叶节点-3
// 叶节点 public class VideoFile implements AbstractFile { private String name; public VideoFile(String name) { this.name = name; } @Override public void killVirus() { System.out.println("视频文件" + name + "进行查杀!"); } }
-
容器
// 容器节点 public class Folder implements AbstractFile { private String name; // 定义容器, 用来存放本容器构建下的子节点 private List<AbstractFile> list = new ArrayList<>(); public Folder(String name) { this.name = name; } public void add(AbstractFile file) { list.add(file); } public void remove(AbstractFile file) { list.remove(file); } public AbstractFile get(int index) { return list.get(index); } @Override public void killVirus() { System.out.println("文件夹" + name + "进行查杀"); for (AbstractFile abstractFile : list) { abstractFile.killVirus(); } } }
-
客户端测试
public class Client { public static void main(String[] args) { Folder f1; AbstractFile f2,f3,f4,f5; f2 = new ImageFile("沙滩.jpg"); f3 = new TextFile("沙滩故事.txt"); f1 = new Folder("我的收藏"); f1.add(f2); f1.add(f3); AbstractFile abstractFile = f1.get(1); abstractFile.killVirus(); f1.killVirus(); } } // output 文本文件沙滩故事.txt进行查杀! 文件夹我的收藏进行查杀 图像文件沙滩.jpg进行查杀! 文本文件沙滩故事.txt进行查杀!
-
-
外观模式: 为程序库、 框架或其他复杂类提供一个简单的接口
-
子系统接口-1
public interface GongShangJu { void checkName(); }
-
子系统实现
ublic class HaiDianGSJ implements GongShangJu { @Override public void checkName() { System.out.println("在海淀工商局检查名字是否有冲突"); } }
-
子系统接口-2
public interface ShuiWuJu { void taxCertificate(); }
-
子系统接口实现
public class HaiDianSWJ implements ShuiWuJu { @Override public void taxCertificate() { System.out.println("在海淀税务局办理税务登记"); } }
-
门面
public class RegisterFacade { public void Register() { HaiDianGSJ haiDianGSJ = new HaiDianGSJ(); HaiDianSWJ haiDianSWJ = new HaiDianSWJ(); haiDianGSJ.checkName(); haiDianSWJ.taxCertificate(); } }
-
客户端
public class Client { public static void main(String[] args) { new RegisterFacade().Register(); } } // output 在海淀工商局检查名字是否有冲突 在海淀税务局办理税务登记
-
-
享元模式: 它摒弃了在每个对象中保存所有数据的方式, 通过共享多个对象所共有的相同状态, 让你能在有限的内存容量中载入更多对象。
-
享元接口
public interface ChessFlyWeight { String getColor(); void display(Coordinate coordinate); }
-
具体实现
public class Chess implements ChessFlyWeight { public Chess(String color) { this.color = color; } private String color; @Override public String getColor() { return color; } @Override public void display(Coordinate coordinate) { System.out.println("棋子的颜色"+color); System.out.println("棋子的位置"+coordinate.getX()+"=========="+coordinate.getY()); } }
-
外部状态类
public class Coordinate { private int x,y; public Coordinate(int x, int y) { this.x = x; this.y = y; } public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; } }
-
享元工厂
public class ChessFlyWeightFactory { private static Map<String, ChessFlyWeight> map = new HashMap<>(); public static ChessFlyWeight getChess(String color) { if(map.get(color)!=null) { return map.get(color); } else { ChessFlyWeight cfw = new Chess(color); map.put(color, cfw); return cfw; } } }
-
客户端
public class Client { public static void main(String[] args) { ChessFlyWeight chess1 = ChessFlyWeightFactory.getChess("黑色"); ChessFlyWeight chess2 = ChessFlyWeightFactory.getChess("黑色"); System.out.println(chess1); System.out.println(chess2); chess1.display(new Coordinate(10,15)); chess2.display(new Coordinate(20,50)); } } // output org.javaboy.lsmf.Chess@191beef org.javaboy.lsmf.Chess@191beef 棋子的颜色黑色 棋子的位置10==========15 棋子的颜色黑色 棋子的位置20==========50
-
-
- 行为模式
- 迭代器模式: 在不暴露集合底层表现形式 (列表、 栈和树等) 的情况下遍历集合中所有的元素。
-
声明迭代器接口
/** * 自定义的迭代器接口 */ public interface MyIterator { void first(); //将游标指向第一个元素 void next(); //将游标指向下一个元素 boolean haxNext(); //判断是否存在下一个元素 boolean isFirst(); boolean isLast(); Object getCurrentObj(); // 获取当前游标的对象 }
-
声明集合接口并描述一个获取迭代器的方法
public class MyConcreteAggregate { private List<Object> list = new ArrayList<>(); public List<Object> getList() { return list; } public void setList(List<Object> list) { this.list = list; } public void addObj(Object obj) { this.list.add(obj); } public void removeObj(Object obj) { this.list.remove(obj); } public MyIterator createIterator() { return new ConcrateIterator(); } private class ConcrateIterator implements MyIterator { private int cursor; @Override public void first() { cursor = 0; } @Override public void next() { if (cursor<list.size()) { cursor++; } } @Override public boolean haxNext() { if (cursor<list.size()) { return true; } return false; } @Override public boolean isFirst() { return cursor==0? true: false; } @Override public boolean isLast() { return cursor==(list.size()-1)? true: false; } @Override public Object getCurrentObj() { return list.get(cursor); } } }
-
客户端
public class Client { public static void main(String[] args) { MyConcreteAggregate mca = new MyConcreteAggregate(); mca.addObj("aaa"); mca.addObj("bbb"); mca.addObj("ccc"); MyIterator iterator = mca.createIterator(); while (iterator.haxNext()) { System.out.println(iterator.getCurrentObj()); iterator.next(); } } } // output aaa bbb ccc
-
- 责任链模式: 将请求沿着处理者链进行发送。 收到请求后, 每个处理者均可对请求进行处理, 或将其传递给链上的下个处理者。
-
声明处理者接口并描述请求处理方法的签名
public abstract class Leader { protected String name; protected Leader nextLeader; public Leader(String name) { this.name = name; } public void setNextLeader(Leader nextLeader) { this.nextLeader = nextLeader; } // 处理请假的核心的业务方法 public abstract void handleLeaveRequest(LeaveRequest lr); }
-
依次创建具体处理者子类并实现其处理方法
public class Director extends Leader { public Director(String name) { super(name); } @Override public void handleLeaveRequest(LeaveRequest lr) { if (lr.getLeaveDays()<3) { System.out.println("请假人:"+lr.getName()+"请假天数:"+lr.getLeaveDays()+"请假原因:"+lr.getReason()); System.out.println("主任:"+name+"批准请假"); } else { if (this.nextLeader!=null) { this.nextLeader.handleLeaveRequest(lr); } } } } public class Manager extends Leader { public Manager(String name) { super(name); } @Override public void handleLeaveRequest(LeaveRequest lr) { if (lr.getLeaveDays()<10) { System.out.println("请假人:"+lr.getName()+"请假天数:"+lr.getLeaveDays()+"请假原因:"+lr.getReason()); System.out.println("经理:"+name+"批准请假"); } else { if (this.nextLeader!=null) { this.nextLeader.handleLeaveRequest(lr); } } } } public class GeneralManager extends Leader { public GeneralManager(String name) { super(name); } @Override public void handleLeaveRequest(LeaveRequest lr) { if (lr.getLeaveDays()<30) { System.out.println("请假人:"+lr.getName()+"请假天数:"+lr.getLeaveDays()+"请假原因:"+lr.getReason()); System.out.println("总经理:"+name+"批准请假"); } else { System.out.println("不批准请假, 要不你离职吧"); } } }
-
封装类
public class LeaveRequest { private String name; private int leaveDays; private String reason; public LeaveRequest(String name, int leaveDays, String reason) { this.name = name; this.leaveDays = leaveDays; this.reason = reason; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getLeaveDays() { return leaveDays; } public void setLeaveDays(int leaveDays) { this.leaveDays = leaveDays; } public String getReason() { return reason; } public void setReason(String reason) { this.reason = reason; } }
-
客户端
public class Client { public static void main(String[] args) { Leader a = new Director("王五"); Leader b = new Manager("张三"); Leader c = new GeneralManager("徐五"); a.setNextLeader(b); b.setNextLeader(c); LeaveRequest lr = new LeaveRequest("Jerry", 12, "想回家看看"); a.handleLeaveRequest(lr); } } // output 请假人:Jerry请假天数:12请假原因:想回家看看 总经理:徐五批准请假
-
- 观察者模式: 定义一种订阅机制, 可在对象事件发生时通知多个 “观察” 该对象的其他对象。
-
声明订阅者接口
public interface Observer { void update(Subject subject); }
-
声明发布者并定义一些接口来在列表中添加和删除订阅对象
public class Subject { protected List<Observer> list = new ArrayList<>(); public void registerObserver(Observer obj) { list.add(obj); } public void removeObserver(Observer obj) { list.remove(obj); } public void notifyAllObservers() { for (Observer observer : list) { observer.update(this); } } }
-
创建具体发布者类
public class ConcrateSubject extends Subject { private int state; public void setState(int state) { this.state = state; this.notifyAllObservers(); } public int getState() { return state; } }
-
在具体订阅者类中实现通知更新的方法
public class Observera implements Observer { private int myState; @Override public void update(Subject subject) { myState = ((ConcrateSubject)subject).getState(); } public int getMyState() { return myState; } public void setMyState(int myState) { this.myState = myState; } }
-
客户端
public class Client { public static void main(String[] args) { ConcrateSubject cs = new ConcrateSubject(); Observera obe1 = new Observera(); Observera obe2 = new Observera(); Observera obe3 = new Observera(); cs.registerObserver(obe1); cs.registerObserver(obe2); cs.registerObserver(obe3); cs.setState(1000); System.out.println(obe1.getMyState()); System.out.println(obe2.getMyState()); System.out.println(obe3.getMyState()); } } // output 1000 1000 1000
-
- 中介者模式: 减少对象之间混乱无序的依赖关系。 该模式会限制对象之间的直接交互, 迫使它们通过一个中介者对象进行合作。
-
声明中介者接口并描述中介者和各种组件之间所需的交流接口
public interface Mediator { void register(String name, Department dept); void command(String dname); }
-
实现具体中介者类
public class GeneralManager implements Mediator { private Map<String, Department> map = new HashMap<>(); @Override public void register(String name, Department dept) { map.put(name,dept); } @Override public void command(String dname) { map.get(dname).selfAction(); } }
-
组件必须保存对于中介者对象的引用
public interface Department { void selfAction(); void outAction(); } public class Development implements Department { private Mediator m; public Development(Mediator m) { this.m = m; m.register("development", this); } @Override public void selfAction() { System.out.println("专心研发, 开发项目"); } @Override public void outAction() { System.out.println("向上汇报, 没钱啦, 需要资金支持"); } } public class Finacial implements Department { private Mediator m; public Finacial(Mediator m) { this.m = m; m.register("finacial", this); } @Override public void selfAction() { System.out.println("数钱"); } @Override public void outAction() { System.out.println("向上汇报, 钱太多啦, 怎么花"); } } public class Market implements Department { private Mediator m; public Market(Mediator m) { this.m = m; m.register("market", this); } @Override public void selfAction() { System.out.println("跑去接项目"); } @Override public void outAction() { System.out.println("向上汇报, 承接的项目太多, 需要资金支持"); m.command("finacial"); } }
-
客户端调用
public class Client { public static void main(String[] args) { Mediator m = new GeneralManager(); Market market = new Market(m); Finacial finacial = new Finacial(m); market.selfAction(); market.outAction(); } } // output 跑去接项目 向上汇报, 承接的项目太多, 需要资金支持 数钱
-
- 模版方法: 在超类中定义了一个算法的框架, 允许子类在不修改结构的情况下重写算法的特定步骤。
-
分析目标算法, 确定能否将其分解为多个步骤
-
创建抽象基类并声明一个模板方法和代表算法步骤的一系列抽象方法
-
为每个算法变体新建一个具体子类, 它必须实现所有的抽象步骤, 也可以重写部分可选步骤。
public abstract class BankTemplateMethod { public void takeNumber() { System.out.println("取号,排队"); } public abstract void transcat(); public void evaluate() { System.out.println("反馈评分"); } // 模版方法 public final void process() { this.takeNumber(); this.transcat(); this.evaluate(); } }
-
客户端调用
public class Client { public static void main(String[] args) { BankTemplateMethod btm = new BankTemplateMethod() { @Override public void transcat() { System.out.println("先给我取10万"); } }; btm.process(); } }
-
- 策略模式: 定义一系列算法, 并将每种算法分别放入独立的类中, 以使算法的对象能够相互替换。
-
从上下文类中找出修改频率较高的算法
-
声明该算法所有变体的通用策略接口
public interface Strategy { double getPrice(Double d); }
-
将算法逐一抽取到各自的类中, 它们都必须实现策略接口
public class NewCustomerFewStrategy implements Strategy { @Override public double getPrice(Double d) { System.out.println("新用户小批量购买, 不打折原价"); return d; } } public class NewCustomerManyStrategy implements Strategy { @Override public double getPrice(Double d) { System.out.println("新用户大批量购买, 打9折"); return d*0.9; } } public class OldCustomerFewStrategy implements Strategy { @Override public double getPrice(Double d) { System.out.println("老用户小批量购买, 打85折"); return d*0.85; } } public class OldCustomerManyStrategy implements Strategy { @Override public double getPrice(Double d) { System.out.println("老用户大批量购买, 打8折"); return d*0.8; } }
-
在上下文类中添加一个成员变量用于保存对于策略对象的引用
public class Context { private Strategy strategy; public Context(Strategy strategy) { this.strategy = strategy; } public void setStrategy(Strategy strategy) { this.strategy = strategy; } public void getPrice(double d) { double price = strategy.getPrice(d); System.out.println(price); } }
-
客户端调用
public class Client { public static void main(String[] args) { Context context = new Context(new OldCustomerFewStrategy()); context.getPrice(1000); } } // output 老用户小批量购买, 打85折 850.0
-
- 状态模式: 在一个对象的内部状态变化时改变其行为, 使其看上去就像改变了自身所属的类一样。
-
确定哪些类是上下文
-
声明状态接口
public interface State { void handle(); }
-
为每个实际状态创建一个继承于状态接口的类
public class FreeState implements State { @Override public void handle() { System.out.println("房间空闲, 没人住"); } } public class BookedState implements State { @Override public void handle() { System.out.println("房间已预定, 没法定啦"); } } public class CheckedState implements State { @Override public void handle() { System.out.println("房间已入住"); } }
-
在上下文类中添加一个状态接口类型的引用成员变量, 以及一个用于修改该成员变量值的公有设置器。
public class Context { private State state; public void setState(State s) { System.out.println("切换状态"); this.state = s; state.handle(); } }
-
客户端调用
public class Client { public static void main(String[] args) { Context cont = new Context(); cont.setState(new FreeState()); } } // output 切换状态 房间空闲, 没人住
-
- 备忘录模式: 在不暴露对象实现细节的情况下保存和恢复对象之前的状态。
-
确定担任原发器角色的类
public class Emp { private String ename; private double salary; private int age; // 设置备忘操作, 并返回备忘录对象 public EmpMemento memento() { return new EmpMemento(this); } // 数据恢复 恢复成备忘录的值 public void reconery(EmpMemento mmt) { this.ename = mmt.getEname(); this.age = mmt.getAge(); this.salary = mmt.getSalary(); } public Emp(String ename, double salary, int age) { this.ename = ename; this.salary = salary; this.age = age; } public String getEname() { return ename; } public void setEname(String ename) { this.ename = ename; } public double getSalary() { return salary; } public void setSalary(double salary) { this.salary = salary; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
-
创建备忘录类
public class EmpMemento { private String ename; private double salary; private int age; public EmpMemento(Emp e) { this.ename = e.getEname(); this.salary = e.getSalary(); this.age = e.getAge(); } public String getEname() { return ename; } public void setEname(String ename) { this.ename = ename; } public double getSalary() { return salary; } public void setSalary(double salary) { this.salary = salary; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
-
创建负责人类
public class CareTaker { private EmpMemento empMemento; public EmpMemento getEmpMemento() { return empMemento; } public void setEmpMemento(EmpMemento empMemento) { this.empMemento = empMemento; } }
-
客户端调用
public class Client { public static void main(String[] args) { CareTaker ck = new CareTaker(); Emp e = new Emp("小强", 2000, 20); System.out.println("第一次打印 姓名:"+e.getEname()+" 年龄:"+e.getAge()+" 工资:"+e.getSalary()); // 设置备忘录点 ck.setEmpMemento(e.memento()); e.setAge(21); e.setEname("强哥"); e.setSalary(8000); System.out.println("第二次打印 姓名:"+e.getEname()+" 年龄:"+e.getAge()+" 工资:"+e.getSalary()); e.reconery(ck.getEmpMemento()); System.out.println("第三次打印 姓名:"+e.getEname()+" 年龄:"+e.getAge()+" 工资:"+e.getSalary()); } } // output 第一次打印 姓名:小强 年龄:20 工资:2000.0 第二次打印 姓名:强哥 年龄:21 工资:8000.0 第三次打印 姓名:小强 年龄:20 工资:2000.0
-
- 迭代器模式: 在不暴露集合底层表现形式 (列表、 栈和树等) 的情况下遍历集合中所有的元素。