设计模式是一类问题的最佳解决方法,是面向对象编程人员经过长期总结改良出来的工程化的代码模块。
这些模式可以分为三大类:创建型模式(Creational Patterns)、结构型模式(Structural Patterns)、行为型模式(Behavioral Patterns)。
创建型模式:将创建对象的逻辑隐藏起来,不使用new新建对象。包含设计模式有:工厂模式、抽象工厂模式、单例模式、建造者模式、原型模式。
结构型模式:积木方式组合接口,定义组合对象,使其获得新的功能。包含设计模式有:适配器模式、桥接模式、过滤器模式、组合模式、装饰器模式、外观模式、享元模式、代理模式。
行为型模式:责任链模式、命令模式、解释权模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、空对象模式、策略模式、模板模式、访问者模式。
其他模式J2EE模式:MVC模式、业务代表模式、组合实体模式、数据访问对象模式、前端控制器模式、拦截过滤器模式、服务定位器模式、传输对象模式。
1、开闭原则(Open Close Principle)
开闭原则的意思是:对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。
2、里氏代换原则(Liskov Substitution Principle)
里氏代换原则是面向对象设计的基本原则之一。 里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。LSP 是继承复用的基石,只有当派生类可以替换掉基类,且软件单位的功能不受到影响时,基类才能真正被复用,而派生类也能够在基类的基础上增加新的行为。里氏代换原则是对开闭原则的补充。实现开闭原则的关键步骤就是抽象化,而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。
3、依赖倒转原则(Dependence Inversion Principle)
这个原则是开闭原则的基础,具体内容:针对接口编程,依赖于抽象而不依赖于具体。
4、接口隔离原则(Interface Segregation Principle)
这个原则的意思是:使用多个隔离的接口,比使用单个接口要好。它还有另外一个意思是:降低类之间的耦合度。
5、迪米特法则,又称最少知道原则(Demeter Principle)
最少知道原则是指:一个实体应当尽量少地与其他实体之间发生相互作用,使得系统功能模块相对独立。
6、合成复用原则(Composite Reuse Principle)
合成复用原则是指:尽量使用合成/聚合的方式,而不是使用继承。
类对象创建过程中使用到的设计模式
定义一个工厂,创建对象在工厂中进行,用户只要知道他需要的什么类型的对象,就可以通过一个对应类型的名字就可以拿到对应类型的对象。
工厂生产产品有个标准,或者说专利,生产东西的应用方向(Shape接口);
工厂生产的产品类型,生产东西具体应用(各种类实现Shape接口,例如:Circle、Rectangle类);
工厂根据订单生产产品(ShapeFactory类),其中订单就是对应产品类型的名字;
示例:
工厂产品标准,抽象接口
Shape.java
package factoryMode; public abstract interface Shape { void draw(); }
工厂生产的产品,只需要实现这个接口,满足标准,实现具体功能Square.java
package factoryMode; public class Square implements Shape { @Override public void draw() { // TODO Auto-generated method stub System.out.println("this is drawing a Square!"); } }
Rectangle.java
package factoryMode; public class Rectangle implements Shape { @Override public void draw() { // TODO Auto-generated method stub System.out.println("this is drawing a rectangle!"); } }
工厂根据用户订单生产, shapeType就是用户要求生产类型的订单
Shapefactory.java
package factoryMode; /* * 工厂方法 */ public class ShapeFactory { public Shape getShape(String shapeType) { if (shapeType ==null){ return null; }else { if (shapeType=="Rectangle") { //获取Rectangle对象 return new Rectangle(); }else if(shapeType=="Square"){//获取Square对象 return new Square(); }else if(shapeType=="Circle") {//获取Circle对象 return new Circle(); } } return null; } }
测试main
factoryDemo.java
package factoryMode; /** * 工厂模式 */ public class factoryDemo { public static void main(String[] args) { //获取工厂对象 ShapeFactory fac = new ShapeFactory(); Rectangle re = (Rectangle) fac.getShape("Rectangle"); re.draw(); } }
工厂模式加强,工厂的不同子工厂能生产不同系列的产品,一个系列下有多个产品。
工厂生产有多个标准,专利,(Shape接口、Color接口);
工厂根据专利生产不同系列的产品,实现Shape接口系列产品,实现Color接口系列产品(例如:Red、Circle类)
工厂的管理部门,管理定义子工厂生产哪个系列产品需要的生产线(AbstractFactory类)
工厂下的子工厂,可以自己选择可以生产的系列产品(ColorFactory、ShapeFactory类)
工厂根据用户选择产品系列,选择不同的子工厂(FactoryProducer类)
工厂根据用户订单生产该系列产品(ColorFactory、ShapeFactory类)
工厂生产标准,专利,抽象接口
Shape.java
package abstractFacMode; public abstract interface Shape { void draw(); }
Color.java
package abstractFacMode; public interface Color { public void fill(); }
工厂管理子工厂生产产品系列生产线,getColor,getShape两条生产线
AbstractFactory.java
package abstractFacMode; public abstract class AbstractFactory { public abstract Color getColor(String color); public abstract Shape getShape(String shape); }
工厂下的子工厂
ShapeFactory.java
Shape系列生产的子工厂,只需要实现getShape这条生产线
package abstractFacMode; public class ShapeFactory extends AbstractFactory { @Override public Color getColor(String color) { // TODO Auto-generated method stub return null; } @Override public Shape getShape(String shape) { // TODO Auto-generated method stub if(shape==null) { return null; }else if(shape=="Rectangle") { return new Rectangle(); }else if(shape=="Square") { return new Square(); }else if(shape=="Circle") { return new Circle(); } return null; } }
ColorFactory.java
Color系列生产工厂,只实现getColor这条生产线
package abstractFacMode; public class ColorFactory extends AbstractFactory { @Override public Color getColor(String color) { // TODO Auto-generated method stub if (color==null) { return null; }else if(color=="Red") { return new Red(); }else if(color=="Blue") { return new Blue(); } return null; } @Override public Shape getShape(String shape) { // TODO Auto-generated method stub return null; } }
根据用户需求,选择子工厂生产对应系列产品
FactoryProducer.java
package abstractFacMode; public class FactoryProducer { public AbstractFactory getFactory(String choice) { if(choice==null) { return null; }else if(choice=="Shape") { return new ShapeFactory(); }else if(choice=="Color") { return new ColorFactory(); } return null; } }
不同系列的产品
Shape系列生产的Rectangle产品
package abstractFacMode; public class Rectangle implements Shape { @Override public void draw() { // TODO Auto-generated method stub System.out.println("this is drawing a rectangle!"); } }
Color系列生产的Red产品
package abstractFacMode; public class Red implements Color { @Override public void fill() { // TODO Auto-generated method stub System.out.println("fill red color!"); } }
测试
package abstractFacMode; /* * 抽象工厂 */ public class AbstractFacDemo { public static void main(String[] args) { //获取生产对应系列子工厂对象 AbstractFactory absFac=new FactoryProducer().getFactory("Shape"); Shape s=absFac.getShape("Rectangle"); s.draw(); AbstractFactory absFac1=new FactoryProducer().getFactory("Color"); Color c=absFac1.getColor("Red"); c.fill(); } }
类只能创建一个对象,并且提供一个方法供全局访问。
示例:
饿汉式,通过java类加载机制实现线程安全。在类加载的时候就实例化对象。优点执行效率高,但式类加载时就实例化对象,浪费内存。
SingleObject.java
package singleMode; /* * 单例模式 * 饿汉式(线程安全),但是可以使用反射创建多个实例 */ public class SingleObject { //创建SingleObject对象 private static SingleObject instance=new SingleObject(); //私有构造 private SingleObject() { } public static SingleObject getInstance() { return instance; } public void showMessage() { System.out.println("this is singleMode!"); } }
懒汉式,延迟加载,当调用getInstance方法时才实例化对象。当多线程时,线程不安全,会出现实例化出多个对象。
SingleObject1.java
package singleMode; /* * 单例模式 * 懒汉式,线程不安全 * 将类的实例化延后到方法调用; */ public class SingleObject1 { private static SingleObject1 instance; private SingleObject1() {}; public static SingleObject1 getInstance() { if(instance==null) { instance=new SingleObject1(); } return instance; } public void showMessage() { System.out.println("this is lazy single mode !"); } }
懒汉式,延迟加载,加上同步锁,保证线程安全。但加上锁后执行效率有影响。
SingleObject2.java
package singleMode; /* * 单例模式 * 懒汉式(线程安全),使用同步锁sychonization */ public class SingleObject2 { private static SingleObject2 instance; //构造函数 private SingleObject2() {}; //获取实例对象 public static synchronized SingleObject2 getInstance() { if(instance==null) { instance = new SingleObject2(); } return instance; } public void showMessage() { System.out.println("this lazy synchronized Single Mode!"); } }
懒汉式,延迟加载,加上同步锁,保证线程安全。双锁机制在线程安全情况下,保证高性能。
package singleMode; /* * * 单例模式, * 懒汉式 * 双锁DCL(线程安全,高效) */ public class SingleObject3 { private volatile static SingleObject3 instance; //私有构造 private SingleObject3() {}; public static SingleObject3 getInstance() { if(instance==null) { synchronized(SingleObject3.class) { instance = new SingleObject3(); } } return instance; } public void showMessage() { System.out.println("this lazy DCL single mode!!!"); } }
懒汉式,使用静态内部类实现,通过静态域实现延迟加载。这种方式比较饿汉式能够实现延迟加载,比较双锁机制实现更加简单,能够保证线程安全。
package singleMode; /* * * 单例模式 * 懒汉式,使用静态内部类实现延迟实例化 */ public class SingleObject4 { private static class InstanceHolder{ private static final SingleObject4 instance = new SingleObject4(); } private SingleObject4() {}; public static SingleObject4 getInstance() { return InstanceHolder.instance; } public void showMessage() { System.out.println("this is lazy inner class single mode!!!"); } }
将复杂对象的构建和他的表示分离。将复杂对象的创建过程进行抽象,通过不同的条件执行相同的创建过程,动态得到不同的对象。
示例:
抽象建造者,Builer.java
package builderMode; /** * * 建造者抽象类 */ public abstract class Builder { abstract void buildPainter(MyPainter mypaiter); abstract void buildCanvas(MyCanvas mycanvas); abstract MyPicture getPicture(); }
具体实现Builder
DrawPictureBuilder.java
package builderMode; /** * 具体绘画实现builder */ public class DrawPictureBuilder extends Builder { private MyPicture mypicture = new MyPicture(); @Override void buildPainter(MyPainter mypainter) { // TODO Auto-generated method stub mypicture.setMypainter(mypainter); } @Override void buildCanvas(MyCanvas mycanvas) { // TODO Auto-generated method stub mypicture.setMycanvas(mycanvas); } @Override MyPicture getPicture() { // TODO Auto-generated method stub return mypicture; } }
Director控制者类,控制使用建造者组合出复杂类
Director.java
package builderMode; /** * * Director类使用建造者组合出复杂类 */ public class Director { private Builder builder; private MyCanvas mycanvas; private MyPainter mypaiter; public Director(Builder builder, MyCanvas mycanvas, MyPainter mypaiter) { super(); this.builder = builder; this.mycanvas = mycanvas; this.mypaiter = mypaiter; } //组装复杂类 public MyPicture constractPic() { builder.buildCanvas(mycanvas); builder.buildPainter(mypaiter); return builder.getPicture(); } }
用于组合子类
MyCanvas.java
package builderMode; /** * * 画布类 */ public class MyCanvas { //画布长宽 private int longth; private int width; public MyCanvas(int longth, int width) { super(); this.longth = longth; this.width = width; } public int getLongth() { return longth; } public void setLongth(int longth) { this.longth = longth; } public int getWidth() { return width; } public void setWidth(int width) { this.width = width; } }
MyPainter.java
package builderMode; /** * * 画笔类 */ public class MyPainter { //画笔颜色 private String color; //画笔宽度 private int pwidth; public MyPainter(String color, int pwidth) { super(); this.color = color; this.pwidth = pwidth; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } public int getPwidth() { return pwidth; } public void setPwidth(int pwidth) { this.pwidth = pwidth; } }
MyPicture.java
package builderMode; public class MyPicture { //画笔 private MyPainter mypainter; //画布 private MyCanvas mycanvas; public MyPicture() { super(); } public MyPicture(MyPainter mypainter, MyCanvas mycanvas) { super(); this.mypainter = mypainter; this.mycanvas = mycanvas; } public MyPainter getMypainter() { return mypainter; } public void setMypainter(MyPainter mypainter) { this.mypainter = mypainter; } public MyCanvas getMycanvas() { return mycanvas; } public void setMycanvas(MyCanvas mycanvas) { this.mycanvas = mycanvas; } @Override public String toString() { // TODO Auto-generated method stub String str = "画布:"+"long = "+mycanvas.getLongth() +";width = "+mycanvas.getWidth() +"-----画笔:"+"color = "+mypainter.getColor()+";pwidth = "+mypainter.getPwidth(); return str; } }
测试
package builderMode; /** * 建造者模式 */ public class BuilderModeDemo { public static void main(String[] args) { //创建画图所需元素 MyCanvas mycanvas = new MyCanvas(10,10); MyPainter mypainter = new MyPainter("red",10); //创建建造者对象 Builder builder = new DrawPictureBuilder(); //Director控制组合过程 Director director = new Director(builder,mycanvas,mypainter); MyPicture mypicture = director.constractPic(); System.out.println(mypicture.toString()); } }
原型模式(Prototype mode)用于创建重复对象,同时保证高效。原型模式实现一个接口创建当前对象的克隆,拷贝一个现有对象生成一个新对象,浅拷贝实现Cloneable,重写;深拷贝通过Serializable读取二进制流。
示例:
创建一个抽象类或接口实现接口Cloneable,重写clone()方法
Shape.java
package PrototypeMode; //定义抽象类或接口实现Cloneable接口 public abstract class Shape implements Cloneable { //查找到唯一原型标识 private String id; private String type; //draw方法 public abstract void draw(); public String getId() { return id; } public void setId(String id) { this.id = id; } public String getType() { return type; } public void setType(String type) { this.type = type; } //重写clone()方法 public Object clone() { Object clone = null; try { clone = super.clone(); } catch (CloneNotSupportedException e) { // TODO Auto-generated catch block e.printStackTrace(); } return clone; } }
对应继承抽象类的实体类:
Circle.java类
package entry; import PrototypeMode.Shape; //Shape类的实体 public class Circle extends Shape { @Override public void draw() { // TODO Auto-generated method stub System.out.println("draw a circle"); } }
Rectangle.java类
package entry; import PrototypeMode.Shape; public class Rectangle extends Shape { @Override public void draw() { // TODO Auto-generated method stub System.out.println("draw a rectangle"); } }
创建一个类保存实体类对象原型,通过这个类获取原型的拷贝
ShapeCashe.java类
package PrototypeMode; import java.util.Hashtable; import entry.Circle; import entry.Rectangle; //Shape对象容器类 public class ShapeCache { //保存Shape原型对象 private static Hashtable<String,Shape> shapeMap = new Hashtable<String,Shape>(); //创建获取根据唯一标识获取原型方法 public static Shape getShape(String id) { //根据唯一标识获取原型 Shape shapetemp = shapeMap.get(id); //返回原型对象的一个克隆 return (Shape) shapetemp.clone(); } //初始化原型对象 public static void loadShape() { Circle circle = new Circle(); circle.setId("1"); circle.setType("Circle"); shapeMap.put(circle.getId(), circle); Rectangle rectangle = new Rectangle(); rectangle.setId("2"); rectangle.setType("Rectangle"); shapeMap.put(rectangle.getId(), rectangle); } }
测试:
PrototypeModeDemo.java类
package PrototypeMode; public class PrototypeModeDemo { public static void main(String[] args) { //初始化原型表 ShapeCache.loadShape(); //获取clone实例 //根据id,获取对应原型的拷贝 Shape cloneShape = ShapeCache.getShape("1"); System.out.println(cloneShape.toString()); } }
适配器模式(Adapter Mode),不兼容接口之间的桥梁。通过适配器一个类实例使用其他类功能。
实例:
播放器接口:
Player.java类
package adapterMode; //播放器接口 public interface Player { //传入播放文件类型,文件名 public void play(String filetype,String filename); }
基本播放器类,只能播放mp4格式文件,
BasicPlayer.java类
package adapterMode; public class BasicPlayer implements Player { AdapterPlayer adapterplayer; @Override public void play(String filetype, String filename) { // TODO Auto-generated method stub //BasicPlayer只能播放mp4 if(filetype.equalsIgnoreCase("mp4")) { System.out.println("播放mp4:"+filename); }else { //使用其他播放器 if(filetype.equalsIgnoreCase("mp3")||filetype.equalsIgnoreCase("vlc")) { //创建适配器 adapterplayer = new AdapterPlayer(filetype); //适配器去调用其他类对象方法 adapterplayer.play(filetype, filename); }else { System.out.println("不支持格式!"); } } } }
其他先进播放器接口,拥有MP3和vlc格式播放功能:
AdvancePlayer.java类
package adapterMode; //先进播放器 public interface AdvancePlayer { public void playVlc(String filename); public void playMp3(String filename); }
实现先进播放器的实体类:
MP3Player.java类,播放MP3文件
package adapterMode; public class Mp3Player implements AdvancePlayer { @Override public void playVlc(String filename) { // TODO Auto-generated method stub } @Override public void playMp3(String filename) { // TODO Auto-generated method stub System.out.println("播放Mp3:"+filename); } }
VlcPlayer.java类,播放VLC格式文件
package adapterMode; public class VlcPlayer implements AdvancePlayer { @Override public void playVlc(String filename) { // TODO Auto-generated method stub System.out.println("播放Vlc:"+filename); } @Override public void playMp3(String filename) { // TODO Auto-generated method stub } }
创建适配器类,让BasicPlayer可以使用MP3Player和VLCPlayer播放器的功能。
AdapterPlayer.java类,实现Player接口。
package adapterMode; public class AdapterPlayer implements Player { AdvancePlayer advancePlayer; //根据文件类型,选择实例化对应advancePlayer public AdapterPlayer(String filetype) { if (filetype.equalsIgnoreCase("vlc")) { advancePlayer = new VlcPlayer(); }else if(filetype.equalsIgnoreCase("mp3")) { advancePlayer = new Mp3Player(); } } //调用advancePlayer的不同实例方法 @Override public void play(String filetype, String filename) { // TODO Auto-generated method stub if (filetype.equalsIgnoreCase("vlc")) { advancePlayer.playVlc(filename);; }else if(filetype.equalsIgnoreCase("mp3")) { advancePlayer.playMp3(filename);; } } }
测试:
package adapterMode; //测试 public class AdapterModeDemo { public static void main(String[] args) { BasicPlayer basicplayer = new BasicPlayer(); //调用自己的功能 basicplayer.play("mp4", "hello.mp4"); //通过adapter,调用advanceplayer的播放器 basicplayer.play("vlc", "welcome.vlc"); } }
桥接模式(Bridge Mode),将实体类的功能独立出来,抽象成一个通用的Bridge接口。将实体和功能实现分离,实现不同功能。通过Brideg接口,传入不同功能Bridge接口的实现类,实现调用不同功能。
实例:
创建一个抽象的功能接口,
Bridge.java类
package bridgeMode; //桥接Bridge接口,连接定义与功能桥梁 //不同功能的接口 public interface Bridge { public void draw(); }
不同的功能,实现bridge接口的类,重写方法
RedDraw.java类
package bridgeMode; public class RedDraw implements Bridge { @Override public void draw() { // TODO Auto-generated method stub System.out.println("draw red"); } }
YellowDraw.java类
package bridgeMode; public class YellowDraw implements Bridge { @Override public void draw() { // TODO Auto-generated method stub System.out.println("draw yellow"); } }
对应实体类父类,拥有Bridge接口类型属性
Painter.java类
package bridgeMode; //实体的父类,拥有属性:bridge接口对象 //画笔父类 public abstract class Painter { //子类需要访问到父类属性、构造 protected Bridge bridge; protected Painter(Bridge bridge) { this.bridge = bridge; } public abstract void drawPic(); }
具体实体类子类
BasicPainter.java类
package bridgeMode; //实体的子类,通过功能接口Bridge对象实现不同功能 public class BasicPainter extends Painter { public BasicPainter(Bridge bridge) { //调用父类的构造,赋值 super(bridge); } @Override public void drawPic() { // TODO Auto-generated method stub //通过bridge,根据不同实现bridge接口的功能类,实现功能和实体分离 bridge.draw(); } }
测试:
package bridgeMode; //桥接模式 //测试 public class BridgeModeDemo { public static void main(String[] args) { //调用不同实现 BasicPainter basicPainter = new BasicPainter(new RedDraw()); basicPainter.drawPic(); basicPainter = new BasicPainter(new YellowDraw()); basicPainter.drawPic(); } }
过滤器模式(Filter Mode),通过不同的接口实现不同标准的对一组对象进行过滤处理。
示例:
过滤器接口标准
Filter.java类
package filterMode; import java.util.List; //过滤器接口 public interface Filter { //过滤方法 public List<People> filtObject(List<People> lists); }
实现接口类,不同的过滤条件
FilterAge.java对年龄进行过滤
package filterMode; import java.util.ArrayList; import java.util.List; public class FilterAge implements Filter { @Override public List<People> filtObject(List<People> lists) { // TODO Auto-generated method stub List<People> peopleup50 = new ArrayList<People>(); for (People people:lists) { //将age大于50放入列表 if (people.getAge()>50){ peopleup50.add(people); } } return peopleup50; } }
FilterAddr.java类,对地址过滤
package filterMode; import java.util.ArrayList; import java.util.List; public class FilterAddr implements Filter { @Override public List<People> filtObject(List<People> lists) { // TODO Auto-generated method stub List<People> peopleaddr = new ArrayList<People>(); for(People people:lists) { //将地址四川的筛选出来 if (people.getAddr().equalsIgnoreCase("四川")) { peopleaddr.add(people); } } return peopleaddr; } }
FilterComponent.java组合条件过滤
package filterMode; import java.util.List; //组合条件过滤 public class FilterComponent implements Filter { private Filter filter1; private Filter filter2; public FilterComponent(Filter filter1,Filter filter2) { this.filter1 = filter1; this.filter2 = filter2; } @Override public List<People> filtObject(List<People> lists) { // TODO Auto-generated method stub //同时满足两个条件 //使用条件1过滤 List<People> peoples1 = filter1.filtObject(lists); //然后将过滤后的使用条件2过滤 List<People> peoples2 = filter2.filtObject(peoples1); return peoples2; } }
过滤的实体类:
People.java类
package filterMode; //实体类people public class People { private String name; private int age; private String addr; public People(String name, int age, String addr) { super(); this.name = name; this.age = age; this.addr = addr; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getAddr() { return addr; } public void setAddr(String addr) { this.addr = addr; } }
测试
package filterMode; import java.util.ArrayList; import java.util.List; //测试 public class FilterModeDemo { public static void main(String[] args) { List<People> peoples = new ArrayList<People>(); People people = new People("tom",11,"四川"); peoples.add(people); people = new People("li",45,"云南"); peoples.add(people); people = new People("wom",61,"四川"); peoples.add(people); people = new People("tm",11,"北京"); peoples.add(people); //过滤年龄过滤器 Filter filtAge = new FilterAge(); filtAge.filtObject(peoples); //过滤地址过滤器 Filter filtAddr = new FilterAddr(); filtAddr.filtObject(peoples); //组合过滤器 Filter filtComp = new FilterComponent(filtAge,filtAddr); filtComp.filtObject(peoples); } }
组合模式(Composite Mode),将对象组合成类似树形结构,表现对象之间的关系。类中拥有保存该类对象的列表的属性,用来构建类对象之间的关系,形成树形结构。
示例:
员工类Employee.java,不同员工拥有不同职级,下辖管理不同员工。
package compositeMode; import java.util.ArrayList; import java.util.List; //员工类 public class Employee { //姓名 private String name; //年龄 private int age; //职位 private String position; //下辖员工 private List<Employee> employeelists; //构造方法 public Employee(String name, int age, String position) { super(); this.name = name; this.age = age; this.position = position; this.employeelists = new ArrayList<Employee>(); } //get set方法 public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getPosition() { return position; } public void setPosition(String position) { this.position = position; } //将下辖职员加入 public void add(Employee employee) { this.employeelists.add(employee); } //根据名称移除职员 public void remove(Employee employee) { this.employeelists.remove(employee); } }
测试:
package compositeMode; public class CompositeModeDemo { public static void main(String[] args) { //CEO,类似树根结点 Employee employee = new Employee("tom",31,"CEO"); Employee employee1 = new Employee("li",33,"SA Manager"); Employee employee2 = new Employee("li",43,"SA1"); Employee employee3 = new Employee("li",23,"SA2"); //构建关系 employee.add(employee1); employee1.add(employee2); employee1.add(employee3); } }
装饰器模式(Decorator Mode),在不改变现有对象结构情况下,为对象添加新的功能。
示例:
抽象接口被装饰,实现这一接口的类都可以传入装饰器类
Shape.java接口
package decratorMode; //抽象接口,被装饰 public interface Shape { public void draw(); }
实现Shape接口的实体类:
Circle.java类
package decratorMode; //实体类,实现Shape接口 public class Circle implements Shape { @Override public void draw() { // TODO Auto-generated method stub System.out.println("draw circle"); } }
Rectangle.java类
package decratorMode; //实体类,实现Shape接口 public class Rectangle implements Shape { @Override public void draw() { // TODO Auto-generated method stub System.out.println("draw rectangle"); } }
装饰器类,定义一个抽象的装饰器父类,实现Shape接口
ShapeDecrator.java类
package decratorMode; //装饰器抽象类,父类 public abstract class ShapeDecrator implements Shape { protected Shape decShape; public ShapeDecrator(Shape shape) { this.decShape = shape; } public void draw() { this.decShape.draw(); } }
具体装饰器实现类,将Shape的实体类传入,执行原有逻辑和装饰逻辑
package decratorMode; //实现具体装饰逻辑 public class RedShapeDecrator extends ShapeDecrator { public RedShapeDecrator(Shape decShape) { super(decShape); } public void draw() { System.out.println("Red装饰逻辑"); decShape.draw(); System.out.println("Red装饰逻辑"); } }
测试:
package decratorMode; //测试 public class DecratorModeDemo { public static void main(String[] args) { Circle circle = new Circle(); RedShapeDecrator reddec = new RedShapeDecrator(new Circle()); RedShapeDecrator reddec1 = new RedShapeDecrator(new Rectangle()); circle.draw(); reddec.draw(); reddec1.draw(); } }
外观模式(Façade Mode),将复杂系统隐藏起来,直接提供一个整合的外部接口供用户调用。用户不用了解系统内部复杂逻辑关系。
示例 :
模拟内部复杂逻辑接口
Shape.java类
package facadeMode; //Shape接口 public interface Shape { public void draw(); }
实现Shape接口实体类:
package facadeMode; //实现Shape接口实体类 public class Circle implements Shape { @Override public void draw() { // TODO Auto-generated method stub System.out.println("draw circle"); } }
package facadeMode; //实现Shape接口实体类 public class Rectangle implements Shape { @Override public void draw() { // TODO Auto-generated method stub System.out.println("draw rectangle"); } }
提供给用户统一访问复杂内部逻辑接口:
ShapeMaker.java类
package facadeMode; //用户接口类,直接提供给用户访问Shape功能集合接口 public class ShapeMaker { //circle类对象 private Shape circle; //rectangle类对象 private Shape rectangle; public ShapeMaker() { circle = new Circle(); rectangle = new Rectangle(); } //提供给用户的接口方法 public void drawCircle() { circle.draw(); } public void drawRectangle() { rectangle.draw(); } }
测试:
package facadeMode; //测试 public class FacadeModeDemo { public static void main(String[] args) { //直接使用ShapeMaker类对象获取Shape接口类型类对象功能 ShapeMaker shapeMaker = new ShapeMaker(); shapeMaker.drawCircle(); shapeMaker.drawRectangle(); } }
享元模式(Flyweight Mode),主要用来减少重复对象的创建,增加对象重用,减少内存占用。
示例:
Shape.java,抽象接口
package flyweightMode; //Shape接口 public interface Shape { public void draw(); }
实现Shape接口实体类
Circle.java
package flyweightMode; //实现shape接口实体类 public class Circle implements Shape { private String color; //构造 public Circle(String color) { this.setColor(color); } @Override public void draw() { // TODO Auto-generated method stub System.out.println("draw Circle,color:"+this.color); } public String getColor() { return color; } public void setColor(String color) { this.color = color; } }
创建一个工厂类,保存已经创建的实体类对象,获取已经创建的重用实体类对象或创建一个新类对象。
ShapeFactory.java package flyweightMode; import java.util.HashMap; //工厂类,保存现有的Shape对象,获取新的Shape对象或可重用的Shape对象 public class ShapeFactory { private static HashMap<String,Shape> circleMap = new HashMap<>(); //获取指定color的Circle public static Shape getCircle(String color) { Circle circle = (Circle) circleMap.get(color); if (circle == null){ circle = new Circle(color); circleMap.put(color, circle); } return circle; } }
测试:
package flyweightMode; //测试享元模式 public class FlyweightModeDemo { public static void main(String[] args) { ShapeFactory shapefac = new ShapeFactory(); Circle circle = (Circle) shapefac.getCircle("yellow"); System.out.println(circle); circle.draw(); circle = (Circle) shapefac.getCircle("red"); System.out.println(circle); circle.draw(); //使用的还是之前的对象,color为yellow circle = (Circle) shapefac.getCircle("yellow"); System.out.println(circle); circle.draw(); } }
为一个类额外添加一层访问控制逻辑,用另一个类包装被代理类。
示例:
Image接口
Image.java
package proxyMode; //定义Image接口 public interface Image { public void show(); }
被代理类
SourceImage.java类
package proxyMode; //被代理类 public class SourceImage implements Image { @Override public void show() { // TODO Auto-generated method stub System.out.println("source show Image"); } }
代理类
ProxyImage.java类
package proxyMode; //代理类,对SourceImage类添加访问控制 public class ProxyImage implements Image { private SourceImage sourceImg; //代理类添加访问控制 @Override public void show() { // TODO Auto-generated method stub //source类对象不存在,创建,已经存在使用已有的 if (sourceImg ==null){ sourceImg = new SourceImage(); }else { System.out.println("proxy image show"); } } }
动态代理示例:
JDK自带代理,需要实现相同接口
Image接口
package DynProxy; //image接口 public interface Image { public void show(); }
被代理类sourceImage
SourceImage.java类
package DynProxy; import DynProxy.Image; public class SourceImage implements Image { @Override public void show() { // TODO Auto-generated method stub System.out.println("souce image show"); } }
代理类和处理器
package DynProxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; //代理类和处理器 public class DynProxyHandler implements InvocationHandler { private SourceImage sourceImg; public DynProxyHandler(SourceImage sourceImg) { this.sourceImg = sourceImg; } @Override public Object invoke(Object arg0, Method arg1, Object[] arg2) throws Throwable { // TODO Auto-generated method stub System.out.println("代理逻辑"); //代理调用原处理逻辑 arg1.invoke(sourceImg, arg2); return null; } }
测试使用代理调用功能
package DynProxy; import java.lang.reflect.Proxy; public class DynProxyDemo { public static void main(String[] args) { //创建处理器对象 DynProxyHandler handler = new DynProxyHandler(new SourceImage()); //创建代理类对象 Image proxyImage = (Image) Proxy.newProxyInstance( handler.getClass().getClassLoader(), new Class[] {Image.class}, handler); //使用代理类对象调用方法 proxyImage.show(); } }
责任链模式:将同一个请求交给多个类对象处理,这些类对象连接成一条链,链上每个对象都有机会处理这个请求。每个处理的类都拥有对下一个处理者的引用。
示例:
打印不同级别的log
logging.java抽象类
package responseChainMode; //日志抽象类 public abstract class Logging { // 日志打印级别 public static int INFO = 1; public static int DEBUG = 2; public static int ERROR = 3; protected int level; // 责任链下一个 protected Logging nextLogging; // 设置下一个责任链节点 public void setNextLogging(Logging nextLogging) { this.nextLogging = nextLogging; } public void logMessage(int level, String message) { // 如果 if (this.level <= level) { write(message); } // 如果有下一个节点,再调用logMessage方法 if (nextLogging != null) { nextLogging.logMessage(level, message); } } // 输出log abstract protected void write(String message); }
错误级别的log类
ErrorLogging.java类
package responseChainMode; public class ErrorLogging extends Logging { // 设置level public ErrorLogging() { this.level = Logging.ERROR; } @Override protected void write(String message) { // TODO Auto-generated method stub System.out.println("error logging:" + message); } }
Debug级别的log类
DebugLogging.java类
package responseChainMode; public class DebugLogging extends Logging { // 设置level public DebugLogging() { this.level = Logging.DEBUG; } @Override protected void write(String message) { // TODO Auto-generated method stub System.out.println("debug logging:" + message); } }
提示级别的Logging
InfoLogging.java类
package responseChainMode; public class InfoLogging extends Logging { // 设置level public InfoLogging() { this.level = Logging.INFO; } @Override protected void write(String message) { // TODO Auto-generated method stub System.out.println("info logging:" + message); } }
测试责任链模式
package responseChainMode; public class ResponseChainModeDemo { public static Logging getLoggingChain() { Logging errorLogging = new ErrorLogging(); Logging debugLogging = new DebugLogging(); Logging infoLogging = new InfoLogging(); // 构建责任链 errorLogging.setNextLogging(debugLogging); debugLogging.setNextLogging(infoLogging); // 返回责任链 return errorLogging; } public static void main(String[] args) { Logging loggingChain = getLoggingChain(); // debug级别,debug及以下节点响应 loggingChain.logMessage(Logging.DEBUG, "debug,some message"); // error级别,所有处理节点都响应 loggingChain.logMessage(Logging.ERROR, "error,some message"); } }
命令模式(Command Mode)将具体处理的逻辑请求包装成命令,命令调用类直接调用命令,具体处理还是调用的请求类中方法。命令模式将请求和处理逻辑分开,实现松耦合。
示例:
Request.java类,具体请求逻辑
package commandMode; //请求对象,具体逻辑 public class Request { public void sayHello() { System.out.println("say hello"); } public void sayBye() { System.out.println("say bye"); } }
Command接口,命令接口类
package commandMode; //命令接口 public interface Command { //执行请求逻辑 public void excute(); }
Command具体接口实现,调用Request不同逻辑:
HelloCommand.java类
package commandMode; //命令command实现类,调用Request具体方法 public class HelloCommand implements Command { private Request req; public HelloCommand(Request request) { this.req = request; } @Override public void excute() { // TODO Auto-generated method stub req.sayHello(); } }
CommandList.java类,提供给用户的调用Command的入口:
package commandMode; import java.util.ArrayList; import java.util.List; //命令调用的接口类 public class CommandList { //命令列表 private List<Command> commands = new ArrayList<Command>(); //添加命令 public void addCommand(Command command) { commands.add(command); } public void excCommand() { //执行所有命令 for(Command command:commands) { command.excute(); } //清空命令列表 commands.clear(); } }
测试:
package commandMode; //命令模式测试 public class CommandModeDemo { public static void main(String[] args) { //创建请求 Request req = new Request(); //包装成命令 Command com = new HelloCommand(req); //将命令放入命令列表,提供给用户调用命令接口 CommandList coms = new CommandList(); coms.addCommand(com); //执行命令列表 coms.excCommand(); } }
迭代器模式(Iterator Mode),提供一种新的方法遍历聚合对象。聚合对象本身可以遍历自身包含元素,迭代器模式将这种遍历交给Iterator来实现。
示例:
Iterator接口
package iteratorMode; //迭代器接口 public interface Iterator { //判断是否有下一个元素 public boolean hasNext(); //获取下一个元素 public Object next(); }
Container.java类,获取迭代器的接口
package iteratorMode; //获取迭代器 public interface Container { //获取迭代器 public Iterator getIterator(); }
Container的实现类,拥有内部类实现Iterator接口,遍历类中聚合属性值
package iteratorMode; //Container实现类 public class StringContainer implements Container { public String lists[] = {"hello","welcome"}; @Override public Iterator getIterator() { // TODO Auto-generated method stub return new StringIterator(); } //内部类,实现Iterator接口 public class StringIterator implements Iterator { int index; @Override public boolean hasNext() { // TODO Auto-generated method stub if (index<lists.length) { return true; } return false; } @Override public Object next() { // TODO Auto-generated method stub if(this.hasNext()) { return lists[index++]; } return null; } } }
测试
package iteratorMode; //测试迭代器模式 public class IteratorModeDemo { public static void main(String[] args) { StringContainer strContainer = new StringContainer(); Iterator ite = strContainer.getIterator(); while (ite.hasNext()) { String str = (String) ite.next(); System.out.println(str); } } }
原文:https://www.cnblogs.com/tangToms/p/12677686.html