设计模式
设计模式参考:https://www.runoob.com/design-pattern/design-pattern-tutorial.html
一、设计模式六大原则
1.单一职责原则,一个类只负责一项职责
2.里氏替换原则,子类可以扩展父类的功能,但不要改变父类原有的功能
3.依赖倒置原则,面向接口编程
4.接口隔离原则,设计接口功能尽量细粒度,最小功能单元
5.迪米特法则,降低耦合(在局部变量里,不要引用新的类)
6.开闭原则,宏观系统上,对扩展开放,对修改关闭
二、简单工厂模式
对象散养,自己需要对象,自己去new,使用者也许不了解这个类,容易出错。
简单工厂模式,向简单工厂类提供的创建对象的接口发起请求获得对象
public class SimpleFactory{ public static final int APPLE = 1; public static final int BANANA= 2; public static Fruit getFruit(int type){ if(APPLE == type){ return new Apple(); }else if(BANANA == type){ return new Banana(); } return null; } }
可将SimpleFactory拆分开为AppleFactory BananaFactory
三、工厂方法模式
简单工厂模式不符合单一职责原则,一个类负责了各类的创建;
不符合开闭原则扩展类型时,需要修改已有代码,没有对修改封闭。
public interface FruitFactory{ public Fruit getFruit(); }
public class AppleFactory implements FruitFactory{ public Fruit getFruit(){ return new Apple(); } } public class BananaFactory implements FruitFactory{ public Fruit getFruit(){ return new Banana(); } }
//使用 FruitFactory fruitFactory = new AppleFactory();
Fruit fruit = fruitFactory.getFruit();
四、抽象工厂模式
创建一个系列的产品:水果与包装两个工厂合并,创建水果时,也创建水果的包装
public interface FruitFactory{ public Fruit getFruit(); public Fruit getBag(); } public class AppleFactory implements FruitFactory{ public Fruit getFruit(){ return new Apple(); } public Fruit getBag(){ return new AppleBag(); } }
//使用 FruitFactory fruitFactory = new AppleFactory(); Fruit fruit = fruitFactory.getFruit(); Bag bag = fruitFactory.getBag();
五、 建造者模式
设置套餐:设置苹果价格,设置香蕉价格,最终创建套餐,根据步骤依次创建,创建过程模板化
public interface Builder{ void buildApple(int price); void buildBanana(int price); FruitMeal getFruitMeal(); } public class HolidayFactory implements Builder{ public Fruit buildApple(){ return new Apple(); } public Fruit buildBanana(){ return new Banana(); } //获取最终套餐 public FruitMeal getFruitMeal(){ } }
//使用 Builder builder = new HolidayFactory(); builder.buildApple(); builder.buildBanana(); FruitMeal meal = builder.getFruitMeal();
六、单例模式
懒汉式:线程不安全
public class Singleton { private static Singleton instance; private Singleton (){} public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
懒汉式:线程安全
public class Singleton { private static Singleton instance; private Singleton (){} public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
懒汉式:线程安全 双检锁/双重校验锁,比方法synchronized高性能
public class Singleton { private volatile static Singleton singleton; private Singleton (){} public static Singleton getSingleton() { if (singleton == null) { synchronized (Singleton.class) { if (singleton == null) { singleton = new Singleton(); } } } return singleton; } }
饿汉式:线程安全
public class Singleton { private static Singleton instance = new Singleton(); private Singleton (){} public static Singleton getInstance() { return instance; } }
以上几种设计模式为创建的设计模式
以下为类与类的关系的设计模式
七、适配器模式
如果香蕉盒不够用了,将苹果包装盒改造后包装香蕉,相当于将苹果包装盒适配香蕉
适配器
public class BananaBagAdapter extend BananaBag{ private AppleBag appleBag; public BananaBagAdapter (AppleBag appleBag){ this.appleBag = appleBag; } @Override public void pack(){ appleBag.pack(); } }
//使用 AppleBag appleBag = new AppleBag(); //把苹果盒适配为香蕉盒 BananaBag bananaBag = new BananaBagAdapter(appleBag);
八、桥接模式
产品属性有两个或两个以上维度,可以将一个属性放到另一个属性的成员变量里(如:大中小、塑料箱子袋子)。若用适配器模式的话,会导致继承混乱。
public abstract class Bag{ private Meterial material; public void setMeterial (Meterial material) { this.material = material; } } //使用 //型号大中小 Bag bag = new BigBag(); //材质 Meterial material = new Plastic(); bag.setMeterial (material);
九、装饰器模式
将类进行装饰
public class BagDecorator implements Bag{ private Bag bag; public BagDecorator(Bag bag){ this.bag = bag; } public void pack(){ this.bag.pack(); } } public class CheckBag extends BagDecorator{ public CheckBag (Bag bag){ super(bag); } public void pack(){ super.pack();//调通用业务方法 checked();//调个性的方法(装饰) } }
//使用 Bag bag = factory.getBag(); bag = new checkBag(bag); bag.pack();
十、代理模式
调用外部接口用代理类去调用
public class ProxyOrder implements OrderService{ //代理外部订单 private OrderService orderService = new OutOrderServiceImpl(); public int saveOrder(){ orderService.saveOrder(); } }
//使用 Ordrservice orderService = new ProxyOrder(); orderService.saveOrder();
十一、组合模式
public abstract class Node(){ private String name; pubilc Node(String name){this.name = name;} public abstract List<Node> getChildren(); } public class DistricNode extends Node{ private List<Node> children = new ArrayList<>(); pubilc DistricNode (String name){super(name);} public void addChild(Node node){ children.add(node); } public List<Node> getChildren(){return children;} }
//使用 DistrictNode root = new DistrictNode("中国"); root.addChild(new DistrictNode("北京")); root.addChild(new DistrictNode("上海"));
十二、外观模式
对于一套流程只开放一个接口
public class OrderFacade{ private PickService pickService; private PackService packService; private SendService sendService; public OrderFacade(){ pickService = new PickService(); packService= new PackService(); sendService= new SendService(); } public void doOrder(){ pickService.doPick(); packService.doPack(); sendService.doSnd(); } }
以上为结构型设计模式,以下为行为性设计模式
十三、模板方法模式
父类包含部分普通方法,与部分抽象方法,使用时子类继承该类,实现抽象方法个性扩展。
public abstract class shooping{ public void submitOrder(){ pay();//抽象方法,子类去个性的实现 seng();//普通方法父类实现 } //普通方法 private void send(){ //具体业务 } //抽象方法子类个性去实现 protected abstract void pay(); }
十四、策略模式
可用于优惠活动(满减、折扣) ;优惠方案实现同一父接口(优惠接口),实现个性的优惠政策,具体流程类的成员变量中加入优惠接口,使用创建流程类通过创建不同的优惠类,来实现不同的策略。
Spring IOC的思想便是策略模式,通过在IOC注入不同的bean实现,来实现注入
代码参考 https://www.cnblogs.com/lewis0077/p/5133812.html
//策略接口 public interface IStrategy { //定义的抽象算法方法 来约束具体的算法实现方法 public void algorithmMethod(); }
// 具体的策略实现 public class ConcreteStrategy implements IStrategy { //具体的算法实现 @Override public void algorithmMethod() { System.out.println("this is ConcreteStrategy method..."); } }
// 具体的策略实现2 public class ConcreteStrategy2 implements IStrategy { //具体的算法实现 @Override public void algorithmMethod() { System.out.println("this is ConcreteStrategy2 method..."); } }
/** * 策略上下文 */ public class StrategyContext { //持有一个策略实现的引用 private IStrategy strategy; //使用构造器注入具体的策略类 public StrategyContext(IStrategy strategy) { this.strategy = strategy; } public void contextMethod(){ //调用策略实现的方法 strategy.algorithmMethod(); } }
//外部客户端 public class Client { public static void main(String[] args) { //1.创建具体测策略实现 IStrategy strategy = new ConcreteStrategy2(); //2.在创建策略上下文的同时,将具体的策略实现对象注入到策略上下文当中 StrategyContext ctx = new StrategyContext(strategy); //3.调用上下文对象的方法来完成对具体策略实现的回调 ctx.contextMethod(); } }
十五、责任链模式
策略模式只能使用一个策略,责任链可将策略放入自身的next中,产生一个策略链,servlet过滤器为责任链,一个一个过滤。
public abstract class MultyDiscount{ // 关联下一个策略 protected MultyDiscount nextMultyDiscount; public MultyDiscount(MultyDiscount nextMultyDiscount){ this.nextMultyDiscount = nextMultyDiscount; } public abstract int calculate(int money); } //具体实现 public class HolidayMultyDiscount extends MultyDiscount{ public HolidayMultyDiscount(MultyDiscount nextMultyDiscount{super(nextMultyDiscount);} public int calculate(int money){ //本策略执行的业务 。。。 if(this.nextMultyDiscount != null){ //执行链上的策略 return this.nextMultyDiscount.calculate(money) } return money } }
//其他实现
public class NewerMultyDiscount extends MultyDiscount{
}
//使用 MultyDiscount multyDiscount = new HolidayMultyDiscount(null); multyDiscount = new NewerMultyDiscount(multyDiscount); multyDiscount = new SecondMultyDiscount(multyDiscount);
十六、观察者模式
创建 Subject 类。
public class Subject { private List<Observer> observers = new ArrayList<Observer>(); private int state; public int getState() { return state; } public void setState(int state) { this.state = state; //通知所有观察者 notifyAllObservers(); } public void attach(Observer observer){ observers.add(observer); } public void notifyAllObservers(){ for (Observer observer : observers) { observer.update(); } } }
创建 Observer 类。
public abstract class Observer { protected Subject subject; public abstract void update(); }
创建实体观察者类。
public class BinaryObserver extends Observer{ public BinaryObserver(Subject subject){ this.subject = subject; this.subject.attach(this); } @Override public void update() { System.out.println( "Binary String: " + Integer.toBinaryString( subject.getState() ) ); } }
public class OctalObserver extends Observer{ public OctalObserver(Subject subject){ this.subject = subject; this.subject.attach(this); } @Override public void update() { System.out.println( "Octal String: " + Integer.toOctalString( subject.getState() ) ); } }
public class HexaObserver extends Observer{ public HexaObserver(Subject subject){ this.subject = subject; this.subject.attach(this); } @Override public void update() { System.out.println( "Hex String: " + Integer.toHexString( subject.getState() ).toUpperCase() ); } }
使用 Subject 和实体观察者对象。
public class ObserverPatternDemo { public static void main(String[] args) { Subject subject = new Subject(); new HexaObserver(subject); new OctalObserver(subject); new BinaryObserver(subject); System.out.println("First state change: 15"); subject.setState(15); System.out.println("Second state change: 10"); subject.setState(10); } }
还可以使用JDK提供的观察者模式的接口(java.util.Observer与java.util.Observable)去实现
java.util.Observer 观察者 update方法
java.util.Observable 被观察者 addObservers、 setChanged、nofityObservers方法 (setChanged、nofityObservers会自动通知观察者,也就是调用updat方法)
十七、命令模式
面向接口,各个命令实现同一个接口,通过实例化不同的接口实现类,来命令。
十八、访问者模式
利用双重分派机制,弥补java多态中的重载识别不出真实的类型(全是父类,真实类型为子类)