设计模式
GOF<设计模式>对设计模式的分类如下图:
创建型模式
创建型模式主要用来创建对象,可以理解为对象的工厂,这种设计模式主要是为了方便后续对象的创建和使用。
结构型模式
将类和对象以一种关系结构的形式组合在一起,这种关系结构可以形象的理解为日常见到的事物关系。比如代理模式:两个对象之间存在的代理关系和艺人和经纪人之间的代理关系一样。结构型模式主要是从现实的结构中获取优点构建代码中同样的结构。
行为型模式
行为型模式可以理解为现实世界中的一种优秀行为模式的借鉴。比如观察者模式:我们对一件事情感兴趣,可以告诉这件事情的负责人,让他告诉这件事情的最新消息。
类模式和对象模式
这个就好理解。类模式就是处理类之间的关系的模式,对象模式就是处理对象之间的关系。
设计模式六大原则:
其中最重要的是开闭原则(open close Principle):这是基础(开闭原则指的是对扩展开放,对修改关闭)。在程序需要扩展的时候不能去修改原本类,而是要扩展原有的代码,实现这一功能,就要可扩展的的实现由子类自己去实现,而定义抽象类去实现公共功能,避免重复的造轮子,所以这一步很重要。这样不同的子类可以实现不同的功能,且不影响原本的程序代码。在开闭原则之上又延申出下面六个原则。
1. 单一职责原则:这样做的好处是类之间的结构界限清晰,方便后续扩展,且方便开发。
2. 里氏替换原则(Liskov Substitution Principle LSP):任何子类可以出现的地方,基类也可以出现。里氏替换原则是对开闭原则的补充,实现开闭原则的关键步骤是抽象化,可以说里氏替换原则是对开闭原则中抽象化步骤的另一种形式的描述。历史替换原则中,子类对父类的方法尽量不要重写和重载。因为父类代表了定义好的结构,通过这个规范的接口与外界交互,子类不应该随便破坏它。
3. 依赖倒转原则(Dependence Inversion Principle):开闭原则的基础,依赖接口不依赖实现类,所以依赖的应该是子类但是实际上依赖的是抽象接口。
4. 接口隔离原则(Interfaces Segregation Principle):一个接口一个功能,否则另起一个接口。
5. 迪米特法则(最少知道原则 Demeter Principle):调用者和被调用者之间最好是只存在调用关系,不存在逻辑交互关系,这样被调用者变化时才能最小的影响调用者。
6. 合称复用原则(Composite Reuse Principle):优先使用持有依赖的方式组合对象关系,而不是继承这个对象的能力来组合对象关系。
*************************创建型模式
工厂方法模式:
工厂就是制造东西的地方,在Java中引申为创造对象的工具类,设计模式中的工厂方法模式基于设计模式原则-上述来进行设计。具体内容就是设计一个工厂接口,根据需要实现不同的工厂类,实际开发中依赖的是接口而非子类。
package org.yang.get; public interface interfaces { interface entity{ String say(); } class entity1 implements entity{ @Override public String say() { return "im entity1"; } } class entity2 implements entity{ @Override public String say() { return "im entity2"; } } interface factoryBean{ entity getBean(); } class factoryBean1 implements factoryBean{ @Override public entity getBean() { return new entity1(); } } class factoryBean2 implements factoryBean{ @Override public entity getBean() { return new entity2(); } } static void main(String[] args) { factoryBean factoryBean1 = new factoryBean1(); entity entity1 = factoryBean1.getBean(); System.out.println(entity1.say()); factoryBean factoryBean2 = new factoryBean2(); entity entity2 = factoryBean2.getBean(); System.out.println(entity2.say()); } }
抽象工厂模式:
抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
大致的思路是:
你是个开小卖铺的老板你开张了。首先把你要卖的商品种类ABCD制成招牌放在不同的四个货架上,ABCD下面又各有四种产品,比如A下面有A1A2A3A4四款产品,你会有个记账本S,S里面记录了这16种产品在货架上的具体存货量,采购员会和你每天都核对一遍库存,S里面有四页,分别叫abcd,a里面记录了A1A2A3A4四款产品的记录,找到a就可以得到A1A2A3A4这四款产品了,但首先你要找到S。
类比到抽象工厂模式中可以理解为:你就是一个对外开放的获得工厂的工具类,告诉你想核对什么商品,你可以快速的定位到S中的每一个具体的页并得到需要的信息;S就是抽象工厂;abcd就是具体的工厂类,A1A2A3A4就是四种具体的产品,ABCD是四种产品的分类;这三种信息都会在S中进行处理,最终得到产品的具体信息。
1 package org.yang.get; 2 3 public interface abstractFactoryDemo { 4 interface A{ 5 String WHO(); 6 } 7 8 class A1 implements A{ 9 10 @Override 11 public String WHO() { 12 return "im a1"; 13 } 14 } 15 16 interface B{ 17 String WHO(); 18 } 19 20 class B1 implements B{ 21 22 @Override 23 public String WHO() { 24 return "im b1"; 25 } 26 } 27 28 abstract class abstractFactory{ 29 abstract A getA(String name); 30 abstract B getB(String name); 31 } 32 33 class factoryA extends abstractFactory{ 34 35 @Override 36 A getA(String name) { 37 return name.equals("A1") ? new A1() : new A1(); 38 } 39 40 @Override 41 B getB(String name) { 42 return null; 43 } 44 } 45 46 class factoryB extends abstractFactory{ 47 48 @Override 49 A getA(String name) { 50 return null; 51 } 52 53 @Override 54 B getB(String name) { 55 return name.equals("B1") ? new B1() : new B1(); 56 } 57 } 58 59 class tools{ 60 abstractFactory get(String name){ 61 abstractFactory factory; 62 switch (name){ 63 case "A" : { 64 factory = new factoryA(); break; 65 } 66 case "B" :{ 67 factory = new factoryB(); break; 68 } 69 default: { 70 factory = null; break; 71 } 72 } 73 return factory; 74 } 75 } 76 77 public static void main(String[] args) { 78 tools tools = new tools(); 79 abstractFactory Factory = tools.get("A"); 80 A a1 = Factory.getA("A1"); 81 System.out.println(a1.WHO()); 82 } 83 }
建造者模式:
创建者模式Builder Pattern,使用多个简单的对象一步一步构建成一个复杂的对象。这种模式属于创建型模式,它提供了一种创建对象的最佳方式。一个Builder类会一步一步构造最终的对象。该Buildler类是独立与其他对象的。
1 package org.yang.get; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 public interface builderDemo { 7 interface car{ 8 String name(); 9 String description(); 10 } 11 12 abstract class truckCar implements car{ 13 @Override 14 public String description() { 15 return "this is a truckCar!"; 16 } 17 } 18 19 abstract class smallCar implements car{ 20 @Override 21 public String description() { 22 return "this is a smallCar!"; 23 } 24 } 25 26 class redTruckCar extends truckCar{ 27 @Override 28 public String name() { 29 return "my name is redTruckCar"; 30 } 31 } 32 33 class blueTruckCar extends truckCar{ 34 @Override 35 public String name() { 36 return "my name is blueTruckCar"; 37 } 38 } 39 40 class blackSmallCar extends smallCar{ 41 @Override 42 public String name() { 43 return "my name is blackSmallCar"; 44 } 45 } 46 47 class whiteSmallCar extends smallCar{ 48 @Override 49 public String name() { 50 return "my name is whiteSmallCar"; 51 } 52 } 53 54 class meal{ 55 private List<car> list = new ArrayList<>(); 56 57 void add(car car){ 58 list.add(car); 59 } 60 61 String showMe(){ 62 String CAR = ""; 63 for(car car : list){ 64 CAR = CAR + " " +car.name(); 65 } 66 return CAR; 67 } 68 } 69 70 class carBuilder{ 71 public meal meal1(){ 72 meal meal = new meal(); 73 meal.add(new redTruckCar()); 74 meal.add(new blackSmallCar()); 75 return meal; 76 } 77 78 public meal meal2(){ 79 meal meal = new meal(); 80 meal.add(new blackSmallCar()); 81 meal.add(new whiteSmallCar()); 82 meal.add(new redTruckCar()); 83 return meal; 84 } 85 } 86 87 public static void main(String[] args) { 88 carBuilder carBuilder = new carBuilder(); 89 meal meal = carBuilder.meal1(); 90 System.out.println(meal.showMe()); 91 } 92 }
从上面的例子可以看出,构造者模式就是将复杂的对象集合以一个构造类builder的形式对外展示,构造类是我们已经实现按照需求完成的工具类,这样我们只需要调用builder的一个方法就可以完成复杂的对象集合创建。
原型模式:
原型模式(Prototype Pattern),将消耗资源大的对象放入缓存中,使用的时候创建,后面获得的是缓存中的副本,避免重复创建,类似数据源。
1 package org.yang.get; 2 3 import java.util.HashMap; 4 import java.util.Map; 5 6 public interface PrototypeDemo { 7 abstract class abstractDataSource{ 8 HashMap hashMap = new HashMap(); 9 String getOne(){ 10 return (String)hashMap.get("0"); 11 } 12 abstract String getName(); 13 } 14 15 class druid extends abstractDataSource{ 16 17 @Override 18 String getName() { 19 return "druid"; 20 } 21 } 22 23 class c3p0 extends abstractDataSource{ 24 25 @Override 26 String getName() { 27 return "c3p0"; 28 } 29 } 30 31 class cacheUtil{ 32 static Map abstractDataSources = new HashMap(); 33 34 static void loadDataSources(){ 35 abstractDataSources.put("0",new druid()); 36 abstractDataSources.put("1",new c3p0()); 37 } 38 39 static abstractDataSource get(String name){ 40 return (abstractDataSource)abstractDataSources.get(name); 41 } 42 } 43 44 public static void main(String[] args) { 45 cacheUtil.loadDataSources(); 46 abstractDataSource dataSource = cacheUtil.get("0"); 47 System.out.println(dataSource.getName()); 48 } 49 }
单例模式:
单例模式是 Java 中最简单的设计模式之一,像下面这样:
1 public class singleton { 2 3 private static singleton singleton = new singleton() ; 4 public String message = "im a singleton Object"; 5 6 private singleton(){} 7 8 public static singleton get(){ 9 return singleton; 10 } 11 }
上面的属于饿汉式单例,因为没有加锁,且没有判断在多线程下会有问题,所以如果是多线程下的代码需要加上同步命令。
*********结构模式
适配器模式:
适配器模式是作为两个不兼容接口的桥梁存在的,这种设计模式属于结构型设计模式,它结合了两个独立接口的功能。这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。类似驱动。
1 package org.yang.get; 2 3 public interface adapterDemo { 4 5 interface product{ 6 String name = null; 7 String getName(); 8 String doWhat(); 9 } 10 11 class car implements product{ 12 @Override 13 public String getName() { 14 return "im a car product"; 15 } 16 17 @Override 18 public String doWhat() { 19 return "i can run"; 20 } 21 } 22 23 class aircraft implements product{ 24 25 @Override 26 public String getName() { 27 return "im a aircraft product"; 28 } 29 30 @Override 31 public String doWhat() { 32 return "i can fly"; 33 } 34 } 35 36 interface Vehicle{ 37 String description(); 38 String go(); 39 } 40 41 class VehicleAdapter implements Vehicle{ 42 product product ; 43 44 VehicleAdapter(String type){ 45 switch (type){ 46 case "run": product = new car(); break; 47 case "fly": product = new aircraft(); break; 48 } 49 } 50 51 @Override 52 public String description() { 53 return product.getName(); 54 } 55 56 @Override 57 public String go() { 58 return product.doWhat(); 59 } 60 } 61 62 /*** 63 * 外星人不会使用交通工具,提供一个适配器 64 */ 65 class Alien implements Vehicle{ 66 67 VehicleAdapter VehicleAdapter; 68 69 Alien(String type){ 70 VehicleAdapter = new VehicleAdapter("fly"); 71 } 72 73 @Override 74 public String description() { 75 return VehicleAdapter.description(); 76 } 77 78 @Override 79 public String go() { 80 return VehicleAdapter.go(); 81 } 82 } 83 }
桥接模式:
对于有几个变化的维度,一般不会使用继承的形式实现而是通过不同类的组合的形式,这样除了减少系统中的类个数,也利于系统扩展。这种形式称之为桥接模式。
1 package org.yang.get; 2 3 /*** 4 * 桥接模式 5 */ 6 public interface bridging { 7 abstract class team{ 8 String message = null; 9 abstract void set(String message); 10 } 11 12 abstract class boss{ 13 team team; 14 15 void setTeam(team team){ 16 this.team = team; 17 } 18 19 abstract String speak(); 20 } 21 22 class bigBoss extends boss{ 23 24 @Override 25 String speak() { 26 return "i am bigBoss and i have a team named " + team.message; 27 } 28 } 29 30 class teamA extends team{ 31 32 @Override 33 public void set(String message) { 34 this.message = message; 35 } 36 } 37 38 public static void main(String[] args) { 39 boss boss = new bigBoss(); 40 team team = new teamA(); 41 team.set("teamA"); 42 boss.setTeam(team); 43 System.out.println(boss.speak()); 44 } 45 }
这里不同变化的维度指的是不同的组合的可能,比如bossa和teama以及teamb可以组合为两种组合,如果一一列举太麻烦,可以使用桥接模式进行组合减少重复工作。
组合模式:
又叫部分整体模式,强调部分和整体的区别。
1 package org.yang.get; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 /*** 7 * 组合模式 8 */ 9 public interface Composite { 10 class Employee{ 11 private String name; 12 private String salary; 13 private List<Employee> list; 14 15 Employee(String name,String salary){ 16 this.name = name; 17 this.salary = salary; 18 this.list = new ArrayList<>(); 19 } 20 21 void setEmployee(Employee e){ 22 this.list.add(e); 23 } 24 25 void removeEmployee(Employee e){ 26 this.list.remove(e); 27 } 28 29 @Override 30 public String toString() { 31 return "Employee{" + 32 "name='" + name + '\'' + 33 ", salary='" + salary + '\'' + 34 '}'; 35 } 36 } 37 38 public static void main(String[] args) { 39 Employee CEO = new Employee("zs","2000000"); 40 Employee gl1 = new Employee("ww","200000"); 41 Employee gl2 = new Employee("ls","200000"); 42 Employee worker1 = new Employee("xm","20000"); 43 Employee worker2 = new Employee("za","20000"); 44 45 gl1.setEmployee(worker1); 46 gl2.setEmployee(worker2); 47 48 CEO.setEmployee(gl1); 49 CEO.setEmployee(gl2); 50 51 System.out.println(CEO.toString()); 52 System.out.println("-----"); 53 for(Employee e: CEO.list){ 54 System.out.println(e.toString()); 55 for(Employee ee : e.list){ 56 System.out.println(ee.toString()); 57 } 58 System.out.println("****"); 59 } 60 } 61 }
装饰模式:
装饰模式就是将使用装饰类隐藏被装饰类。
1 package org.yang.get; 2 3 /*** 4 * 装饰模式 5 */ 6 public interface decorate { 7 8 interface decoratePattern{ 9 String doSth(); 10 } 11 12 class son implements decoratePattern{ 13 @Override 14 public String doSth() { 15 return "i want play"; 16 } 17 } 18 19 class decorator implements decoratePattern{ 20 decoratePattern decoratePattern; 21 22 decorator(decoratePattern decoratePattern){ 23 this.decoratePattern = decoratePattern; 24 } 25 26 @Override 27 public String doSth() { 28 this.Enhance(); 29 return this.decoratePattern.doSth(); 30 } 31 32 void Enhance(){ 33 System.out.println("extra do"); 34 } 35 } 36 37 public static void main(String[] args) { 38 decorator decorator = new decorator(new son()); 39 System.out.println(decorator.doSth()); 40 } 41 }
外观模式:
Facade Pattern,隐藏系统的复杂内容,只展示客户需要的内容。
1 package org.yang.get; 2 3 4 /*** 5 * 外观模式 6 */ 7 public interface Facade { 8 9 class project{ 10 String message1; 11 String message2; 12 String message3; 13 14 public void set(String message1,String message2,String message3){ 15 this.message1 = message1; 16 this.message2 = message2; 17 this.message3 = message3; 18 } 19 20 public String getMessage1() { 21 return message1; 22 } 23 24 public String getMessage2() { 25 return message2; 26 } 27 28 public String getMessage3() { 29 return message3; 30 } 31 } 32 33 class facade{ 34 private project project; 35 facade(project project){ 36 this.project = project; 37 } 38 39 String getMessage(String name){ 40 if(name.equals("VP")) 41 return this.project.message1; 42 return project.message2; 43 } 44 } 45 }
享元模式:
享元模式有个很具体的例子就是常量池和数据库连接池,可重复利用的对象不需要重复构造,直接复用,这样达到节省资源的效果,这有个好的文章是讲享元模式的:https://www.cnblogs.com/adamjwh/p/9070107.html
1 package org.yang.get; 2 3 import java.util.HashMap; 4 import java.util.Map; 5 6 /*** 7 * 享元模式 8 */ 9 public interface FLYWEIGHT { 10 interface Mode{ 11 String getMessage(); 12 } 13 14 class PublicMode implements Mode{ 15 String message; 16 PublicMode(String message){ 17 this.message = message; 18 } 19 20 @Override 21 public String getMessage() { 22 return this.message; 23 } 24 25 @Override 26 public String toString() { 27 return "PublicMode{" + 28 "message='" + message + '\'' + 29 '}'; 30 } 31 } 32 33 class factory{ 34 private Map pool = new HashMap(); 35 36 public Mode getMode(String key){ 37 Object o = this.pool.get(key); 38 if(o!=null) 39 return (Mode)o; 40 Mode mode = new PublicMode(key); 41 this.pool.put(key,mode); 42 return mode; 43 } 44 } 45 46 static void main(String[] args) { 47 factory factory = new factory(); 48 Mode mode = factory.getMode("ap"); 49 System.out.println(mode.toString()); 50 } 51 }
代理模式:
Proxy Pattern,一个类代理了另一个类的功能,最常见到的介绍代理模式的就是艺人和经纪人的例子。例子很简单,但能说明问题。
1 package org.yang.get; 2 3 /*** 4 * 代理模式 5 */ 6 public interface proxy { 7 8 interface proxyInterface{ 9 void play(); 10 void takeMoney(); 11 } 12 13 class star implements proxyInterface{ 14 @Override 15 public void play() { 16 System.out.println("吼吼,苍茫的天涯是我的爱"); 17 } 18 19 @Override 20 public void takeMoney() { 21 System.out.println("我要买兰博基尼"); 22 } 23 } 24 25 class Agent implements proxyInterface{ 26 27 private star star; 28 29 Agent(star star){ 30 this.star = star; 31 } 32 33 @Override 34 public void play() { 35 this.star.play(); 36 System.out.println("演出结束"); 37 } 38 39 @Override 40 public void takeMoney() { 41 this.star.takeMoney(); 42 System.out.println("我去买"); 43 } 44 } 45 }
**********行为模式
解释器模式:
这种模式实现了一个表达式接口,该接口解释了一个特点的上下文。
1 package org.yang.get; 2 3 /*** 4 * 解释器模式 5 */ 6 public interface InterpreterDemo { 7 interface Interpreter{ 8 String Interpreter(String messageExpression); 9 } 10 11 class terminalExpression implements Interpreter{ 12 13 private String message; 14 15 terminalExpression(String message){ 16 this.message = message; 17 } 18 19 @Override 20 public String Interpreter(String messageExpression) { 21 return messageExpression!=null&&messageExpression.startsWith(message)?messageExpression+"end":null; 22 } 23 } 24 }
模板方法模式:
模板方法就比较常见了,就是抽象类定义骨架流程,子类实现具体的细节。
1 package org.yang.get; 2 3 /*** 4 * 模板方法模式 5 */ 6 public interface templateDemo { 7 interface template{ 8 void method1(); 9 void method2(); 10 void method3(); 11 } 12 13 /*** 14 * 模板 15 */ 16 abstract class example implements template{ 17 18 boolean start(){ 19 this.method1(); 20 this.method2(); 21 this.method3(); 22 return true; 23 } 24 } 25 26 /*** 27 * 具体的子类 28 */ 29 class entity extends example{ 30 @Override 31 public void method1() { 32 System.out.println("my method1"); 33 } 34 35 @Override 36 public void method2() { 37 System.out.println("my method1"); 38 } 39 40 @Override 41 public void method3() { 42 System.out.println("my method1"); 43 } 44 } 45 }
职责链模式:
顾名思义就是一个处理流链,在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推,知道找到处理这个请求的对象。
1 package org.yang.get; 2 3 /*** 4 * 责任链模式 5 */ 6 public interface ChainOfResponsibilityPattern { 7 interface Chain{ 8 boolean deal(String message); 9 } 10 11 abstract class abstractChain implements Chain{ 12 protected Chain chain; 13 abstract void setChain(Chain chain); 14 } 15 16 class chainTemplate extends abstractChain{ 17 @Override 18 public boolean deal(String message) { 19 if(message.startsWith("1")) 20 return true; 21 return this.chain.deal(message); 22 } 23 24 @Override 25 void setChain(Chain chain) { 26 this.chain = chain; 27 } 28 } 29 }
命令模式:
简单的讲命令模式中包含四个部分:invoker调用者;command命令;concreteCommand具体命令;Receiver命令执行者。
1 package org.yang.get; 2 3 /*** 4 * ,命令模式 5 */ 6 public interface commandDemo { 7 /*** 8 * 命令执行者1 9 */ 10 class Infantry { 11 boolean run(){ 12 System.out.println("ready to run"); 13 return true; 14 } 15 } 16 17 /*** 18 * 命令执行者2 19 */ 20 class navy{ 21 boolean swim(){ 22 System.out.println("ready to swim"); 23 return true; 24 } 25 } 26 27 /*** 28 * 命令接口 29 */ 30 interface command{ 31 boolean go(); 32 } 33 34 /*** 35 * 具体的命令1 36 */ 37 class InfantryCommand implements command{ 38 Infantry infantry; 39 40 InfantryCommand(Infantry infantry){ 41 this.infantry = infantry; 42 } 43 44 @Override 45 public boolean go() { 46 return this.infantry.run(); 47 } 48 } 49 50 /*** 51 * 具体的命令2 52 */ 53 class navyCommand implements command{ 54 navy navy; 55 56 navyCommand(navy navy){ 57 this.navy = navy; 58 } 59 60 @Override 61 public boolean go() { 62 return this.navy.swim(); 63 } 64 } 65 66 /*** 67 * 调用者 68 */ 69 class invoker{ 70 void invoke(command command){ 71 command.go(); 72 } 73 } 74 }
迭代器模式:
迭代器最典型的例子就是迭代器,我们知道集合类都是实现了Iterable接口的,这个接口的功能就是实现迭代器的功能,所以所有集合类都可以进行迭代。下面看下ArrayList的迭代器:
1 /** 2 * An optimized version of AbstractList.Itr 3 */ 4 private class Itr implements Iterator<E> { 5 int cursor; // index of next element to return 6 int lastRet = -1; // index of last element returned; -1 if no such 7 int expectedModCount = modCount; 8 9 Itr() {} 10 11 public boolean hasNext() { 12 return cursor != size; 13 } 14 15 @SuppressWarnings("unchecked") 16 public E next() { 17 checkForComodification(); 18 int i = cursor; 19 if (i >= size) 20 throw new NoSuchElementException(); 21 Object[] elementData = ArrayList.this.elementData; 22 if (i >= elementData.length) 23 throw new ConcurrentModificationException(); 24 cursor = i + 1; 25 return (E) elementData[lastRet = i]; 26 } 27 28 public void remove() { 29 if (lastRet < 0) 30 throw new IllegalStateException(); 31 checkForComodification(); 32 33 try { 34 ArrayList.this.remove(lastRet); 35 cursor = lastRet; 36 lastRet = -1; 37 expectedModCount = modCount; 38 } catch (IndexOutOfBoundsException ex) { 39 throw new ConcurrentModificationException(); 40 } 41 } 42 43 @Override 44 @SuppressWarnings("unchecked") 45 public void forEachRemaining(Consumer<? super E> consumer) { 46 Objects.requireNonNull(consumer); 47 final int size = ArrayList.this.size; 48 int i = cursor; 49 if (i >= size) { 50 return; 51 } 52 final Object[] elementData = ArrayList.this.elementData; 53 if (i >= elementData.length) { 54 throw new ConcurrentModificationException(); 55 } 56 while (i != size && modCount == expectedModCount) { 57 consumer.accept((E) elementData[i++]); 58 } 59 // update once at end of iteration to reduce heap write traffic 60 cursor = i; 61 lastRet = i - 1; 62 checkForComodification(); 63 } 64 65 final void checkForComodification() { 66 if (modCount != expectedModCount) 67 throw new ConcurrentModificationException(); 68 } 69 }
中介者模式:
中介者模式(Mediator Pattern)是用来降低多个对象和类之间的通信复杂性。这种模式提供了一个中介类,该类通常处理不同类之间的通信,并支持松耦合,使代码易于维护。中介者模式属于行为型模式。提到通信很容易就会想到聊天室,因为聊天软件本身上不复杂,但是处理用户的复杂聊天关系和维持这种关系是最重要的,这个有点远,中介者模式就是复杂关系的维护者。
1 package org.yang.get; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 /*** 7 * 中介者模式 8 */ 9 public interface MediatorPattern { 10 /*** 11 * 通信单元 12 */ 13 class user{ 14 String name; 15 chatRoom chatRoom; 16 user(String name,chatRoom chatRoom){ 17 this.name = name; 18 this.chatRoom = chatRoom; 19 this.chatRoom.loginOn(this); 20 } 21 boolean sendMessage(String name,String message){ 22 return this.chatRoom.sendMessage(new user(name,chatRoom),message); 23 } 24 25 void receiveMessage(String message){ 26 System.out.println("my name is:"+name+" i received a message:"+message); 27 } 28 } 29 30 /*** 31 * 中介者 32 */ 33 class chatRoom{ 34 private List<user> room = new ArrayList<>(); 35 36 void loginOn(user user){ 37 this.room.add(user); 38 } 39 40 boolean sendMessage(user user,String message){ 41 this.room.get(this.room.indexOf(user)).receiveMessage(message); 42 return true; 43 } 44 } 45 46 public static void main(String[] args) { 47 chatRoom chatRoom = new chatRoom(); 48 user user1 = new user("张三",chatRoom); 49 new user("里斯",chatRoom); 50 user1.sendMessage("里斯","hai friend"); 51 } 52 }
备忘录模式:
备忘录模式(Memento Pattern)保存一个对象的某个状态,以便在适当的时候恢复对象。备忘录模式属于行为型模式。很多时候我们总是需要记录一个对象的内部状态,这样做的目的就是为了允许用户取消不确定或者错误的操作,能够恢复到他原先的状态,使得他有"后悔药"可吃。
备忘录模式使用三个类 Memento、Originator 和 CareTaker。Memento 包含了要被恢复的对象的状态。Originator 创建并在 Memento 对象中存储状态。Caretaker 对象负责从 Memento 中恢复对象的状态。
1 package org.yang.get; 2 3 import java.util.HashMap; 4 import java.util.Map; 5 6 /*** 7 * 备忘录模式 8 */ 9 public interface MementoPatternDemo { 10 /*** 11 * 实体类 12 */ 13 class Originator{ 14 String message; 15 String name;/*这个字段是可以通过其他手段获得的,或者说这个不会被遗忘,就像你会忘了密码,但不会忘了你的名字*/ 16 Originator(String message,String name){ 17 this.message = message; 18 this.name = name; 19 } 20 } 21 22 /*** 23 * 从遗忘中恢复 24 */ 25 interface util{ 26 Originator recover(String name); 27 } 28 29 /*** 30 * 存储状态的对象 31 */ 32 class Memento implements util{ 33 Map pool = new HashMap(); 34 Memento(Originator originator){ 35 this.pool.put(originator.name,originator.message); 36 } 37 38 @Override 39 public Originator recover(String name) { 40 return new Originator(name,(String) this.pool.get(name)); 41 } 42 } 43 }
观察者模式:
当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知它的依赖对象。观察者模式属于行为型模式。定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
1 package org.yang.get; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 /*** 7 * 观察者模式 8 */ 9 public interface ObserverPatternDemo { 10 interface Observer{ 11 void doSth(String name); 12 } 13 14 class Observer1 implements Observer{ 15 @Override 16 public void doSth(String name) { 17 if(name.startsWith("1")){ 18 System.out.println("Observer1 deal"); 19 } 20 } 21 } 22 23 class Observer2 implements Observer{ 24 @Override 25 public void doSth(String name) { 26 if(name.startsWith("1")){ 27 System.out.println("Observer2 deal"); 28 } 29 } 30 } 31 32 class subject{ 33 List<Observer> list = new ArrayList<>(); 34 void addObserver(Observer observer){ 35 this.list.add(observer); 36 } 37 38 void myDo(String type){ 39 System.out.println("i want do sth"); 40 this.doType(type); 41 } 42 43 void doType(String type){ 44 for(Observer e:list){ 45 e.doSth(type); 46 } 47 } 48 } 49 50 public static void main(String[] args) { 51 subject subject = new subject(); 52 subject.addObserver(new Observer1()); 53 subject.addObserver(new Observer2()); 54 subject.myDo("1"); 55 } 56 }
状态模式:
当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。简单的理解就是对象的行为依赖于它的状态(属性),并且可以根据它的状态改变而改变它的相关行为。
状态模式中共有三个角色,他们分别是上下文环境Context,抽象状态state,具体状态Concrete state。从模型中可以看出关键的两部分即环境和状态。
1 package org.yang.get; 2 3 /*** 4 * 状态模式 5 */ 6 public interface statePatternDemo { 7 /*** 8 * 状态 9 */ 10 class state{ 11 String info; 12 state(String info){ 13 this.info = info; 14 } 15 } 16 17 /*** 18 * 容器 19 */ 20 class factory{ 21 private String name; 22 state state; 23 factory(state state){ 24 this.state = state; 25 } 26 27 void produce(){ 28 if(this.state.info.equals("Rifle")){//状态 29 this.name = "Rifle"; 30 System.out.println("im a Rifle factory");//行为 31 }else{ 32 this.name = "Sniper rifle"; 33 System.out.println("im a Sniper Rifle factory"); 34 } 35 } 36 } 37 }
策略模式:
策略模式是通过实现不同的策略实现类来完成灵活使用不同策略的目的。
1 package org.yang.get; 2 3 /*** 4 * 策略模式 5 */ 6 public interface strategyDemo { 7 interface Strategy{ 8 void operation(); 9 } 10 11 class Strategy1 implements Strategy{ 12 @Override 13 public void operation() { 14 System.out.println("策略1开始执行"); 15 } 16 } 17 18 class Strategy2 implements Strategy{ 19 @Override 20 public void operation() { 21 System.out.println("策略2开始执行"); 22 } 23 } 24 25 class lieBei{ 26 private Strategy strategy; 27 lieBei(Strategy strategy){ 28 this.strategy=strategy; 29 } 30 31 void war(){ 32 this.strategy.operation(); 33 } 34 } 35 }
访问者模式:
最复杂的设计模式,并且使用频率不高,《设计模式》的作者评价为:大多情况下,你不需要使用访问者模式,但是一旦需要使用它时,那就真的需要使用了。访问者模式是一种将数据操作和数据结构分离的设计模式。
访问者模式的使用场景:
1.对象结构比较稳定,但经常需要在此对象结构上定义新的操作。
2.需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免这些操作“污染”这些对象的类,也不希望在增加新操作时修改这些类。
1 package org.yang.get; 2 3 /*** 4 * 访问者模式 5 */ 6 public interface VisitorPatternDemo { 7 abstract class abstractAssembly{ 8 String name; 9 void setName(String name){ 10 this.name = name; 11 } 12 13 abstract void work(); 14 } 15 16 class mouse extends abstractAssembly{ 17 mouse(){ 18 this.setName("mouse"); 19 } 20 @Override 21 void work() { 22 System.out.println("im working, im a :" + this.name); 23 } 24 } 25 26 class Monitor extends abstractAssembly{ 27 Monitor(){ 28 this.setName("Monitor"); 29 } 30 @Override 31 void work() { 32 System.out.println("im working, im a :" + this.name); 33 } 34 } 35 36 /*** 37 * 访问接口 38 */ 39 interface visit{ 40 void visit(abstractAssembly assembly); 41 } 42 43 /*** 44 * 访问器 45 */ 46 class person implements visit{ 47 @Override 48 public void visit(abstractAssembly assembly) { 49 assembly.work(); 50 } 51 } 52 }
参考文章:https://www.cnblogs.com/geek6/p/3951677.html https://www.runoob.com/design-pattern/design-pattern-tutorial.html