JAVA之设计模式(结构型模式)
来源:互联网 发布:中国高铁无砟 知乎 编辑:程序博客网 时间:2024/06/03 10:52
一、设计模式的六大原则
1、开闭原则(Open Close Principle)
开闭原则就是说:对扩展开放,对修改关闭。在程序需要进行扩展的时候,不能去修改原有的代码,实现一个热插拔的效果。所以一句话概括就是:为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类,后面的具体设计中我们会提到这点。
2、依赖倒转原则(Dependence Inversion Principle)
依赖倒转原则就是说:针对接口编程,依赖于抽象而不依赖于具体。它是开闭原则的基础。
3、里氏代换原则(Liskov Substitution Principle)
里氏代换原则就是说:任何基类可以出现的地方,子类一定可以出现。 LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。里氏代换原则是对“开-闭”原则的补充。实现“开-闭”原则的关键步骤就是抽象化。而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。
4、接口隔离原则(Interface Segregation Principle)
接口隔离原则就是说:使用多个隔离的接口,比使用单个接口要好。其实也就是降低类之间的耦合度的意思。
5、合成复用原则(Composite Reuse Principle)
合成复用原则就是说:尽量使用合成/聚合的方式,而不是使用继承。
6、迪米特原则(最少知道原则)(Demeter Principle)
迪米特原则就是说:一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。
二、设计模式的分类与应用
总体来说设计模式分为三大类(23种):
结构型模式(7种):适配器模式、装饰模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
1、适配器模式:将原有类或接口转换成客户端期望的类或接口,目的是消除由于接口不匹配所造成的类兼容性问题。分3种:
1>类适配器模式:适配器类实现了目标接口,并且继承了被适配的类。适配器类与被适配的类是一种继承关系。此模式由3部分组成:
①目标接口:即客户期望成的接口。
public interface Animal{public void say();}
目标接口的实现:
public class OrdinaryAnimal implements Animal{public void say() {System.out.println("普通动物的叫声");}}
②被适配的类:即通过目标接口也能访问的类
public class People {public void speak(){System.out.println("人类的语言");}}
③适配器类:
public class PeopleAdapter extends People implements Animal {public void say(){super.speak();}}
主入口:
public class Test {public static void main(String[] args) {Animal animal1 = new OrdinaryAnimal();animal1.say();Animal animal2 = new PeopleAdapter();animal2.say();}}
2>对象适配器模式:适配器类实现了目标接口,并且将被适配的类的作为适配器类的成员变量。适配器类与被适配的类是一种包含关系。此模式由3部分组成:
①目标接口:即客户期望成的接口。
public interface Animal{public void say();}
目标接口的实现:
public class OrdinaryAnimal implements Animal{public void say() {System.out.println("普通动物的叫声");}}
②被适配的类:即通过目标接口也能访问的类
public class People {public void speak(){System.out.println("人类的语言");}}
③适配器类:
public class PeopleAdapter implements Animal {private People people;public PeopleAdapter(People people){this.people=people;}public void say() {people.speak();}}
主入口:
public class Test {public static void main(String[] args) {Animal animal1 = new OrdinaryAnimal();animal1.say();People people = new People();Animal animal2 = new PeopleAdapter(people);animal2.say();}}
双向适配器:如果目标接口需要被适配的类适配,而被适配的类也需要目标接口适配,那么就需要将目标接口和被适配的类都作为适配器类的成员变量。
3>缺省适配器模式(单接口适配器模式):当不需要实现一个接口所提供的所有方法时,可先设计一个抽象类实现该接口,并为接口中每个方法提供一个默认实现(空方法),那么该抽象类的子类可以选择性地覆盖父类的某些方法来实现需求,它适用于不想使用接口中的所有方法的情况。
①原接口:
public interface Animal{public void say();public void run();public void fly();}
②抽象类:
public abstract class AnimalClass implements Animal {public void say(){}public void run(){}public void fly(){}}
③继承类1:
public class People extends AnimalClass{public void say(){System.out.println("人类的语言");}public void run(){System.out.println("使用双腿奔跑");}}
继承类2:
public class Bird extends AnimalClass {public void say(){System.out.println("鸟的语言");}public void fly(){System.out.println("使用翅膀飞翔");}}
主入口:
public class Test {public static void main(String[] args) {Animal people = new People();people.say();people.run();Animal bird = new Bird();bird.say();bird.fly();}}
2、装饰模式:动态地给一个对象增加一些额外的功能,就增加对象功能来说,装饰模式比添加继承子类实现更为灵活。此模式由4部分组成:
①抽象构件接口:被装饰类和装饰类都会实现此接口,实现统一管理。
public interface Animal {public void act();}
②被装饰类:原有的功能,需要在此基础上新增功能。
public class People implements Animal{public void act(){System.out.println("我可以用双脚走路");}}
③抽象装饰类:将构件接口作为本类的成员变量,通过此变量可以调用装饰之前的功能,而实际新增功能是在其子类中实现的。
public class SuperMan implements Animal{private Animal animal;public SuperMan(Animal animal){this.animal=animal;}public void act() {animal.act();}}
④具体装饰类:
public class IronMan extends SuperMan {public IronMan(Animal animal){super(animal);}public void act() {super.act();this.addAct();}public void addAct(){System.out.println("我还可以在天空飞");}}
主入口:
public class Test {public static void main(String[] args) {Animal animal1 = new People();Animal animal2 = new IronMan(animal1);animal2.act();}}
透明装饰模式:要求客户端程序不应该将对象声明为具体构件类型或具体装饰类型,而应该全部声明为抽象构件类型。透明装饰模式可以对一个已装饰过的对象进行多次装饰,得到更为复杂、功能更为强大的对象。
半透明装饰模式:要求客户端程序必须使用具体的装饰类型(具体装饰类)定义被装饰后的对象,所以不能对一个已装饰过的对象进行多次装饰。
3、代理模式:使用代理对象来替代实际对象,代理对象和实际对象要实现同一个接口。此模式由3部分组成:
①接口:声明了代理对象和实际对象的共同接口。
public interface Human{public void act();}
②实际对象:包含实际的业务。
public class RealPeople implements Human{public void act(){System.out.println("我是真正的幕后老大");}}
③代理对象:包含对实际对象的引用,从而在任何时候都可以操作实际对象。
public class proxyPeople implements Human {private Human human;public proxyPeople(){this.human=new RealPeople();}public void act() {human.act();}}
主入口:
public class Test {public static void main(String[] args) {Human people = new ProxyPeople();people.act();}}
4、外观模式:对多个对象的访问都是通过同一个对象统一管理统一访问。此模式由2部分组成:
①子系统角色1:
public class CPU {public void startup(){System.out.println("cpu startup!");}public void shutdown(){System.out.println("cpu shutdown!");}}
子系统角色2:
public class Memory {public void startup(){System.out.println("memory startup!");}public void shutdown(){System.out.println("memory shutdown!");}}
子系统角色3:
public class Disk {public void startup(){System.out.println("disk startup!");}public void shutdown(){System.out.println("disk shutdown!");}}
②外观角色:
public class Computer {private CPU cpu;private Memory memory;private Disk disk;public Computer(){cpu = new CPU();memory = new Memory();disk = new Disk();}public void startup(){System.out.println("start the computer!");cpu.startup();memory.startup();disk.startup();System.out.println("start computer finished!");}public void shutdown(){System.out.println("begin to close the computer!");cpu.shutdown();memory.shutdown();disk.shutdown();System.out.println("computer closed!");}}
主入口:
public class Test {public static void main(String[] args) { Computer computer = new Computer(); computer.startup(); computer.shutdown(); } }
5、桥接模式:当某个类同时存在两个独立变化的维度时,需要将这两个维度分离开,使两者可以独立扩展。此模式由4部分组成:
①维度1的抽象类:将维度2作为一个成员变量。
public abstract class Pen {protected Draw draw;Pen(Draw draw){this.draw=draw;}public abstract void draw();}
②维度1的子类1:
public class Pen1 extends Pen {Pen1(Draw draw){super(draw);}public void draw() {System.out.println("第1种笔正在画");this.draw.drawCircle();}}
维度1的子类2:
public class Pen2 extends Pen {Pen2(Draw draw){super(draw);}public void draw() {System.out.println("第2种笔正在画");this.draw.drawSquare();}}
维度1的子类3:
public class Pen3 extends Pen {Pen3(Draw draw){super(draw);}public void draw() {System.out.println("第3种笔正在画");this.draw.drawTriangle();}}
③维度2的接口:
public interface Draw {public void drawCircle();public void drawSquare();public void drawTriangle();}
④维度2的实现1:
public class Draw1 implements Draw {public void drawCircle() {System.out.println("画圆的第1种画法");}public void drawSquare() {System.out.println("画矩形的第1种画法");}public void drawTriangle() {System.out.println("画三角形的第1种画法");}}
维度2的实现2:
public class Draw2 implements Draw {public void drawCircle() {System.out.println("画圆的第2种画法");}public void drawSquare() {System.out.println("画矩形的第2种画法");}public void drawTriangle() {System.out.println("画三角形的第2种画法");}}
维度2的实现3:
public class Draw3 implements Draw {public void drawCircle() {System.out.println("画圆的第3种画法");}public void drawSquare() {System.out.println("画矩形的第3种画法");}public void drawTriangle() {System.out.println("画三角形的第3种画法");}}
主入口:
public class Test {public static void main(String[] args) {Draw draw1 = new Draw1();Draw draw2 = new Draw2();Draw draw3 = new Draw3();Pen pen1 = new Pen1(draw1);Pen pen2 = new Pen2(draw2);Pen pen3 = new Pen3(draw3);pen1.draw();pen2.draw();pen3.draw();}}
6、组合模式:也叫部分-整体模式,即组合对象的结构和单个对象的结构是相同的。此时本类的对象作为本类中的一个成员变量,常用于树结构或文件目录中的节点。
TreeNode:
import java.util.Vector;public class TreeNode {private TreeNode parentNode;private String nodeName;private Vector<TreeNode> childNodes=new Vector<TreeNode>();TreeNode(String name){this.nodeName = name;}public TreeNode getParentNode() {return parentNode;}public void setParentNode(TreeNode parentNode) {this.parentNode = parentNode;}public String getNodeName() {return nodeName;}public void setNodeName(String nodeName) {this.nodeName = nodeName;}public Vector<TreeNode> getChildNodes() {return childNodes;}public void setChildNodes(Vector<TreeNode> childNodes) {this.childNodes = childNodes;}public void addNode(TreeNode node){this.childNodes.add(node);}public void delNode(int num){this.childNodes.remove(num);}public String getChildNodeNames(TreeNode node){ String nodes = "";for(TreeNode tmp:node.childNodes){nodes+=tmp.getNodeName()+","+tmp.getChildNodeNames(tmp);}return nodes;} }
Tree:
public class Tree {static TreeNode root = new TreeNode("root");public static void main(String[] args) {TreeNode node1 = new TreeNode("node1");TreeNode node11 = new TreeNode("node11");TreeNode node12 = new TreeNode("node12");TreeNode node2 = new TreeNode("node2");TreeNode node21 = new TreeNode("node21");TreeNode node22 = new TreeNode("node22");TreeNode node221 = new TreeNode("node221");root.addNode(node1);root.addNode(node2);node1.addNode(node11);node1.addNode(node12);node2.addNode(node21);node2.addNode(node22);node22.addNode(node221);System.out.println(root.getChildNodeNames(root));}}
7、享元模式:主要目的是实现对象的共享,即共享池,当系统中有相应的对象时就不再创建该对象,因此可以减少内存的开销,通常与工厂模式一起使用。
import java.sql.Connection;import java.sql.DriverManager;import java.sql.SQLException;import java.util.Vector;public class ConnectionPool{private Vector<Connection> pool;private int poolSize = 10;Connection conn = null;private String url = "jdbc:mysql://localhost:3306/test";private String username = "root";private String password = "root";private String driverClassName = "com.mysql.jdbc.Driver";private ConnectionPool() {pool = new Vector<Connection>(poolSize);for (int i = 0; i < poolSize; i++) {try {Class.forName(driverClassName);conn = DriverManager.getConnection(url, username, password);pool.add(conn);} catch (ClassNotFoundException e) {e.printStackTrace();} catch (SQLException e) {e.printStackTrace();}}}//释放回到连接池 public synchronized void release() {pool.add(conn);}//得到连接池中的一个数据库连接 public synchronized Connection getConnection() {if (pool.size() > 0) {Connection conn = pool.get(0);pool.remove(conn);return conn;} else {return null;}}}
- Java设计模式之结构型模式
- Java设计模式之结构型模式
- java设计模式(结构型)之适配器模式
- java设计模式(结构型)之桥接模式
- java设计模式(结构型)之组合模式
- java设计模式(结构型)之装饰模式
- java设计模式(结构型)之外观模式
- java设计模式(结构型)之享元模式
- java设计模式(结构型)之代理模式
- JAVA之设计模式(结构型模式)
- java设计模式之结构型模式-装饰模式
- java设计模式之结构型模式-代理模式
- java 设计模式-结构模式之门面模式(facade)
- java设计模式之结构模式
- java设计模式之结构模型模式
- (6)设计模式之策略模式(结构型模式)
- (8)设计模式之装饰模式(结构型模式)
- 设计模式之结构型设计模式
- Node.JS基础知识
- Unity3D学习:制作粒子光环特效
- Javascript基础知识
- mysql ZIP免安装版本配置
- bzoj 4873 [Shoi2017]寿司餐厅
- JAVA之设计模式(结构型模式)
- SpringBootApplication背后的秘密
- PHP编程规范
- error Link 2005
- @Configuration
- stack模型融合
- JAVA之设计模式(行为型模式)
- NK1123: 转换到 COFF 期间失败
- Android基础知识