[TOC]
设计模式概述
设计模式目的
七大原则
单一职责原则
接口隔离原则
依赖倒转原则(面向接口编程)
里氏替换原则
开闭原则
迪米特法则
合成复用原则
UML类图
设计模式
基本概念
单例模式
饿汉式
静态常量写法
1 2 3 4 5 6 7 8 9 10 11 12 13 class Hungry1 { private Hungry1 () { } static final private Hungry1 h1 = new Hungry1 (); static Hungry1 getHungrt () { return h1; } }
静态代码块写法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Hungry1 { private Hungry1 () { } static final private Hungry1 h1; static { h1 = new Hungry1 (); } static Hungry1 getHungrt () { return h1; } }
懒汉式
线程不安全方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Hungry2 { private Hungry2 () { } static private Hungry2 h2; static Hungry2 getHungry () { if (h2 == null ) { h2 = new Hungry2 (); return h2; } else return h2; } }
2. 线程安全式(同步方法方式)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Hungry2 { private Hungry2 () { } static private Hungry2 h2; public static synchronized Hungry2 getHungry () { if (h2 == null ) { h2 = new Hungry2 (); return h2; } else return h2; } }
线程安全式(同步代码块形式)
错误方式,不存在!!!!
双重检查
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class Hungry3 { private Hungry3 () { } static private volatile Hungry3 h3; public static Hungry3 getInstance () { if (h3 == null ) { synchronized (Hungry3.class) { if (h3 == null )h3 = new Hungry3 (); } } return h3; } }
静态内部类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public class StaticInnerClass { @Test public void test () { } }class Static { private Static () { } private static class StaticInner { private static Static instance = new Static (); } public static Static getInstance () { return StaticInner.instance; } }
枚举类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 package SingleInstance;import org.junit.jupiter.api.Test;public class EnumClass { @Test public void test () { Enum e1 = Enum.Instance; Enum e2 = Enum.Instance; System.out.println(e1 == e2); } }enum Enum { Instance(); private Enum () { } }
单例模式注意
工厂模式
简单工厂模式
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 classDiagram class Pizza{ Attributes } class OrderPizza{ Factory factory; } class Factory{ Pizza getPizza() } class BJPizza{ } class TJPizza{ } Pizza <|-- TJPizza Pizza <|-- BJPizza Factory <| -- BJPizza Factory <| -- TJPizza OrderPizza <|-- Factory Factory <|-- OrderPizza
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package Factory.SimpleFactory;public class Factory { public Pizza getPizza (String name) { Pizza pizza = null ; if (name.equals("BJ" ) || name.equals("TJ" )) pizza = new Pizza (name); return pizza; } }
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 package Factory.SimpleFactory;import org.junit.jupiter.api.Test;public class OrderPizza { private Factory factory = new Factory (); private Pizza pizza = null ; @Test public void getPizza () { String name = "BJ" ; pizza = factory.getPizza(name); if (pizza == null ) System.out.println("no" ); else System.out.println("yes" ); } }
1 2 3 4 5 6 7 8 9 10 11 package Factory.SimpleFactory;public class Pizza { public Pizza (String name) { this .name = name; } String name; }
工厂方法模式
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 classDiagram class Pizza{ } class BJPepperPizza{ } Pizza <|-- BJPepperPizza BJPepperPizza <|-- BJOrder class BJSourPizza{ } Pizza <|-- BJSourPizza BJSourPizza <|-- BJOrder class TJPepperPizza{ } Pizza <|-- TJPepperPizza TJPepperPizza <|-- TJOrder class TJSourPizza{ } Pizza <|-- TJSourPizza TJSourPizza <|-- TJOrder class BJOrder{ } BJOrder <|-- Order class TJOrder{ } TJOrder <|-- Order class Order{ }
1 2 3 4 5 6 7 8 9 10 11 12 13 package Factory.FactoryMethods.Pizzas;public class Pizza { String name; public Pizza (String name) { this .name = name; } }
1 2 3 4 5 6 7 8 9 10 package Factory.FactoryMethods.Pizzas;public class BJPizza extends Pizza { public BJPizza (String name) { super (name); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 package Factory.FactoryMethods.Orders;import Factory.FactoryMethods.Pizzas.Pizza;import Factory.FactoryMethods.Pizzas.TJPizza;public class TJOrder extends Order { @Override Pizza getPizza (String name) { Pizza pizza = null ; if (name.equals("22" )) pizza = new TJPizza (name); return pizza; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 package Factory.FactoryMethods.Orders;import Factory.FactoryMethods.Pizzas.Pizza;public abstract class Order { public Order () { } public void orderPizza (String name) { Pizza pizza = getPizza(name); } abstract Pizza getPizza (String name) ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 package Factory.FactoryMethods.Orders;import Factory.FactoryMethods.Pizzas.BJPizza;import Factory.FactoryMethods.Pizzas.Pizza;public class BJorder extends Order { @Override Pizza getPizza (String name) { Pizza pizza = null ; if (name.equals("ll" )) pizza = new BJPizza (name); return pizza; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 package Factory.FactoryMethods.Orders;import Factory.FactoryMethods.Pizzas.Pizza;import Factory.FactoryMethods.Pizzas.TJPizza;public class TJOrder extends Order { @Override Pizza getPizza (String name) { Pizza pizza = null ; if (name.equals("22" )) pizza = new TJPizza (name); return pizza; } }
抽象工厂模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 classDiagram Pizza <|-- BJPepperPizza Pizza <|-- TJPepperPizza Pizza <|-- BJSourPizza Pizza <|-- TJSourPizza BJPepperPizza <|-- Order TJPepperPizza <|-- Order BJSourPizza <|-- Order TJSourPizza <|-- Order Order <|-- BJFactory Order <|-- TJFactory BJFactory <|-- AbsFactory TJFactory <|-- AbsFactory
1 2 3 4 5 6 7 8 9 10 11 12 13 14 package Factory.Abstract;public class Order { AbsFactory factory; public void setFactory (AbsFactory factory,String name) { this .factory = factory; Pizza pizza = factory.getPizza(name); } }
1 2 3 4 5 6 7 8 package Factory.Abstract;public interface AbsFactory { public Pizza getPizza (String name) ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 package Factory.Abstract;public class BJFactory implements AbsFactory { @Override public Pizza getPizza (String name) { Pizza pizza = null ; if (name.equals("6" )) pizza = new BJPizza (name); return pizza; } }
1 2 3 4 5 6 7 8 package Factory.Abstract;public class TJPizza extends Pizza { TJPizza(String name){ super (name); } }
原型模式
建造者模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 classDiagram class HosueBuilder class CommonHouse class HighHouse HosueBuilder <|-- CommonHouse HosueBuilder <|-- HighHouse class House class Director Director : 【中间商】 Director <|-- HosueBuilder House <|-- Director HosueBuilder : void buildBasic() HosueBuilder : void buildWalls() HosueBuilder : void roofed()
1 2 3 4 5 6 7 8 9 10 11 12 13 package Builder;public interface BuildeHouse { House house = new House (); public void buildWalls () ; public void buildBasic () ; public void roofed () ; }
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 package Builder;public class CommonHouse implements BuildeHouse { @Override public void buildBasic () { System.out.println("basic" ); } @Override public void buildWalls () { System.out.println("walls" ); } @Override public void roofed () { System.out.println("roof" ); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 package Builder;public class HighHouse implements BuildeHouse { @Override public void buildBasic () { System.out.println("highB" ); } @Override public void buildWalls () { System.out.println("highW" ); } @Override public void roofed () { System.out.println("highR" ); } }
1 2 3 4 5 6 package Builder;public class House { }
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 package Builder;public class Director { BuildeHouse builder; public Director (BuildeHouse builder) { this .builder = builder; } public void setBuilder (BuildeHouse builder) { this .builder = builder; } public void buildHouse () { builder.buildBasic(); builder.buildWalls(); builder.roofed(); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 package Builder;import org.junit.jupiter.api.Test;public class Client { @Test public void test () { Director director = new Director (new CommonHouse ()); director.setBuilder(new HighHouse ()); director.buildHouse(); } }
1 2 3 4 5 6 7 8 classDiagram class MidFactory MidFactory : abstractBuild class MidBuilder MidBuilder : buildConcreate1 MidBuilder : buildConcreate2 MidBuilder : buildConcreate3
适配器模式
1 2 3 4 5 6 7 8 9 10 classDiagram class Voltage220V class Voltage5V class AdapterVoltage class Phone AdapterVoltage <|-- Voltage220V AdapterVoltage <|-- Voltage5V Phone <|-- AdapterVoltage
对象适配器
1 2 3 4 5 6 7 8 9 10 classDiagram class Voltage220V class Voltage5V class AdapterVoltage class Phone AdapterVoltage : Voltage220V voltage AdapterVoltage <|-- Voltage220V AdapterVoltage <|-- Voltage5V Phone <|-- AdapterVoltage
接口适配器(缺省适配器模式)
桥接模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 classDiagram class Phone class VIVO class XiaoMi class Brand class FolderPhone Brand : void open() Brand : void close() VIVO <|-- Brand XiaoMi <|-- Brand Phone <|-- VIVO Phone <|-- XiaoMi FolderPhone <|-- Phone
1 2 3 4 5 6 7 8 9 package Bridge;public interface Brand { void open () ; void close () ; }
1 2 3 4 5 6 7 package Bridge;public class FolderPhone extends Phone { }
1 2 3 4 5 6 7 8 package Bridge;public abstract class Phone { Brand brand; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 package Bridge;public class Vivo implements Brand { @Override public void close () { } @Override public void open () { } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 package Bridge;public class XiaoMi implements Brand { @Override public void close () { } @Override public void open () { } }
装饰者模式
以io模块为例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 classDiagram class InputStream class FileInputStream class StringBufferInputStream class ByteArrayInputStream class FilterInputStream InputStream <|-- FileInputStream InputStream <|-- StringBufferInputStream InputStream <|-- ByteArrayInputStream InputStream <|-- FilterInputStream class BufferInputStream class DataInputStream class LineNumberInputStream FilterInputStream : InputStream is FilterInputStream <|-- BufferInputStream FilterInputStream <|-- DataInputStream FilterInputStream <|-- LineNumberInputStream
1 2 3 4 5 6 7 8 9 10 11 12 package Decorate;public class BlackCoffee extends Coffee { @Override int cost () { return super .cost() + 10 ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 package Decorate;public class Coffee extends Drink { @Override int cost () { return 5 ; } @Override void setCost () { } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 package Decorate;public class Decorater extends Drink { Drink drink; @Override int cost () { int cost_temp = 0 ; if (drink != null ) cost_temp = drink.cost(); return cost_temp + cost; } void setDrink (Drink drink) { this .drink = drink; }@Override void setCost () { } }
1 2 3 4 5 6 7 8 9 10 package Decorate;public abstract class Drink { int cost; abstract int cost () ; abstract void setCost () ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package Decorate;public class Sugar extends Decorater { void getCost () { int temp_cost = 0 ; if (drink != null ) temp_cost = drink.cost(); cost = temp_cost + 5 ; } }
外观模式(过程模式)
享元模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 classDiagram class FlyWeight class FlyWeightFactory class ConcreteFlyWeight class UnsharedConcreteFlyWeight class Client FlyWeight <|-- ConcreteFlyWeight FlyWeight <|-- UnsharedConcreteFlyWeight FlyWeight : void operate FlyWeightFactory : void getFlyWeight FlyWeightFactory <|-- FlyWeight FlyWeightFactory <|-- Client ConcreteFlyWeight <|-- Client UnsharedConcreteFlyWeight <|-- Client
1 2 3 4 5 6 package FlyWeight;public abstract class WebSite { }
1 2 3 4 5 6 7 8 9 10 11 12 package FlyWeight;public class ConcreteWebSite extends WebSite { String type; public ConcreteWebSite (String type) { this .type = type; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 package FlyWeight;import java.util.HashMap;public class WebSiteFactory { private HashMap<String,ConcreteWebSite> pool = new HashMap <String, ConcreteWebSite>(); public WebSite getWebSite (String type) { if (!pool.containsKey(type)) pool.put(type, new ConcreteWebSite (type)); return (WebSite)pool.get(type); } }
代理模式
静态代理
1 2 3 4 5 6 7 8 package Proxy;public interface TeacherDao { void teach () ; }
1 2 3 4 5 6 7 8 9 10 11 package Proxy;public class TeacherDaoImpl implements TeacherDao { @Override public void teach () { System.out.println("this is teacher" ); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 package Proxy;public class TeacherProxy implements TeacherDao { TeacherDao teacher; public TeacherProxy (TeacherDao teacher) { this .teacher = teacher; } @Override public void teach () { System.out.println("this proxy saying" ); teacher.teach(); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 package Proxy;import org.junit.jupiter.api.Test;public class TestClass { @Test public void test () { TeacherDao teacher = new TeacherProxy (new TeacherDaoImpl ()); teacher.teach(); } }
动态代理(JDK代理)
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 package Proxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public class ProxyFactory { Object target; public void setTarget (Object obj) { this .target = obj; } public ProxyFactory (Object obj) { target = obj; } public Object getProxyInstance () { return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),new InvocationHandler ( ) { @Override public Object invoke (Object proxy, Method method, Object[] args) throws Throwable { System.out.println("proxy" ); method.invoke(target, args); return null ; } }); } }
参数说明:
newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),new InvocationHandler):
参数一:被代理对象的类的加载器
参数二:被代理对象类的接口集合
参数三:事件处理,执行目标对象的方法时,会触发事件处理器的方法,进而完成代理方法的加强
动态代理(CGLIB代理)
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 package Proxy.CGLIB;import java.lang.reflect.Method;import net.sf.cglib.proxy.Enhancer;import net.sf.cglib.proxy.MethodInterceptor;import net.sf.cglib.proxy.MethodProxy;public class ProxyFactory implements MethodInterceptor { Object target; public ProxyFactory (Object obj) { this .target = obj; } public Object getProxyInstance () { Enhancer enhancer = new Enhancer (); enhancer.setSuperclass(target.getClass()); enhancer.setCallback(this ); return enhancer.create(); } @Override public Object intercept (Object arg0, Method method, Object[] arg2, MethodProxy arg3) throws Throwable { System.out.println("cglib代理方法" ); method.invoke(target, arg2); return null ; } }
1 2 3 4 5 6 7 8 9 10 package Proxy.CGLIB;public class TeacherDao { void teach () { System.out.println("被代理对象" ); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package Proxy.CGLIB;import org.junit.jupiter.api.Test;public class Client { @Test public void test () { TeacherDao teacher = new TeacherDao (); TeacherDao proxy = (TeacherDao)new ProxyFactory (teacher).getProxyInstance(); System.out.println(proxy.getClass()); } }
代理模式的变种
模板方法模式
基本模板方法模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 package TemplateMethods;public abstract class MakeDrink { final void operate () { System.out.println("select:" + select() + " add: " + add()); } abstract String select () ; abstract String add () ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 package TemplateMethods;public class RedDrink extends MakeDrink { @Override String add () { return "red!!" ; } @Override String select () { return "select red!" ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 package TemplateMethods;import org.junit.jupiter.api.Test;public class Client { @Test public void test () { MakeDrink drink = new RedDrink (); drink.operate(); } }
钩子方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 package TemplateMethods;public abstract class MakeDrink { final void operate () { if (isPure()) { addEquip(); } } void addEquip () { System.out.println("select:" + select() + " add: " + add()); } abstract boolean isPure () ; abstract String select () ; abstract String add () ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 package TemplateMethods;public class PureDrink extends MakeDrink { @Override String add () { return null ; } @Override boolean isPure () { return true ; } @Override String select () { return null ; } }
命令模式
访问者模式
1 2 3 4 5 6 7 8 9 10 11 12 package Visitors;public class ObjectStructure { Person persons[]; void setPerson () { } }
1 2 3 4 5 6 7 package Visitors;public abstract class Action { abstract void setAction () ; }
1 2 3 4 5 6 7 8 9 10 package Visitors;public class Failed extends Action { @Override void setAction () { } }
1 2 3 4 5 6 7 8 9 10 package Visitors;public class Sucessfully extends Action { @Override void setAction () { } }
1 2 3 4 5 6 7 8 9 package Visitors;public abstract class Person { Action action; abstract void accpet (Action action) ; }
1 2 3 4 5 6 7 8 9 10 package Visitors;public class Man extends Person { @Override void accpet (Action action) { this .action = action; } }
1 2 3 4 5 6 7 8 9 10 package Visitors;public class Woman extends Person { @Override void accpet (Action action) { this .action = action; } }
1 2 3 4 5 6 7 8 9 10 11 12 package Visitors;public class ObjectStructure { Person persons[]; void setPerson () { } }
双分派
首先将一个对象作为参数传入(第一次分派)
在被传入的方法中将this作为参数传入第一个对象的某个方法内
1 2 3 4 5 6 7 8 9 10 11 12 package Visitors.Doule;public class A { String name = "A" ; public void getBMethods (B b) { b.method(this ); } }
1 2 3 4 5 6 7 8 9 10 package Visitors.Doule;public class B { public void method (A a) { System.out.println(a.name); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 package Visitors.Doule;import org.junit.jupiter.api.Test;public class TestClass { @Test public void test () { A a = new A (); a.getBMethods(new B ()); } }
迭代器模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 classDiagram class Iterator Iterator : boolean hasNext Iterator : E next Iterator : void remove class ConcreteIterator ConcreteIterator <|-- Iterator class Aggregate Aggregate : void createIterator class ConcreteAggregate ConcreteAggregate <|-- Aggregate ConcreteAggregate <|-- ConcreteIterator ConcreteAggregate : ArrayList elements
1 2 3 4 5 6 7 8 9 10 11 12 13 14 package Iterator;import java.util.Iterator;import java.util.List;public interface College { public Iterator getIterator () ; }
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 package Iterator;import java.util.ArrayList;import java.util.Iterator;import java.util.List;public class ComputerCollege implements College { List<Department> list; String name = "computer" ; public ComputerCollege () { list = new ArrayList <>(); list.add(new Department ("66" )); list.add(new Department ("77" )); } @Override public Iterator getIterator () { return new ComputerIterator (list); } public String toString () { return name; } }
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 package Iterator;import java.util.Iterator;import java.util.List;public class ComputerIterator implements Iterator { List<Department> list; int index = 0 ; @Override public boolean hasNext () { if (index < list.size())return true ; return false ; } @Override public Object next () { return list.get(index++); } public ComputerIterator (List<Department> list) { this .list = list; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package Iterator;public class Department { String name; public Department (String name) { this .name = name; } public String toString () { return name; } }
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 package Iterator;import java.util.Iterator;import java.util.List;public class OutPutImpl { List<College> list; public OutPutImpl (List<College> list) { this .list = list; } public void printCollege () { Iterator<College> iterator = list.iterator(); while (iterator.hasNext()) { College college = iterator.next(); System.out.println(college); printDepartment(college.getIterator()); } } private void printDepartment (Iterator iterator) { while (iterator.hasNext()) { System.out.println(iterator.next()); } } }
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 package Iterator;import java.util.ArrayList;import org.junit.jupiter.api.Test;public class TestClass { @Test public void client () { ArrayList<College> list = new ArrayList (); list.add(new ComputerCollege ()); OutPutImpl impl = new OutPutImpl (list); impl.printCollege(); } }
观察者模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 classDiagram class Subject Subject : registeObeserver Subject : removeObserver Subject : notifyObserver class Data Data : List<Observer> list Data <|-- Subject Data : setNewValue class Observer Observer : update Observer : show class CurrentCondition CurrentCondition <|-- Observer Data <|-- CurrentCondition
1 2 3 4 5 6 7 8 9 10 package Observer;public interface Subject { public void registObserver (Observer o) ; public void removerObserver (Observer o) ; public void notifyObserver () ; }
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 package Observer;import java.util.ArrayList;import java.util.List;public class WeatherData implements Subject { List<Observer> list; double value; public WeatherData () { list = new ArrayList (); } @Override public void notifyObserver () { for (Observer o : list) o.update(value); } @Override public void registObserver (Observer o) { if (!list.contains(o)) list.add(o); } @Override public void removerObserver (Observer o) { if (list.contains(o)) list.remove(o); } public void valueReset (double v) { value = v; notifyObserver(); } }
1 2 3 4 5 6 7 8 package Observer;public interface Observer { public void update (double value) ; public void show (double value) ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 package Observer;public class CurrentCondition implements Observer { @Override public void update (double value) { show(value); } @Override public void show (double value) { System.out.println("new value: " + value); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 package Observer;public class BaiduObserver implements Observer { @Override public void show (double value) { System.out.println("baidu: " + value); } @Override public void update (double value) { show(value); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 package Observer;import org.junit.jupiter.api.Test;public class Client { public static void main (String[] args) { WeatherData data = new WeatherData (); CurrentCondition condition = new CurrentCondition (); data.registObserver(condition); data.registObserver(new BaiduObserver ()); data.valueReset(2 ); } }
中介者模式
1 2 3 4 5 6 7 8 9 10 11 package Mediator;public abstract class Mediator { public abstract void registerColleague (Colleague colleague) ; public abstract void removeColleague (Colleague colleague) ; public abstract void getMessage (Colleague colleague,int index) ; }
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 package Mediator;import java.util.ArrayList;import java.util.List;public class ConcreteMediator extends Mediator { List<Colleague> list; public ConcreteMediator () { list = new ArrayList (); } @Override public void registerColleague (Colleague colleague) { list.add(colleague); } @Override public void removeColleague (Colleague colleague) { list.remove(colleague); } @Override public void getMessage (Colleague colleague,int index) { } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package Mediator;public abstract class Colleague { public Colleague (String name,Mediator mediator) { this .name = name; this .mediator = mediator; } String name; Mediator mediator; public abstract void sendMessage () ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 package Mediator;public class ConcreteColleague extends Colleague { public ConcreteColleague (String name,Mediator mediator) { super (name,mediator); } @Override public void sendMessage () { this .mediator.getMessage(this ,1 ); } }
备忘录模式
解释器模式
状态模式
策略模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 package Strategy;public abstract class Duck { Fly fly; Quack quack; void duckFly () { this .fly.fly(); } void duckQuack () { this .quack.quack(); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package Strategy;public class ToyDuck extends Duck { public ToyDuck () { this .fly = new BadFly (); this .quack = new BadQuack (); } }
1 2 3 4 5 6 7 package Strategy;public interface Fly { void fly () ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 package Strategy;public class BadFly implements Fly { @Override public void fly () { System.out.println("bad fly" ); } }
1 2 3 4 5 6 7 package Strategy;public interface Quack { void quack () ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 package Strategy;public class BadQuack implements Quack { @Override public void quack () { System.out.println("bad quack" ); } }
职责链模式
补充
增强耦合的方法
继承
if...else...(当出现多个if...else...时)
volatile关键词
摘自:https://www.cnblogs.com/zhengbin/p/5654805.html
先补充一下概念:Java
内存模型中的可见性、原子性和有序性。
可见性:
可见性是一种复杂的属性,因为可见性中的错误总是会违背我们的直觉。通常,我们无法确保执行读操作的线程能适时地看到其他线程写入的值,有时甚至是根本不可能的事情。为了确保多个线程之间对内存写入操作的可见性,必须使用同步机制。
可见性,是指线程之间的可见性,一个线程修改的状态对另一个线程是可见的。 也就是一个线程修改的结果。另一个线程马上就能看到。比如:用volatile修饰的变量,就会具有可见性。volatile修饰的变量不允许线程内部缓存和重排序,即直接修改内存。所以对其他线程是可见的。但是这里需要注意一个问题,volatile只能让被他修饰内容具有可见性,但不能保证它具有原子性。比如
volatile int a = 0;之后有一个操作 a++;这个变量a具有可见性,但是a++
依然是一个非原子操作,也就是这个操作同样存在线程安全问题。
在 Java 中 volatile、synchronized 和 final 实现可见性。
原子性:
原子是世界上的最小单位,具有不可分割性。 比如
a=0;(a非long和double类型)
这个操作是不可分割的,那么我们说这个操作时原子操作。再比如:a++;
这个操作实际是a = a +
1;是可分割的,所以他不是一个原子操作。非原子操作都会存在线程安全问题,需要我们使用同步技术(sychronized)来让它变成一个原子操作。一个操作是原子操作,那么我们称它具有原子性。java的concurrent包下提供了一些原子类,我们可以通过阅读API来了解这些原子类的用法。比如:AtomicInteger、AtomicLong、AtomicReference等。
在 Java 中 synchronized 和在 lock、unlock 中操作保证原子性。
有序性:
Java 语言提供了 volatile 和 synchronized
两个关键字来保证线程之间操作的有序性,volatile
是因为其本身包含“禁止指令重排序”的语义,synchronized
是由“一个变量在同一个时刻只允许一条线程对其进行 lock
操作”这条规则获得的,此规则决定了持有同一个对象锁的两个同步块只能串行执行。
Java语言提供了一种稍弱的同步机制,即volatile变量,用来确保将变量的更新操作通知到其他线程。当把变量声明为volatile类型后,编译器与运行时都会注意到这个变量是共享的,因此不会将该变量上的操作与其他内存操作一起重排序。volatile变量不会被缓存在寄存器或者对其他处理器不可见的地方,因此在读取volatile类型的变量时总会返回最新写入的值。
在访问volatile变量时不会执行加锁操作,因此也就不会使执行线程阻塞,因此volatile变量是一种比sychronized关键字更轻量级的同步机制。
当对非 volatile
变量进行读写的时候,每个线程先从内存拷贝变量到CPU缓存中。如果计算机有多个CPU,每个线程可能在不同的CPU上被处理,这意味着每个线程可以拷贝到不同的
CPU cache 中。
而声明变量是 volatile 的,JVM 保证了每次读变量都从内存中读,跳过
CPU cache 这一步。
当一个变量定义为
volatile 之后,将具备两种特性:
1.保证此变量对所有的线程的可见性,这里的“可见性”,如本文开头所述,当一个线程修改了这个变量的值,volatile
保证了新值能立即同步到主内存,以及每次使用前立即从主内存刷新。但普通变量做不到这点,普通变量的值在线程间传递均需要通过主内存(详见:Java内存模型 )来完成。
2.禁止指令重排序优化。有volatile修饰的变量,赋值后多执行了一个“load
addl $0x0,
(%esp)”操作,这个操作相当于一个内存屏障 (指令重排序时不能把后面的指令重排序到内存屏障之前的位置),只有一个CPU访问内存时,并不需要内存屏障;(什么是指令重排序:是指CPU采用了允许将多条指令不按程序规定的顺序分开发送给各相应电路单元处理)。
volatile 性能:
volatile
的读性能消耗与普通变量几乎相同,但是写操作稍慢,因为它需要在本地代码中插入许多内存屏障指令来保证处理器不发生乱序执行。
浅拷贝和深拷贝
浅拷贝
深拷贝
实现方法:
通过重写clone函数进行深拷贝:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public class DeepClone implements Cloneable ,Serializable{ public CopiedClass c = new CopiedClass (); @Override protected Object clone () throws CloneNotSupportedException { DeepClone instance = null ; instance = (DeepClone) super .clone(); instance.c = (CopiedClass) c.clone(); return instance; } }
通过序列化实现深拷贝(推荐)
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 public class DeepClone implements Cloneable ,Serializable{ public CopiedClass c = new CopiedClass (); public DeepClone deepClone () { DeepClone instance = null ; ByteArrayOutputStream bos = null ; ObjectOutputStream oos = null ; ByteArrayInputStream bis = null ; ObjectInputStream ois = null ; try { bos = new ByteArrayOutputStream (); oos = new ObjectOutputStream (bos); oos.writeObject(this ); bis = new ByteArrayInputStream (bos.toByteArray()); ois = new ObjectInputStream (bis); instance = (DeepClone)ois.readObject(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { try { bos.close(); oos.close(); bis.close(); ois.close(); } catch (IOException e) { e.printStackTrace(); } } return instance; } }public class CopiedClass implements Cloneable ,Serializable{ String name; public CopiedClass (String name) { this .name = name; } public CopiedClass () { } @Override protected Object clone () throws CloneNotSupportedException { return super .clone(); } @Test public void test () throws CloneNotSupportedException { CopiedClass a = new CopiedClass ("ych" ); CopiedClass b = (CopiedClass) a.clone(); } }
Iteraior接口
接口方法:
boolean hasNext()
E next()
void remove()
迭代器一般设置成内部类,设置index进行元素的判断,在调用外部类进行内部类的创建
```java package
Iterator.MyIterator;
import java.util.ArrayList; import java.util.Iterator; import
java.util.List;
public class A { List list = new ArrayList();
public A() { // TODO Auto-generated constructor stub list.add(new
B("66")); list.add(new B("77")); list.add(new B("88"));
}
public Iterator iterator() { return new AIterator(); } // 内部类
class AIterator implements Iterator{
int index = 0;
public AIterator() {
// TODO Auto-generated constructor stub
}
@Override
public boolean hasNext() {
// TODO Auto-generated method stub
if(index < list.size())return true;
return false;
}
@Override
public Object next() {
// TODO Auto-generated method stub
return list.get(index++);
}
}
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ```java package Iterator.MyIterator; public class B { String name; public B(String name) { // TODO Auto-generated constructor stub this.name = name; } public String toString() { return name; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 package Iterator.MyIterator;import java.util.Iterator;import org.junit.jupiter.api.Test;public class TestClass { @Test public void test () { A a = new A (); Iterator iterator = a.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); } } }
JDK Observable源码分析
Arrays.sort的lambda表达式用法
1 2 3 4 5 6 7 8 9 10 11 @Test public void test () { Integer arr[] = {9 ,6 ,3 ,8 ,5 ,2 ,7 ,4 ,1 }; Arrays.sort(arr,(var1,var2) -> { if (var1.compareTo(var2) > 0 )return 1 ; else return -1 ; }); System.out.println(Arrays.toString(arr)); }