设计模式 UML & java code
A: 创造性模式
1. 工厂方法模式(FactoryMethod)
1.1 类图
1.2 代码1
public interface Pet { public String petSound(); } public class Cat implements Pet { @Override public String petSound() { return "Meaw Meaw..."; } } public class Dog implements Pet { @Override public String petSound() { return "Bow Bow..."; } } public class PetFactory { public Pet getPet(String petType){ Pet pet = null; if("Bow".equals(petType)){ pet = new Dog(); }else if("Meaw".equals(petType)){ pet = new Cat(); } return pet; } } public class SampleFactoryMethod { public static void main(String[] args){ PetFactory factory = new PetFactory(); Pet pet = factory.getPet("Bow"); System.out.println(pet.petSound()); } }
代码2 (泛型)
public abstract class Product { public void method1(){ // }; public abstract void method2(); } public class ConcreateProduct1 extends Product { @Override public void method2() { } } public class ConcreateProduct2 extends Product { @Override public void method2() { } } public abstract class Creator { public abstract <T extends Product> T createProduct(Class<T> c); } public class ConcreateCreator extends Creator { @Override public <T extends Product> T createProduct(Class<T> c) { Product instance = null; try { instance = (Product) Class.forName(c.getName()).newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } return (T)instance; } } public class Client { public static void main(String[] args){ Creator creator = new ConcreateCreator(); ConcreateProduct1 product1 = creator.createProduct(ConcreateProduct1.class); } }
2. 抽象工厂模式(AbstractFactory)
2.1 类图
2.2 代码
package org.rocky.learn.designPattern.AbstractFactory; /** * Created by admin on 2018/3/20. */ public abstract class Car { public abstract Parts getWheels(); public abstract Parts getMirrors(); public abstract Parts getEngine(); public abstract Parts getBody(); } package org.rocky.learn.designPattern.AbstractFactory; /** * Created by admin on 2018/3/20. */ public class Parts { private String specification; public Parts(String specification){ this.specification = specification; } public String getSpecification(){ return specification; } } package org.rocky.learn.designPattern.AbstractFactory; /** * Created by admin on 2018/3/20. */ public class BenQ extends Car { @Override public Parts getWheels() { return new Parts("BenQ Wheels"); } @Override public Parts getMirrors() { return new Parts("BenQ Mirriors"); } @Override public Parts getEngine() { return new Parts("BenQ Engine"); } @Override public Parts getBody() { return new Parts("BenQ body"); } } package org.rocky.learn.designPattern.AbstractFactory; /** * Created by admin on 2018/3/20. */ public class BMW extends Car { @Override public Parts getWheels() { return new Parts("BMW Wheels"); } @Override public Parts getMirrors() { return new Parts("BMW Mirrors"); } @Override public Parts getEngine() { return new Parts("BMW Engine"); } @Override public Parts getBody() { return new Parts("BMW Body"); } } package org.rocky.learn.designPattern.AbstractFactory; /** * Created by admin on 2018/3/20. */ public class CarType { private Car car; public Car getCar(String carType){ if("BenQ".equals(carType)){ car = new BenQ(); }else if("BMW".equals(carType)){ car = new BMW(); } return car; } public static void main(String[] args){ CarType carType = new CarType(); Car benQ = carType.getCar("BenQ"); System.out.println(benQ.getWheels().getSpecification()); System.out.println(benQ.getMirrors().getSpecification()); System.out.println(benQ.getEngine().getSpecification()); System.out.println(benQ.getBody().getSpecification()); } }
3. 建造者模式(Builder)
克隆对象分为浅层复制和深层复制
3.1 类图
3.2 代码1
public interface CarPlan { public void setBase(String basement); public void setWheels(String structure); } public class Car implements CarPlan { private String base; private String wheels; @Override public void setBase(String basement) { this.base = basement; } @Override public void setWheels(String structure) { this.wheels = structure; } @Override public String toString() { return "Car{" + "base='" + base + '\'' + ", wheels='" + wheels + '\'' + '}'; } } public interface CarBuilder { public void buildBase(); public void buildWheels(); public Car getCar(); } public class LowPriceCarBuilder implements CarBuilder { private Car car; public LowPriceCarBuilder(){ car = new Car(); } @Override public void buildBase() { car.setBase("Low Price Car Base Build"); } @Override public void buildWheels() { car.setWheels("Low Price Car Wheels build"); } @Override public Car getCar() { return this.car; } } public class MechanicalEngineer { private CarBuilder carBuilder; public MechanicalEngineer(CarBuilder carBuilder){ this.carBuilder = carBuilder; } public Car getCar(){ return carBuilder.getCar(); } public void buildCar(){ carBuilder.buildBase(); carBuilder.buildWheels(); } public static void main(String[] args){ CarBuilder lowPriceCarBuilder = new LowPriceCarBuilder(); MechanicalEngineer mechanicalEngineer = new MechanicalEngineer(lowPriceCarBuilder); mechanicalEngineer.buildCar(); Car car = mechanicalEngineer.getCar(); System.out.print("Builder constructor car.."+car); } }
java的api中 StringBuilder 和 StringBuffer是使用的生成器模式实例
代码2
public abstract class House { protected Floor floor; protected Walls walls; protected Roof roof; public Floor getFloor() { return floor; } public void setFloor(Floor floor) { this.floor = floor; } public Walls getWalls() { return walls; } public void setWalls(Walls walls) { this.walls = walls; } public Roof getRoof() { return roof; } public void setRoof(Roof roof) { this.roof = roof; } public abstract String getRepresentation(); } public interface Floor { public String getRepresentation(); } public interface Walls { public String getRepresentation(); } public interface Roof { public String getRepresentation(); } package org.rocky.learn.designPattern.BuilderPattern2; /** * Created by admin on 2018/3/20. */ public class WoodHouse extends House { @Override public String getRepresentation() { return "Build Wood House"; } } package org.rocky.learn.designPattern.BuilderPattern2; /** * Created by admin on 2018/3/20. */ public class WoodFloor implements Floor { @Override public String getRepresentation() { return "Build Wood Floor.."; } } public class WoodWalls implements Walls { @Override public String getRepresentation() { return "Build Wood Walls"; } } public class WoodRoof implements Roof { @Override public String getRepresentation() { return "Build Wood Roof"; } } public abstract class HouseBuilder { protected House house; protected Floor floor; protected Walls walls; protected Roof roof; public abstract House createHouse(); public abstract Floor createFloor(); public abstract Walls createWalls(); public abstract Roof createRoof(); } public class WoodBuilder extends HouseBuilder { @Override public House createHouse() { house = new WoodHouse(); return house; } @Override public Floor createFloor() { floor = new WoodFloor(); return floor; } @Override public Walls createWalls() { walls = new WoodWalls(); return walls; } @Override public Roof createRoof() { roof = new WoodRoof(); return roof; } } public class HouseDirector { public House constructHouse(HouseBuilder houseBuilder){ House house = houseBuilder.createHouse(); System.out.println(house.getRepresentation()); house.setFloor(houseBuilder.createFloor()); System.out.println(house.getFloor().getRepresentation()); house.setWalls(houseBuilder.createWalls()); System.out.println(house.getWalls().getRepresentation()); house.setRoof(houseBuilder.createRoof()); System.out.println(house.getRoof().getRepresentation()); return house; } } public class HouseClient { public static void main(String[] args){ HouseDirector director = new HouseDirector(); HouseBuilder houseBuilder = new WoodBuilder(); director.constructHouse(houseBuilder); } }
4. 单例模式(Singleton)
4.1 UML类图
4.2 代码1 被动实例化
package org.rocky.learn.designPattern.Singleton; /** * Created by admin on 2018/3/20. */ public class SingletonPassive { private static SingletonPassive singleton; private SingletonPassive(){} public static SingletonPassive getSingleton(){ if(singleton == null){ synchronized (SingletonPassive.class){ if(singleton == null){ singleton = new SingletonPassive(); } } } return singleton; } }
代码2 主动实例化
public class SingletonProactive { private static SingletonProactive singleton = new SingletonProactive(); private SingletonProactive(){} public static SingletonProactive getSingleton(){ return singleton; } }
5. 原型模式(prototype)
5.1 UML类图
5.2 代码
//浅拷贝 package org.rocky.learn.designPattern.PrototypePattern; import java.util.ArrayList; import java.util.Date; import java.util.List; /** * Created by admin on 2018/3/21. */ public class Plan implements Cloneable { //计划名称 private String name; //任务级别 private int level; //开始时间 private Date startdate; //截止时间 private Date enddate; //执行人员 private List<String> executors = new ArrayList<String>(); @Override public Plan clone(){ try { return (Plan) super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return null; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Date getStartdate() { return startdate; } public void setStartdate(Date startdate) { this.startdate = startdate; } public Date getEnddate() { return enddate; } public void setEnddate(Date enddate) { this.enddate = enddate; } public List<String> getExecutors() { return executors; } public void setExecutors(List<String> executors) { this.executors = executors; } public int getLevel() { return level; } public void setLevel(int level) { this.level = level; } @Override public String toString() { return "[name=" + name + ", level=" + level + ", startdate=" + startdate + ", enddate=" + enddate + ", executors=" + executors + "]"; } } //client package org.rocky.learn.designPattern.PrototypePattern; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.List; /** * Created by admin on 2018/3/21. */ public class Client { private static final String format = "YYYY-mm-dd"; public static void main(String[] args) throws ParseException { List<String> executors = new ArrayList<String>(); executors.add("张三"); executors.add("李四"); Plan plan = new Plan(); plan.setName("重构前端登录界面"); plan.setLevel(1); plan.setStartdate(new SimpleDateFormat(format).parse("2017-08-07")); plan.setEnddate(new SimpleDateFormat(format).parse("2017-08-07")); plan.setExecutors(executors); Plan plan2 = plan.clone(); plan2.setName("后端接口改造"); plan2.setLevel(2); plan2.setStartdate(new SimpleDateFormat(format).parse("2017-08-07")); plan2.setEnddate(new SimpleDateFormat(format).parse("2017-08-07")); System.out.println("地址是否一样?"+(plan == plan2)); System.out.println("plan.getName() == plan2.getName() "+(plan.getName() == plan2.getName())); System.out.println("plan.getLevel() == plan2.getLevel() "+(plan.getLevel() == plan2.getLevel())); System.out.println("plan.getStartdate() == plan2.getStartdate() "+(plan.getStartdate() == plan2.getStartdate())); System.out.println("plan.getEnddate() == plan2.getEnddate() "+(plan.getEnddate() == plan2.getEnddate())); System.out.println("plan.getExecutors() == plan2.getExecutors() "+(plan.getExecutors() == plan2.getExecutors())); System.out.println("plan:"+plan.toString()); System.out.println("plan2:"+plan2.toString()); //plan任务比较重,在给plan添加一个人 executors.add("王五"); plan.setExecutors(executors); System.out.println(); System.out.println("地址是否一样?"+(plan == plan2)); System.out.println("plan.getName() == plan2.getName() "+(plan.getName() == plan2.getName())); System.out.println("plan.getLevel() == plan2.getLevel() "+(plan.getLevel() == plan2.getLevel())); System.out.println("plan.getStartdate() == plan2.getStartdate() "+(plan.getStartdate() == plan2.getStartdate())); System.out.println("plan.getEnddate() == plan2.getEnddate() "+(plan.getEnddate() == plan2.getEnddate())); System.out.println("plan.getExecutors() == plan2.getExecutors() "+(plan.getExecutors() == plan2.getExecutors())); System.out.println("plan:"+plan.toString()); System.out.println("plan2:"+plan2.toString()); } } //深拷贝 clone方法 package org.rocky.learn.designPattern.PrototypePattern; import java.util.ArrayList; import java.util.Date; import java.util.List; /** * Created by admin on 2018/3/21. */ public class PlanDeeper { //计划名称 private String name; //任务级别 private int level; //开始时间 private Date startdate; //截止时间 private Date enddate; //执行人员 private List<String> executors = new ArrayList<String>(); @Override public Plan clone(){ try { Plan plan = (Plan) super.clone(); //引用类型的属性,需要处理 if(this.getExecutors() != null){ List<String> _executors = new ArrayList<String>(); for(String s : this.getExecutors()){ _executors.add(s); } plan.setExecutors(_executors); } return plan; } catch (CloneNotSupportedException e) { e.printStackTrace(); } return null; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Date getStartdate() { return startdate; } public void setStartdate(Date startdate) { this.startdate = startdate; } public Date getEnddate() { return enddate; } public void setEnddate(Date enddate) { this.enddate = enddate; } public List<String> getExecutors() { return executors; } public void setExecutors(List<String> executors) { this.executors = executors; } public int getLevel() { return level; } public void setLevel(int level) { this.level = level; } @Override public String toString() { return "[name=" + name + ", level=" + level + ", startdate=" + startdate + ", enddate=" + enddate + ", executors=" + executors + "]"; } }
说明 见 3-2
B: 结构型模式
6.适配器模式(Adaptor)
6.1 UML类图
有两种应用适配器模式的方法
使用继承【类适配器】
使用关联【对象适配器】
6.2 代码
a: 使用继承【类适配器】
public class Plug { private String specification; protected String getInput(){ return specification; } public Plug(){ specification = "3-Pin"; } } public interface Socket { public String getInput(); } public class ExpansionAdaptor extends Plug implements Socket { @Override public String getInput() { String input = super.getInput(); input += " converted to 2-Pin"; return input; } } public class Client { public static void main(String[] args){ Socket socket = new ExpansionAdaptor(); String input = socket.getInput(); System.out.print(input); } }
b: 使用关联【对象适配器】
public class ExpansionAdapter implements Socket { private Plug plug; public ExpansionAdapter(Plug p){ plug = p; } @Override public String getInput() { String input = plug.getInput(); input += " power converted to 2-Pin"; return input; } } public static void main(String[] args){ Socket socket = new ExpansionAdapter(new Plug()); String input = socket.getInput(); System.out.println(input); }
7. 桥接模式
7.1 UML图
7.2 代码
public interface TV { public void powerOn(); public void powerOff(); public void changeChannel(int channel); } public class GoogleTV implements TV { @Override public void powerOn() { } @Override public void powerOff() { } @Override public void changeChannel(int channel) { } } public class AppleTV implements TV { @Override public void powerOn() { } @Override public void powerOff() { } @Override public void changeChannel(int channel) { } } public abstract class TVRemoteControl { private TV implementor; public void powerOn(){ implementor.powerOn(); } public void powerOff(){ implementor.powerOff(); } public void setChannel(int channel){ implementor.changeChannel(channel); } } public class ConcreteTVRemoteControl extends TVRemoteControl { private int currentChannel; public void nextChannel(){ currentChannel++; setChannel(currentChannel); } public void previousChannel(){ currentChannel--; setChannel(currentChannel); } }
8. 组合模式
8.1 UML类图
8.2 代码
public interface FileComponent { public void printName(); } public class LeafFile implements FileComponent { private String fileName; public LeafFile(String name){ fileName = name; } @Override public void printName() { System.out.println(fileName); } } public class Directory implements FileComponent { private String fileName; public Directory(String name){ fileName = name; } private List files = new ArrayList(); public void add(FileComponent component){ files.add(component); } @Override public void printName() { System.out.println("Directory name : "+ fileName); for(int i=0; i< files.size(); i++){ FileComponent component = (FileComponent) files.get(i); component.printName(); } } } public class CompositeDemo { public static void main(String[] args){ Directory one = new Directory("dir-1"); Directory two = new Directory("dir-2"); Directory three = new Directory("dir-3"); LeafFile a = new LeafFile("file-a"); LeafFile b = new LeafFile("file-b"); LeafFile c = new LeafFile("file-c"); LeafFile d = new LeafFile("file-d"); one.add(a); one.add(two); two.add(b); two.add(c); two.add(three); three.add(d); one.printName(); } }
9. 装饰模式
9.1 UML类图
9.2 代码1
public interface House { public String makeHouse(); } public class SimpleHouse implements House { @Override public String makeHouse() { return "Base House"; } } public class HouseDecorator implements House { protected House house; public HouseDecorator(House house){ this.house = house; } @Override public String makeHouse() { return house.makeHouse(); } } public class ColorDecorator extends HouseDecorator { public ColorDecorator(House house){ super(house); } private String addColor(){ return " + red color"; } public String makeHouse(){ return house.makeHouse() + addColor(); } } public class LightsDecorator extends HouseDecorator { public LightsDecorator(House house) { super(house); } private String addLights(){ return " + LED lights"; } public String makeHouse(){ return house.makeHouse() + addLights(); } }
java API中 IO流用到装饰模式 (new BufferedReader(new FileReader("a.txt")))
代码2
public interface Coffee { public double getCosts();//加格 public String getIngredients();//成分 } public class SimpleCoffee implements Coffee { @Override public double getCosts() { return 1; } @Override public String getIngredients() { return "Coffee"; } } public abstract class CoffeeDecorator implements Coffee { protected final Coffee decoratedCoffee; protected String ingredientSeparator = ","; public CoffeeDecorator(Coffee coffee){ decoratedCoffee = coffee; } @Override public double getCosts() { return decoratedCoffee.getCosts(); } @Override public String getIngredients() { return decoratedCoffee.getIngredients(); } } public class Milk extends CoffeeDecorator { public Milk(Coffee coffee) { super(coffee); } public double getCost(){ return super.getCosts() + 0.5; } public String getIngredients(){ return super.getIngredients() + ingredientSeparator + " Milk"; } } public class Whip extends CoffeeDecorator { public Whip(Coffee coffee) { super(coffee); } public double getCosts(){ return super.getCosts() + 0.7; } public String getIngredients(){ return super.getIngredients() + ingredientSeparator + " Whip"; } } public class Sprinkles extends CoffeeDecorator { public Sprinkles(Coffee coffee) { super(coffee); } public double getCosts(){ return super.getCosts() + 0.2; } public String getIngredients(){ return super.getIngredients() + ingredientSeparator + " Sprinkles"; } } public class DecoratorTest { public static void main(String[] args){ Coffee c = new SimpleCoffee(); System.out.println("Cost:"+c.getCosts() + ",ingredients:"+ c.getIngredients()); c = new Milk(c); System.out.println("Cost:"+c.getCosts() + ",ingredients:"+ c.getIngredients()); c = new Whip(c); System.out.println("Cost:"+c.getCosts() + ",ingredients:"+ c.getIngredients()); c = new Sprinkles(c); System.out.println("Cost:"+c.getCosts() + ",ingredients:"+ c.getIngredients()); } }
10. 门面模式
10.1 UML类图
10.2 代码
public class GUIMenu { public void drawMenuButtons(){} } public class GUITitleBar { public void showTitleBar(String caption){} } public class GUIContent { public void showButtons(){} public void showTextFields(){} public void setDefaultValues(){} } public class MyGUI { private GUIContent guiContent; private GUIMenu guiMenu; private GUITitleBar guiTitleBar; public MyGUI(){ guiContent = new GUIContent(); guiMenu = new GUIMenu(); guiTitleBar = new GUITitleBar(); } public void drawGUI(){ guiContent.setDefaultValues(); guiContent.showButtons(); guiContent.showTextFields(); guiTitleBar.showTitleBar("My gui"); guiMenu.drawMenuButtons(); } } public class TestFacade { public static void main(String[] args){ MyGUI myGUI = new MyGUI(); myGUI.drawGUI(); } }
11. 代理模式
11.1 UML类图
11.2 代码
public interface Image { public void showImage(); } public class RealImage implements Image { public RealImage(URL url){ loadImage(url); } public void loadImage(URL url) { } @Override public void showImage() { } } public class ProxyImage implements Image { private URL url; public ProxyImage(URL url){ this.url = url; } @Override public void showImage() { RealImage realImage = new RealImage(url); realImage.showImage(); } } public class ProxyTest { public static void main(String[] args){ try { Image image1 = new ProxyImage(new URL("http","ip","TestFloder/1.jpg")); Image image2 = new ProxyImage(new URL("http","ip","TestFloder/2.jpg")); Image image3 = new ProxyImage(new URL("http","ip","TestFloder/3.jpg")); image1.showImage();//被加载到内存中 } catch (MalformedURLException e) { e.printStackTrace(); } } }
12. 享元模式
12.1 UML类图
对象属性分为内蕴状态 和 外蕴状态
12.2 代码
public interface MyShape { public void draw(Graphics g, int x, int y, int width, int height, Color color, boolean fill, String font); } public class MyOval implements MyShape { private String label; public MyOval(String label){ this.label = label; } @Override public void draw(Graphics oval, int x, int y, int width, int height, Color color, boolean fill, String font) { oval.setColor(color); oval.drawOval(x, y, width, height); oval.setFont(new Font(font, 12, 12)); oval.drawString(label, x+(width/2), y); if(fill) oval.fillOval(x, y, width, height); } } public class MyRectangle implements MyShape { private String label; public MyRectangle(String label){ this.label = label; } @Override public void draw(Graphics rectangle, int x, int y, int width, int height, Color color, boolean fill, String font) { rectangle.setColor(color); rectangle.drawRect(x, y, width, height); rectangle.setFont(new Font(font, 12, 12)); rectangle.drawString(label, x+(width/2), y); if(fill) rectangle.fillRect(x, y, width, height); } } public class ShapeFactory { private static final HashMap shapes = new HashMap(); public static MyShape getShape(String label){ MyShape concreteShape = (MyShape) shapes.get(label); if(concreteShape == null){ if("R".equals(label)){ concreteShape = new MyRectangle(label); }else if("O".equals(label)){ concreteShape = new MyOval(label); } } return concreteShape; } } public class Client extends JFrame{ private static final int WIDTH = 300; private static final int HEIGHT = 300; private static final String[] shapes = {"R", "O"}; private static final Color colors[] = {Color.blue, Color.black, Color.red}; private static final boolean fill[] = {true, false}; private static final String font[] = {"Arial", "Courier"}; public Client(){ Container contentPane = getContentPane(); JButton startButton = new JButton("Draw Shapes"); final JPanel panel = new JPanel(); contentPane.add(panel, BorderLayout.CENTER); contentPane.add(startButton, BorderLayout.SOUTH); setSize(WIDTH, HEIGHT); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setVisible(true); startButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent event) { Graphics graphics = panel.getGraphics(); MyShape shape = ShapeFactory.getShape(getRandomShape()); shape.draw(graphics, getRandomX(), getRandomY(), getRandomWidth(), getRandomHeight(), getRandomColor(), getRandomFill(), getRandomFont()); } }); } private String getRandomShape(){ return shapes[(int)Math.random()*shapes.length]; } private int getRandomX(){ return (int) (Math.random()*WIDTH); } private int getRandomY(){ return (int) (Math.random()*HEIGHT); } private int getRandomWidth(){ return (int) (Math.random()*(getWidth()/7)); } private int getRandomHeight(){ return (int) (Math.random()*(getHeight()/7)); } private Color getRandomColor(){ return colors[(int) (Math.random()*colors.length)]; } private boolean getRandomFill(){ return fill[(int) (Math.random()*fill.length)]; } private String getRandomFont(){ return font[(int) (Math.random()*font.length)]; } public static void main(String[] args){ Client client = new Client(); } }
C: 行为型模式
处理不同的对象间的通信关系
13. 职责链模式
13.1 UML类图
13.2 代码
列子: Servlet过滤器和JAVA异常处理机制
public abstract class Logger { public static int ERR = 3; public static int NOTICE = 5; public static int DEBUG = 7; protected int mask; //链中的下一个元素 protected Logger next; public Logger setNext(Logger log){ next = log; return log; } public void message(String msg, int priority){ if(priority <= mask){ writeMessage(msg); } if(next != null){ next.message(msg, priority); } } protected abstract void writeMessage(String msg); } public class StdoutLogger extends Logger { public StdoutLogger(int mask){ this.mask = mask; } @Override protected void writeMessage(String msg) { System.out.println("Writing to stdout:"+msg); } } public class EmailLogger extends Logger { public EmailLogger(int mask){ this.mask = mask; } @Override protected void writeMessage(String msg) { System.out.println("Sending via email:"+msg); } } public class StderrLogger extends Logger { public StderrLogger(int mask){ this.mask = mask; } @Override protected void writeMessage(String msg) { System.err.println("Sending to stderr:"+msg); } } public class ChainOfResponsibilityExample { public static void main(String[] args){ //创建职责链 Logger logger, logger1, logger2; logger = new StdoutLogger(Logger.DEBUG); logger1 = logger.setNext(new EmailLogger(Logger.NOTICE)); logger2 = logger1.setNext(new StderrLogger(Logger.ERR)); //由StdoutLogger进行处理 logger.message("Entering function a:", Logger.DEBUG); //由StdoutLogger 和 EmailLogger进行处理 logger.message("Step 1 finished", Logger.NOTICE); //由三个处理器一起完成 logger.message("An error has occurred", Logger.ERR); } }
14. 命令模式
14.1 UML类图
14.2 代码
public interface Command { void execute(); } /**接收类*/ public class AirConditioner { public AirConditioner(){} public void start(){ System.out.println("The airconditioner is on"); } public void stop(){ System.out.println("The airconditioner is off"); } } /**调用类*/ public class Switch { private List<Command> commandHistory = new ArrayList<Command>(); public Switch(){} public void storeAndExecute(Command command){ this.commandHistory.add(command); command.execute(); } } public class StartCommand implements Command { private AirConditioner theAirConditioner; public StartCommand(AirConditioner airConditioner){ theAirConditioner = airConditioner; } @Override public void execute() { theAirConditioner.start(); } } public class StopCommand implements Command { private AirConditioner theAirConditioner; public StopCommand(AirConditioner airConditioner){ theAirConditioner = airConditioner; } @Override public void execute() { theAirConditioner.stop(); } } public class PressSwitch { public static void main(String[] args){ AirConditioner airConditioner = new AirConditioner(); Command startCommand = new StartCommand(airConditioner); StopCommand stopCommand = new StopCommand(airConditioner); Switch sw = new Switch(); sw.storeAndExecute(startCommand); sw.storeAndExecute(stopCommand); } }
15. 解释器模式
15.1 UML类图
15.2 代码
public abstract class Expression { public abstract boolean interpret(String str); } public class TerminalExpression extends Expression { private String literal; public TerminalExpression(String str){ literal = str; } @Override public boolean interpret(String str) { StringTokenizer st = new StringTokenizer(str); while (st.hasMoreTokens()){ String s = st.nextToken(); if(s.equals(literal)){ return true; } } return false; } } public class OrExpression extends Expression { private Expression expression1 = null; private Expression expression2 = null; public OrExpression(Expression expression1, Expression expression2){ this.expression1 = expression1; this.expression2 = expression2; } @Override public boolean interpret(String str) { return expression1.interpret(str) || expression2.interpret(str); } } public class AndExpression extends Expression { private Expression expression1 = null; private Expression expression2 = null; public AndExpression(Expression expression1, Expression expression2){ this.expression1 = expression1; this.expression2 = expression2; } @Override public boolean interpret(String str) { return expression1.interpret(str) && expression2.interpret(str); } } public class InterpretTest { static Expression buildInterpretTree(){ //字面含义 Expression terminal1 = new TerminalExpression("Name1"); Expression terminal2 = new TerminalExpression("Name2"); Expression terminal3 = new TerminalExpression("Name3"); Expression terminal4 = new TerminalExpression("Name4"); Expression alternation1 = new OrExpression(terminal2, terminal3); Expression alternation2 = new OrExpression(terminal1, alternation1); Expression expression = new AndExpression(terminal4, alternation2); return expression; } public static void main(String[] args){ String context = "Name4 Name3"; Expression expression = buildInterpretTree(); System.out.println(context + " is "+ expression.interpret(context)); } }
16. 迭代器模式
16.1 UML类图
16.2 代码
public class Item { String itemName; float itemPrice; public Item(String itemName, float itemPrice){ this.itemName = itemName; this.itemPrice = itemPrice; } public String toString(){ return itemName + ": "+itemPrice; } } public class Menu { List<Item> menuItems; public Menu(){ menuItems = new ArrayList<Item>(); } public void addItem(Item item){ menuItems.add(item); } public Iterator<Item> createIterator(){ return new MenuIterator(); } class MenuIterator implements Iterator<Item> { int currentIndex = 0; public boolean hasNext(){ if(currentIndex >= menuItems.size()) return false; else return true; } public Item first(){ return menuItems.get(0); } public Item currentItem(){ return menuItems.get(currentIndex); } public Item next(){ return menuItems.get(currentIndex++); } public void remove(){ menuItems.remove(--currentIndex); } } } public class IteratorTest { public static void main(String[] args){ Item item1 = new Item("item1", 10f); Item item2 = new Item("item2", 20f); Item item3 = new Item("item3", 30f); Menu menu = new Menu(); menu.addItem(item1); menu.addItem(item2); menu.addItem(item3); System.out.println("Displaying menu..."); Iterator<Item> iterator = menu.createIterator(); while (iterator.hasNext()){ Item item = iterator.next(); System.out.println(item); } System.out.println("Removing the last item returned."); iterator.remove(); System.out.println("Displaying menu..."); iterator = menu.createIterator(); while (iterator.hasNext()){ Item item = iterator.next(); System.out.println(item); } } }
17. 中介者模式
17.1 UML类图
例子 聊天程序-群聊
17.2 代码
public class Mediator { Buyer indianBuyer; Buyer frenchBuyer; AmericanSeller americanSeller; DollarConverter dollarConverter; public Mediator(){} public void registerIndianBuyer(Buyer indianBuyer){ this.indianBuyer = indianBuyer; } public void registerFrenchBuyer(Buyer frenchBuyer){ this.frenchBuyer = frenchBuyer; } public void registerAmericanSeller(AmericanSeller americanSeller){ this.americanSeller = americanSeller; } public void registerDollarConverter(DollarConverter dollarConverter){ this.dollarConverter = dollarConverter; } public boolean placeBid(float bid, String unitOfCurrency){ float dollars = dollarConverter.convertCurrencyToDollars(bid, unitOfCurrency); return americanSeller.isBidAccepted(dollars); } } public class Buyer { Mediator mediator; String unitOfCurrency; public Buyer(Mediator mediator, String unitOfCurrency){ this.mediator = mediator; this.unitOfCurrency = unitOfCurrency; } public boolean attemptToPurchase(float bid){ System.out.println("Buyer attempting a bid of "+ bid + " " + unitOfCurrency); return this.mediator.placeBid(bid, unitOfCurrency); } } public class IndianBuyer extends Buyer { public IndianBuyer(Mediator mediator) { super(mediator, "INR"); this.mediator.registerIndianBuyer(this); } } public class FrenchBuyer extends Buyer { public FrenchBuyer(Mediator mediator) { super(mediator, "EURO"); this.mediator.registerFrenchBuyer(this); } } public class AmericanSeller { Mediator mediator; float priceInDollars; public AmericanSeller(Mediator mediator, float priceInDollars){ this.mediator = mediator; this.priceInDollars = priceInDollars; this.mediator.registerAmericanSeller(this); } public boolean isBidAccepted(float bidInDollars){ if(bidInDollars >= priceInDollars){ System.out.println("Seller accepts bid of "+ bidInDollars + " dollars\n"); return true; }else{ System.out.println("Seller rejects bid of " + bidInDollars + " dollars\n"); return false; } } } public class DollarConverter { Mediator mediator; public static final float DOLLAR_UNIT = 1.0f; public static final float EURO_UNIT = 0.7f; public static final float INR_UNIT = 45.0f; public DollarConverter(Mediator mediator){ this.mediator = mediator; this.mediator.registerDollarConverter(this); } private float convertEurosToDollars(float euros){ float dollars = euros * (DOLLAR_UNIT/EURO_UNIT); System.out.println("Converting "+ euros + " euros to "+ dollars + " dollars"); return dollars; } private float convertInrToDollars(float inr){ float dollars = inr * (DOLLAR_UNIT/INR_UNIT); System.out.println("Converting "+ inr + " inr to "+ dollars + " dollars"); return dollars; } public float convertCurrencyToDollars(float amount, String unitOfCurrency){ if("INR".equals(unitOfCurrency)){ return convertInrToDollars(amount); }else return convertEurosToDollars(amount); } } public class MediatorTest { public static void main(String[] args){ Mediator mediator = new Mediator(); Buyer indianBuyer = new IndianBuyer(mediator); Buyer frenchBuyer = new FrenchBuyer(mediator); float sellingPriceInDollars = 10.0f; AmericanSeller americanSeller = new AmericanSeller(mediator, sellingPriceInDollars); DollarConverter dollarConverter = new DollarConverter(mediator); float indianBidInInr = 55.0f; while (!indianBuyer.attemptToPurchase(indianBidInInr)){ indianBidInInr += 15.0f; } float frenchBidInEuros = 3.0f; while (!frenchBuyer.attemptToPurchase(frenchBidInEuros)){ frenchBidInEuros += 1.5f; } } }
18. 备忘录模式
18.1 UML类图
18.2 代码
/** * 备忘录需要能够保存编辑内容 这里使用state代表 * Created by admin on 2018/3/28. */ public class Memento { private String state; public Memento(String stateToSave){ state = stateToSave; } public String getSavedState(){ return state; } } /** * 管理者需要处理在何时、为何对发起者进行保存和回滚 * Created by admin on 2018/3/28. */ public class Caretaker { private List<Memento> savedState = new ArrayList<Memento>(); public void addMememto(Memento memento){ savedState.add(memento); } public Memento getMemento(int index){ return savedState.get(index); } } /** * 发起者 也会保存不会在备忘录中保存的数据 * Created by admin on 2018/3/28. */ public class Originator { private String state; public void setState(String state){ System.out.println("Setting state to "+state); this.state = state; } public Memento saveToMemento(){ System.out.println("Saving "+state+" to Memento"); return new Memento(state); } public void restoreFromMemento(Memento memento){ state = memento.getSavedState(); System.out.println("Restoring state "+state+" from Memento"); } } public class MementoTest { public static void main(String[] args){ Caretaker caretaker = new Caretaker(); Originator originator = new Originator(); originator.setState("State1"); originator.setState("State2"); caretaker.addMememto(originator.saveToMemento()); originator.setState("State3"); caretaker.addMememto(originator.saveToMemento()); originator.restoreFromMemento(caretaker.getMemento(0)); } }
18.3 多个状态
package org.rocky.learn.designPattern.mementoMap; /** * @Author: rocky * @Date: Created in 2018/5/11. */ public class Originator { private String state1; private String state2; private String state3; //创建一个备忘录 public Memento createMememto(){ return new Memento(BeanUtils.backupProp(this)); } //恢复一个备忘录 public void restoreMemento(Memento memento){ BeanUtils.restoreProp(this, memento.getStateMap()); } public String getState1() { return state1; } public void setState1(String state1) { this.state1 = state1; } public String getState2() { return state2; } public void setState2(String state2) { this.state2 = state2; } public String getState3() { return state3; } public void setState3(String state3) { this.state3 = state3; } public String toString(){ return "state1="+state1+",state2="+state2+",state3="+state3; } } public class Memento { private HashMap<String, Object> stateMap; public Memento(HashMap<String, Object> map){ this.stateMap = map; } public HashMap<String, Object> getStateMap() { return stateMap; } public void setStateMap(HashMap<String, Object> stateMap) { this.stateMap = stateMap; } } package org.rocky.learn.designPattern.mementoMap; import java.beans.BeanInfo; import java.beans.IntrospectionException; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Observer; /** * @Author: rocky * @Date: Created in 2018/5/11. */ public class BeanUtils { //把bean的所有属性和值放入HashMap中 public static HashMap<String, Object> backupProp(Object bean){ HashMap<String, Object> result = new HashMap<>(); try { //获得bean描述 BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass()); //获得属性描述 PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); //遍历所有属性 for(PropertyDescriptor propertyDescriptor : propertyDescriptors){ //属相名称 String fieldName = propertyDescriptor.getName(); //读取属性的方法 Method readMethod = propertyDescriptor.getReadMethod(); //属性值 // Object value2 = propertyDescriptor.getValue(fieldName); Object value = readMethod.invoke(bean, new Object[]{}); // System.out.println("value2::"+value2 + ",value::"+value); if(!fieldName.equalsIgnoreCase("class")) result.put(fieldName, value); } } catch (Exception e) { e.printStackTrace(); } return result; } //把hashmap的值放入bean中 public static void restoreProp(Object bean, HashMap<String, Object> map){ try { //获得bean的描述 BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass()); //获取属相描述 PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); // 遍历所有属性 for (PropertyDescriptor propertyDescriptor: propertyDescriptors) { //属性名称 String fieldName = propertyDescriptor.getName(); if(map.containsKey(fieldName)){ //获取写入方法 Method writeMethod = propertyDescriptor.getWriteMethod(); //写入值 writeMethod.invoke(bean, new Object[]{map.get(fieldName)}); } } } catch (Exception e) { e.printStackTrace(); } } } public class Caretaker { private Memento memento; public Memento getMemento() { return memento; } public void setMemento(Memento memento) { this.memento = memento; } } public class Client { public static void main(String[] args){ //定义发起人 Originator originator = new Originator(); originator.setState1("aaa"); originator.setState2("bbb"); originator.setState3("ccc"); System.out.println(originator); Caretaker caretaker = new Caretaker(); caretaker.setMemento(originator.createMememto()); originator.setState1("111"); originator.setState2("22"); originator.setState3("333"); System.out.println(originator); originator.restoreMemento(caretaker.getMemento()); System.out.println(originator); } }
18.4 安全问题
如果创建的对象只允许自己访问,可以使用内部类实现一个空接口
public class Originator { //内部状态 private String state = ""; public String getState() { return state; } public void setState(String state) { this.state = state; } //创建一个备忘录 public IMemento createMemento(){ return new Memento(this.state); } //恢复一个备忘录 public void restoreMemento(IMemento _memento){ this.setState(((Memento)_memento).getState()); } //内置类 private class Memento implements IMemento{ //发起人的内部状态 private String state = ""; //构造函数传递参数 private Memento(String _state){ this.state = _state; } private String getState() { return state; } private void setState(String state) { this.state = state; } } } public interface IMemento { } public class Caretaker { //备忘录对象 private IMemento memento; public IMemento getMemento() { return memento; } public void setMemento(IMemento memento) { this.memento = memento; } }
19 观察者模式
19.1 UML类图
推模式和拉模式
19.2 代码
public interface TemperatureSubject { public void addObserver(TemperatureObserver temperatureObserver); public void removeObserver(TemperatureObserver temperatureObserver); public void nofify(); } public interface TemperatureObserver { public void update(int temperature); } public class TemperatureStation implements TemperatureSubject { Set<TemperatureObserver> temperatureObservers; int temperature; public TemperatureStation(int temperature){ temperatureObservers = new HashSet<TemperatureObserver>(); this.temperature = temperature; } @Override public void addObserver(TemperatureObserver temperatureObserver) { temperatureObservers.add(temperatureObserver); } @Override public void removeObserver(TemperatureObserver temperatureObserver) { temperatureObservers.remove(temperatureObserver); } @Override public void nofify() { Iterator<TemperatureObserver> iterator = temperatureObservers.iterator(); while (iterator.hasNext()){ TemperatureObserver temperatureObserver = iterator.next(); temperatureObserver.update(temperature); } } public void setTemperature(int newTemperature){ System.out.println("Setting temperator to "+newTemperature); temperature = newTemperature; nofify(); } } public class TemperatureCustomer1 implements TemperatureObserver { @Override public void update(int temperature) { System.out.println("Customer 1 found the temperature as:"+temperature); } } public class TemperatureCustomer2 implements TemperatureObserver { @Override public void update(int temperature) { System.out.println("Customer 2 found the temperature as:"+temperature); } } public class ObserverTest { public static void main(String[] args){ TemperatureStation temperatureStation = new TemperatureStation(34); TemperatureCustomer1 tc1 = new TemperatureCustomer1(); TemperatureCustomer2 tc2 = new TemperatureCustomer2(); temperatureStation.addObserver(tc1); temperatureStation.addObserver(tc2); temperatureStation.setTemperature(37); temperatureStation.removeObserver(tc1); temperatureStation.setTemperature(40); } }
20. 状态模式
20.1 UML类图
20.2 代码
public interface State { public void pressPlay(MusicPlayerContextInterface context); } public class StandbyState implements State { @Override public void pressPlay(MusicPlayerContextInterface context) { System.out.println("Converting Standby state to Playing state"); context.setState(new PlayingState()); } } public class PlayingState implements State { @Override public void pressPlay(MusicPlayerContextInterface context) { System.out.println("Converting Playing state to Standby state"); context.setState(new StandbyState()); } } public interface MusicPlayerContextInterface { public void requestPlay(); public void setState(State state); public State getState(); } public class MusicPlayerContext implements MusicPlayerContextInterface { State state; public MusicPlayerContext(State state){ this.state = state; } @Override public void requestPlay() { state.pressPlay(this); } @Override public void setState(State state) { this.state = state; } @Override public State getState() { return state; } }
21. 策略模式
21.1 UML类图
21.2 代码
public interface SortInterface { public void sort(int[] array); } public class QuickSort implements SortInterface { @Override public void sort(int[] array) { // quick sort System.out.println("Sort the arrat in quicksort"); } } public class BubbleSort implements SortInterface { @Override public void sort(int[] array) { //bubble sort System.out.println("Sort the arrat in bubblesort"); } } public abstract class Sorter { private SortInterface strategy; public void setSorter(SortInterface strategy){ this.strategy = strategy; } public SortInterface getSorter(){ return strategy; } public abstract void doSort(int[] listToSort); } public class MySorter extends Sorter { @Override public void doSort(int[] listToSort) { getSorter().sort(listToSort); } } public class StrategyTest { public static void main(String[] args){ int[] listToSorted = {15,12,13,16,17}; MySorter mySorter = new MySorter(); mySorter.setSorter(new QuickSort()); mySorter.doSort(listToSorted); mySorter.setSorter(new BubbleSort()); mySorter.doSort(listToSorted); } }
21.3 策略枚举
它是一个枚举; 它是一个浓缩了的策略模式的枚举。
21.4 代码
public enum Calculator { ADD("+"){ @Override public int exec(int a, int b) { return a + b; } }, SUB("-"){ @Override public int exec(int a, int b) { return a - b; } }; private String symbol; Calculator(String symbol){ this.symbol = symbol; } public abstract int exec(int a, int b); } public class Client { public static void main(String[] args){ int a = 5, b=7; System.out.println(Calculator.ADD.exec(a,b)); System.out.println(Calculator.SUB.exec(a,b)); } }
22. 模板方法模式
22.1 UML类图
22.2 代码
public abstract class Lunch { //模板方法 public final void prepareLunch(){ prepareIngredients(); cooking(); eating(); cleaning(); } protected abstract void cleaning(); protected void eating(){ System.out.println("I am eating , please don't disturb me."); } protected abstract void cooking(); protected abstract void prepareIngredients(); } public class McDonaldMeal extends Lunch { @Override public void cleaning() { System.out.println("McDonald clean...."); } @Override public void cooking() { System.out.println("McDonald cook...."); } @Override public void prepareIngredients() { System.out.println("McDonald prepare.."); } } public class KFCMeal extends Lunch { @Override public void cleaning() { System.out.println("KFC clean...."); } @Override public void cooking() { System.out.println("KFC cook...."); } @Override public void prepareIngredients() { System.out.println("KFC prepare...."); } } public class TemplateMethodTest { public static void main(String[] args){ Lunch meal1 = new McDonaldMeal(); meal1.prepareLunch(); Lunch meal2 = new KFCMeal(); meal2.prepareLunch(); } }
23. 访问者模式
23.1 UML类图
23.2 代码
public abstract class Animal { public abstract void accept(Person person); } public class Cat extends Animal { @Override public void accept(Person person) { person.feed(this); System.out.println("喵喵喵"); } } public class Dog extends Animal { @Override public void accept(Person person) { person.feed(this); System.out.println("汪汪汪"); } } public abstract class Person { public abstract void feed(Cat cat); public abstract void feed(Dog dog); } public class Owner extends Person { @Override public void feed(Cat cat) { System.out.println("主人喂食猫 喜欢"); } @Override public void feed(Dog dog) { System.out.println("主人喂食狗 喜欢"); } } public class Someone extends Person { @Override public void feed(Cat cat) { System.out.println("其他人喂食猫 警惕"); } @Override public void feed(Dog dog) { System.out.println("其他人喂食狗 警惕"); } } public class Home { private List<Animal> animals = new ArrayList<>(); public void addAnimal(Animal animal){ animals.add(animal); } public void action(Person person){ for (Animal anmial : animals) { anmial.accept(person); } } } public class VisitorTest { public static void main(String[] args) { Home owerHome = new Home(); owerHome.addAnimal(new Dog()); owerHome.addAnimal(new Cat()); Owner owner = new Owner(); owerHome.action(owner); Someone someone = new Someone(); owerHome.action(someone); } }
二、6大设计原则
● Single Responsibility Principle:单一职责原则
● Open Closed Principle:开闭原则
● Liskov Substitution Principle:里氏替换原则
● Law of Demeter:迪米特法则
● Interface Segregation Principle:接口隔离原则
● Dependence Inversion Principle:依赖倒置原则
三、拓展
3-1 动态代理模式
以上模式十一是静态代理。
JDK实现的动态代理, 被代理类必须实现一个接口(主要用到反射);
public interface BookStore { public void addBook(); } public class BookStoreImpl implements BookStore { @Override public void addBook() { System.out.println("...add a book..."); } } import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * @Author: rocky * @Date: Created in 2018/5/7. */ public class BookStoreProxy implements InvocationHandler { private Object target; public BookStoreProxy(Object target){ this.target = target; } public Object getProxy() { return Proxy.newProxyInstance(this.target.getClass().getClassLoader(), this.target.getClass().getInterfaces(), this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("..jdk proxy start.."); Object result = method.invoke(target, args); System.out.println("..jdk proxy end.."); return result; } public static void main(String[] args){ BookStore bookStore = (BookStore) new BookStoreProxy(new BookStoreImpl()).getProxy(); bookStore.addBook(); } }
CGLIB可以实现不需要接口也可以实现动态代理(原理是通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用)
public class SayHello { public void say(){ System.out.println("hello everyone"); } } import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; import java.lang.reflect.Method; /** * @Author: rocky * @Date: Created in 2018/5/7. */ public class CglibProxy implements MethodInterceptor { private Enhancer enhancer = new Enhancer(); public Object getProxy(Class clazz){ //设置需要创建子类的类 enhancer.setSuperclass(clazz); enhancer.setCallback(this); //通过字节码技术动态创建子类实例 return enhancer.create(); } //实现接口MethodInterceptor接口方法 @Override public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { System.out.println("insert before....."); Object result = methodProxy.invokeSuper(o, args); System.out.println("insert after....."); return result; } public static void main(String[] args){ CglibProxy proxy = new CglibProxy(); SayHello sayHello = (SayHello) proxy.getProxy(SayHello.class); sayHello.say(); } }
特别是调试时,只要看到类似$Proxy0这样的结构,你就应该知道这是一个动态代理了。
3-2 浅拷贝的注意事项
内部的数组和引用对象才不拷贝,其他的原始类型比如int、long、char等都会被拷贝,
但是对于String类型,Java就希望你把它认为是基本类型,它是没有clone方法的,
处理机制也比较特殊,通过字符串池(stringpool)在需要的时候才在内存中创建新的字符串,读者在使用的时候就把String当做基本类使用即可。
四、参考书籍
设计模式之禅(第2版)秦小波著
图解设计模式 [日] 结城浩
设计模式精解及面试攻略 [印] 纳拉西姆哈·卡鲁曼希