结构型:
代理模式
适配器模式
装饰器模式:继承同一个接口,持有父类对象,调用父类方法后再添加新技功(如英雄每升一次级都添加一个技能)
桥接模式:为避免继承太多,将对象分成多纬度变化,避免多层次继承,而是用一个抽象类 来持有桥接类(桥接类即是一个纬度的功能),建立关联关系。
组合模式 :以树的形式 表示“整体部分结构”,比如目录结构
享元模式 :类似对象缓存,当有些对象时直接从hashmap中取出,没有时 新建再放入hashmap
外观模式 : 将多个模块功能封装到一个外观类中,客端调用不用关心具体实现。
5 v5 代理模式
代理模式,可以分为两种,一种是静态代理,一种是动态代理。
//静态代理
//被代理方类
public interface Connection {
Statement createStatement() throws SQLException;
void close() throws SQLException;
}
public class ConnectionService implements Connection {
@Override
public Statement createStatement() throws SQLException {
return null;
}
@Override
public void close() throws SQLException {
}
}
//静态代理类,主要构造的时候传对被代理对象connection
public class ConnectionProxy implements Connection {
private Connection connection;
//传入被代理对象
public ConnectionProxy(Connection connection) {
super();
this.connection = connection;
}
@Override
public Statement createStatement() throws SQLException {
//dosome thing...
//执行被代理方法
Statement statement = connection.createStatement();
//dosome thing ...
return statement;
}
@Override
public void close() throws SQLException {
connection.close();
}
}
//动态代理类,实现InvocationHandler接口,重写invoke方法
public class ConnectionProxy implements InvocationHandler {
private Connection connection;
public ConnectionProxy(Connection connection) {
super();
this.connection = connection;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//这里判断是Connection接口的close方法的话
if (Connection.class.isAssignableFrom(proxy.getClass()) && method.getName().equals("close")) {
//我们不执行真正的close方法
//method.invoke(connection, args);
//将连接归还连接池 //DataSource.getInstance().recoveryConnection(connection);
return null;
}else {
return method.invoke(connection, args);
}
}
/**
* 获取代理类对象
* @return
*/
public Connection getConnectionProxy(){
return (Connection) Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{Connection.class}, this);
}
}
6 v6 适配器模式
需要使用一个类的功能,但是该类的接口不符合使用场合要求的接口,可使用定制适配器,
又或者是有一个接口定义的行为过多,则可以定义一个缺省适配器,让子类选择性的覆盖适配器的方法
7 v7 装饰器模式
通常可以使用继承来实现功能的动态添加,一步步细化原功能
缺点:需要拓展的功能的种类很繁多,那么势必生成很多子类,增加系统的复杂性。
例如:一张画,被添加画框装饰
//原始类 抽象接口
public interface Shape {
void draw();
}
//原始类 具体
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Shape: Rectangle");
}
}
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("Shape: Circle");
}
}
//装饰抽象类
public abstract class ShapeDecorator implements Shape {
protected Shape decoratedShape;
public ShapeDecorator(Shape decoratedShape){
this.decoratedShape = decoratedShape;
}
public void draw(){
decoratedShape.draw();
}
}
//实体装饰类
public class RedShapeDecorator extends ShapeDecorator {
public RedShapeDecorator(Shape decoratedShape) {
super(decoratedShape);
}
@Override
public void draw() {
decoratedShape.draw();
setRedBorder(decoratedShape);
}
private void setRedBorder(Shape decoratedShape){
System.out.println("Border Color: Red");
}
}
//使用
public class DecoratorPatternDemo {
public static void main(String[] args) {
Shape circle = new Circle();
Shape redCircle = new RedShapeDecorator(new Circle());
Shape redRectangle = new RedShapeDecorator(new Rectangle());
System.out.println("Circle with normal border");
circle.draw();
System.out.println("\nCircle of red border");
redCircle.draw();
System.out.println("\nRectangle of red border");
redRectangle.draw();
}
}
装饰类:为已有的类,动态的添加额外功能。比如游戏里面的人物,每升级一次 就会额外添加一些技能。
7.1 装饰模式在Java I/O库中的应用
IO流实现细节:
Component抽象构件角色:io流中的InputStream,OutputStream,Reader,Writer
ConcreteComponent具体构件角色:io流中的FileInputStream,FileOutputStream
Decorate装饰角色:持有抽象构件的引用,FilterInputStream,FilterOutputStream
ConcreteDecorate具体装饰角色:负责给构件对象添加新的责任,BufferedInputStream,BufferedOutputStream等
8 v8 外观模式
外观模式处理的是类之间复杂的依赖关系,对子类功能进行包装实现一个大功能.客端调用时,只需要调用外观,而不需要知内问部过程。
public class ModuleA {
//示意方法
public void testA(){
System.out.println("done a");
}
}
//子功能模块
class ModuleB {
//示意方法
public void testB(){
System.out.println("done b");
}
}
//子功能模块
class ModuleC {
//示意方法
public void testC(){
System.out.println("done c");
}
}
/**
* 外观类
*/
class Facade {
//示意方法,满足客户端需要的功能
public void test(){
ModuleA a = new ModuleA();
a.testA();
ModuleB b = new ModuleB();
b.testB();
ModuleC c = new ModuleC();
c.testC();
}
}
//客户端 调用类,用外观类 完成整个模块功能
class Client {
public static void main(String[] args) {
Facade facade = new Facade();
facade.test();
}
}
10 v10桥接模式
将一个类分成2个或多个纬度的变化。
如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。
在抽象实类中,关系桥接抽象类
//桥接类
public interface DrawAPI {
public void drawCircle(int radius, int x, int y);
}
public class RedCircle implements DrawAPI {
@Override
public void drawCircle(int radius, int x, int y) {
System.out.println("Drawing Circle[ color: red, radius: "
+ radius +", x: " +x+", "+ y +"]");
}
}
public class GreenCircle implements DrawAPI {
@Override
public void drawCircle(int radius, int x, int y) {
System.out.println("Drawing Circle[ color: green, radius: "
+ radius +", x: " +x+", "+ y +"]");
}
}
//抽象实类中关联桥接类
public abstract class Shape {
//关联桥接类
protected DrawAPI drawAPI;
protected Shape(DrawAPI drawAPI){
this.drawAPI = drawAPI;
}
public abstract void draw();
}
public class Circle extends Shape {
private int x, y, radius;
public Circle(int x, int y, int radius, DrawAPI drawAPI) {
super(drawAPI);
this.x = x;
this.y = y;
this.radius = radius;
}
public void draw() {
drawAPI.drawCircle(radius,x,y);
}
}
//调用
public class BridgePatternDemo {
public static void main(String[] args) {
Shape redCircle = new Circle(100,100, 10, new RedCircle());
Shape greenCircle = new Circle(100,100, 10, new GreenCircle());
redCircle.draw();
greenCircle.draw();
}
}
11、组合模式
将对象组合成树形结构以表示“部分整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
比如:1、公司、子公司以及部门,2、书的目录,3、文件系统,4、菜单
//员工类
public class Employee {
private String name;
private String dept;
private int salary;
private List<Employee> subordinates;
//构造函数
public Employee(String name,String dept, int sal) {
this.name = name;
this.dept = dept;
this.salary = sal;
subordinates = new ArrayList<Employee>();
}
public void add(Employee e) {
subordinates.add(e);
}
public void remove(Employee e) {
subordinates.remove(e);
}
public List<Employee> getSubordinates(){
return subordinates;
}
public String toString(){
return ("Employee :[ Name : "+ name
+", dept : "+ dept + ", salary :"
+ salary+" ]");
}
}
//调用
public class CompositePatternDemo {
public static void main(String[] args) {
Employee CEO = new Employee("John","CEO", 30000);
Employee headSales = new Employee("Robert","Head Sales", 20000);
Employee headMarketing = new Employee("Michel","Head Marketing", 20000);
Employee clerk1 = new Employee("Laura","Marketing", 10000);
Employee clerk2 = new Employee("Bob","Marketing", 10000);
Employee salesExecutive1 = new Employee("Richard","Sales", 10000);
Employee salesExecutive2 = new Employee("Rob","Sales", 10000);
//将CEO的子结点添加到CEO持有List中
CEO.add(headSales);
CEO.add(headMarketing);
//headSales 下的结点添加 headSales List中
headSales.add(salesExecutive1);
headSales.add(salesExecutive2);
//headMarketing 下的结点添加 headMarketing list中
headMarketing.add(clerk1);
headMarketing.add(clerk2);
//打印该组织的所有员工
System.out.println(CEO);
for (Employee headEmployee : CEO.getSubordinates()) {
System.out.println(headEmployee);
for (Employee employee : headEmployee.getSubordinates())
{
System.out.println(employee);
}
}
}
}
//树形图结构如下:
12、享元模式
主要用于减少创建对象的数量,实现对象的多次复用。比如我们从缓存取数据,如果没有则新建后放到缓存,如果有则直接取出。
public abstract class Shape {
public abstract void draw();
}
public class Circle extends Shape{
private String color;
public Circle(String color){
this.color = color;
}
public void draw() {
System.out.println("画了一个" + color +"的圆形");
}
}
//享元工厂类
public class FlyweightFactory{
static Map<String, Shape> shapes = new HashMap<String, Shape>();
public static Shape getShape(String key){
Shape shape = shapes.get(key);
//如果shape==null,表示不存在,则新建,并且保持到共享池中
if(shape == null){
shape = new Circle(key);
shapes.put(key, shape);
}
return shape;
}
public static int getSum(){
return shapes.size();
}
}
//调用
public class Client {
public static void main(String[] args) {
Shape shape1 = FlyweightFactory.getShape("红色");
shape1.draw();
Shape shape2 = FlyweightFactory.getShape("灰色");
shape2.draw();
Shape shape3 = FlyweightFactory.getShape("绿色");
shape3.draw();
System.out.println("一共绘制了"+FlyweightFactory.getSum()+"中颜色的圆形");
}
}