设计模式之结构型模式 Java pattern 设计模式分类

##结构型模式

描述在面向对象设计中,类和对象的几种结构关系,设计好了会为后续代码的维护带来很大的方便。

  • 外观模式(Facade);
  • 适配器模式(Adapter);
  • 代理模式(Proxy);
  • 装饰模式(Decorator);
  • 桥模式(Bridge);
  • 组合模式(Composite);
  • 享元模式(Flyweight);

###外观模式(Facade)又称门面模式;
GoF这样定义:

为子系统中的一组接口提供一个一致的界面, Facade 模式定义了一个高层 接口,这个接口使得这一子系统更加容易使用。

外观模式,在我理解就是给一组对象提供一个对外统计的操作方式 ,让外部使用者不用操心内部工作。如一个汽车,一个电脑,你点开机,硬盘,CPU,内存,显卡就都开始工作了,关机时也一样。这里对我们操作者来说其实就是一个开关。

``
package design.pattern.facade;

/**
* Created by Aaron on 15/9/14.
*/
public class User {
public static void main(String[] args)throws InterruptedException{
Computer computer=new Computer();
computer.startup();
System.out.println("--------shutdown-----------");
computer.shutdown();
}
}

package design.pattern.facade;
/**
* Created by Aaron on 15/9/14.
*/
public class Computer {
private CPU cpu;
private Memory memory;
private GraphicsCard graphicsCard;
private Disk disk;

public Computer() {
this.cpu = new CPU();
this.memory = new Memory();
this.graphicsCard = new GraphicsCard();
this.disk = new Disk();
}

public void startup(){
this.cpu.startup();
this.memory.startup();
this.disk.startup();
this.graphicsCard.startup();
}
public void shutdown(){
this.graphicsCard.shutdown();
this.disk.shutdown();
this.memory.shutdown();
this.cpu.shutdown();
}



}

package design.pattern.facade;

/**
* Created by Aaron on 15/9/14.
*/
public class CPU {
public void startup(){
System.out.println(this.getClass().getSimpleName()+"启动");
}
public void shutdown(){
System.out.println(this.getClass().getSimpleName()+"关闭");
}
}

package design.pattern.facade;

/**
* Created by Aaron on 15/9/14.
*/
public class Disk {
public void startup(){
System.out.println(this.getClass().getSimpleName()+"启动");
}
public void shutdown(){
System.out.println(this.getClass().getSimpleName()+"关闭");
}
}

package design.pattern.facade;

/**
* Created by Aaron on 15/9/14.
*/
public class GraphicsCard {
public void startup(){
System.out.println(this.getClass().getSimpleName()+"启动");
}
public void shutdown(){
System.out.println(this.getClass().getSimpleName()+"关闭");
}
}

package design.pattern.facade;

/**
* Created by Aaron on 15/9/14.
*/
public class Memory {
public void startup(){
System.out.println(this.getClass().getSimpleName()+"启动");
}
public void shutdown(){
System.out.println(this.getClass().getSimpleName()+"关闭");
}
}

输出结果:

CPU启动
Memory启动
Disk启动
GraphicsCard启动
--------shutdown-----------
GraphicsCard关闭
Disk关闭
Memory关闭
CPU关闭

###适配器模式(Adapter);
GoF这样定义:

将一个类的接口转换成客户希望的另外一个接口。 Adapter 模式使得原本 由于接口不兼容而不能一起工作的那些类可以一起工作。

我的事例理解:如咱们家中常用的洗衣机,当我们要与我们的水龙头进行对接时,中间要借助一个中间者“转换头”,它在这里就起到了适配作用。

``
package design.pattern.adapter;

/**
* Created by Aaron on 15/9/14.
*/
public class WashingMachine {
public void connectPort(IWashFaucetAdapter washportadapter){
System.out.print(washportadapter.outToWashingPort()+" success!");
}
}

package design.pattern.adapter;

/**
* Created by Aaron on 15/9/14.
*/
public interface IWashFaucetAdapter {
String outToWashingPort();
}

package design.pattern.adapter;

/**
* Created by Aaron on 15/9/14.
*/
public class WashingFaucetAdapter extends Faucet implements IWashFaucetAdapter{

public String outToWashingPort(){
return "transform"+this.port()+" to washing port!";
}
}

package design.pattern.adapter;

/**
* Created by Aaron on 15/9/14.
* 水龙头
*/

public class Faucet {
public String port(){
System.out.print("facucet port .....");
return "facucet port";
}
}

package design.pattern.adapter;

/**
* Created by Aaron on 15/9/14.
*/
public class User {
public static void main(String[] args){
// 创建水龙头、洗衣机、镶接头
WashingMachine washingMachine=new WashingMachine();
WashingFaucetAdapter washingFaucetAdapter= new WashingFaucetAdapter();
// 进行适配
washingMachine.connectPort(washingFaucetAdapter);

}
}

输出结果:

facucet port .....transformfacucet port to washing port! success!

###代理模式(Proxy);
GoF这样定义:

为其他对象提供一个代理以控制对这个对象的访问。

这里就以找工作为例吧,现在我们找工作都会通过找工作平台来进行找工作,因为他们有资源,他们比较专业。我们告诉他们要找什么样的工作他们就会给我们推荐什么样的工作,在这个环节中,类似51job,100offer这样的平台就是所谓的招聘代理。
他代理公司进行招人。同时也方便了我们去找工作。

下面是代码实现:

package design.pattern.proxy;

/**
* Created by Aaron on 15/9/14.
*/
public interface IRecruitment {
void recruitment(String user);
}

package design.pattern.proxy;

/**
* Created by Aaron on 15/9/14.
*/
public class FounderWork implements IRecruitment{
public void recruitment(String user){
System.out.println(this.getClass().getSimpleName()+"招聘员工"+user+"成功!");
}
}

package design.pattern.proxy;

/**
* Created by Aaron on 15/9/14.
*/
public class WorkProxy implements IRecruitment {
private IRecruitment recruitment;

public WorkProxy() {
this.recruitment = new FounderWork();
}

@Override
public void recruitment(String user) {
before();
this.recruitment.recruitment(user);
after();
}

public void before() {
System.out.println(this.getClass().getSimpleName() + "进行招聘前工作准备!");
}

public void after() {
System.out.println(this.getClass().getSimpleName() + "进行招聘完成后工作收尾!");
}

}


package design.pattern.proxy;

/**
* Created by Aaron on 15/9/14.
*/
public class User {
public static void main(String[] args){
new WorkProxy().recruitment("Aaron");
}
}

输出:

WorkProxy进行招聘前工作准备!
FounderWork招聘员工Aaron成功!
WorkProxy进行招聘完成后工作收尾!

###装饰模式(Decorator);
GoF这样定义:

动态地给一个对象添加一些额外的职责。就扩展功能而言, Decorator 模 式比生成子类方式更为灵活。

我们可以拿我们的扩音器为例,假如一个mp3的有声音,那么它的声音不是很大,稍微远一点我们就不能听到了,这里就会用一个扩音器,放在mp3旁边,离稍微远点也能享受音乐的快乐了。

这里,扩音器就是装饰器,他使mp3的声音变大。有时扩音器也可以改变声音的音质,变的更好听。

下面是代码实现:

package design.pattern.decorator;

/**
* Created by Aaron on 15/9/14.
*/
public interface ISoundable {
void sound();
}

package design.pattern.decorator;

/**
* Created by Aaron on 15/9/14.
*/
public class MP3 implements ISoundable{
public void sound(){
System.out.println("small sound from mp3!");
}
}

package design.pattern.decorator;

/**
* Created by Aaron on 15/9/14.
*/
public class SoundDecorator implements ISoundable {
private ISoundable soundable;

public SoundDecorator(ISoundable soundable) {
this.soundable = soundable;
}

public void sound(){
this.soundable.sound();
System.out.println("make sound beautiful");
System.out.println("make sound aloud ");
}
}

package design.pattern.decorator;

/**
* Created by Aaron on 15/9/14.
*/
public class User {
public static void main(String[] args){
new SoundDecorator(new MP3()).sound();
}
}

输出:

small sound from mp3!
make sound beautiful
make sound aloud 

###桥接模式(Bridge);
GoF这样定义:

将抽象部分与它的实现部分分离,使它们都可以独立地变化。

这里还举一个生活中常用到的例子,洗衣机有多种,但我们当我们没有接到水龙头上的管子时,我们可以去商店里买,这里可能会有大小长短各不相同的管子,但都可以与我们的洗衣机相连接进行使用。

这里我们变化的是多种洗衣机和多种管子,我们为洗衣机做一个抽像类。可以设置不同的管子。

``
package design.pattern.bridge;

/**
* Created by Aaron on 15/9/14.
*/
public interface IPip {
String color();
}

package design.pattern.bridge;

/**
* Created by Aaron on 15/9/14.
* 水龙头
*/

public class RedPip implements IPip{
public String color(){
return "Red";
}
}

package design.pattern.bridge;

/**
* Created by Aaron on 15/9/14.
* 水龙头
*/

public class BluePip implements IPip{
public String color(){
return "blue pip";
}
}


package design.pattern.bridge;

/**
* Created by Aaron on 15/9/14.
*/
public abstract class AbstractWashingMachine {
private IPip pip;

public IPip getPip() {
return pip;
}

public void setPip(IPip pip) {
this.pip = pip;
System.out.println(this.getClass().getSimpleName()+" set "+pip.color()+" "+pip.getClass().getSimpleName());
}
}


package design.pattern.bridge;

/**
* Created by Aaron on 15/9/14.
*/
public class ChinaWashingMachine extends AbstractWashingMachine {
}

package design.pattern.bridge;

/**
* Created by Aaron on 15/9/14.
*/
public class HaierWashingMachine extends AbstractWashingMachine {
}

package design.pattern.bridge;

/**
* Created by Aaron on 15/9/14.
*/
public class User {
public static void main(String[] args){
new HaierWashingMachine().setPip(new BluePip());
new HaierWashingMachine().setPip(new RedPip());
new ChinaWashingMachine().setPip(new BluePip());
}
}

输出:

HaierWashingMachine set blue pip BluePip
HaierWashingMachine set Red RedPip
ChinaWashingMachine set blue pip BluePip

###组合模式(Composite);
GoF这样定义:

将对象组合成树形结构以表示“部分-整体”的层次结构。Composite使 得客户对单个对象和复合对象的使用具有一致性。

这里我们最常见的就是公司与部门的关系,其实就是整体与部分的关系。

代码

package design.pattern.composite;

import java.util.Vector;

/**
* Created by Aaron on 15/9/14.
*/
public abstract class AbstractCompany {
private String name;
private Vector<AbstractCompany> companys=new Vector<AbstractCompany>();
public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
public void display(int deep) {
StringBuilder sb=new StringBuilder();
for(int i=0;i<deep;i++){
sb.append("\t");
}
sb.append(this.getName());
System.out.println(sb.toString());
int l = this.getCompanys().size();
if (l > 0) {
for (int i = 0; i < l; i++) {
this.getCompanys().get(i).display(deep+2);
}
}
}
public Vector<AbstractCompany> getCompanys() {
return companys;
}
public void removeCompany(AbstractCompany company){
this.companys.remove(company);
}
public void addCompany(AbstractCompany company) {
this.companys.add(company);
}
}

package design.pattern.composite;

/**
* Created by Aaron on 15/9/14.
*/
public class Company extends AbstractCompany {
public Company(String name) {
this.setName(name);
}

}

package design.pattern.composite;

/**
* Created by Aaron on 15/9/14.
*/
public class TechDepartment extends AbstractCompany {
public TechDepartment() {
}
public TechDepartment(String name) {
this.setName(name);
}
}

package design.pattern.composite;

/**
* Created by Aaron on 15/9/14.
*/
public class UIDepartment extends AbstractCompany {
public UIDepartment(String name) {
this.setName(name);
}

public UIDepartment() {
}
}

package design.pattern.composite;

/**
* Created by Aaron on 15/9/14.
*/
public class CEO {
public static void main(String[] args) {
AbstractCompany company = new Company("总公司");
AbstractCompany abc = new TechDepartment("技术一部");
company.addCompany(abc);
abc = new TechDepartment("技术二部");
company.addCompany(abc);
abc = new TechDepartment("技术三部");
company.addCompany(abc);
abc = new UIDepartment("UI一部");
company.addCompany(abc);
abc = new UIDepartment("UI二部");
company.addCompany(abc);
abc = new UIDepartment("UI三部");
company.addCompany(abc);
AbstractCompany abc1 = new UIDepartment("UI一组");
abc.addCompany(abc1);
abc1 = new UIDepartment("UI二组");
abc.addCompany(abc1);
abc1 = new UIDepartment("UI三组");
abc.addCompany(abc1);
company.display(0);
}
}


输出:

总公司
        技术一部
        技术二部
        技术三部
        UI一部
        UI二部
        UI三部
                UI一组
                UI二组
                UI三组

###享元模式(Flyweight)
GoF这样定义:

运用共享技术有效地支持大量细粒度的对象。

咱们这里会想到数据库连接池,对,就是它,咱们先看一下类图。

`示例代码如下:`
package design.pattern.flayweight;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Vector;

/**
* Created by Aaron on 15/9/14.
*/
public class ConnectionPool {
private Vector<Connection> pool;
private static ConnectionPool instance;
private int poolSize=10;
private String url = "jdbc:mysql://127.0.0.1:3306/mysql";
private String username = "root";
private String password = "root";
private String driverClassName = "com.mysql.jdbc.Driver";
private ConnectionPool(){
this.pool=new Vector<Connection>();

for (int i = 0; i < poolSize; i++) {
try {
Class.forName(driverClassName);
pool.add(DriverManager.getConnection(url, username, password));
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
}

public static synchronized ConnectionPool getInstance(){
if(instance==null){
return instance=new ConnectionPool();
}
return instance;
}

public synchronized Connection getConnection(){
Connection connection=null;
if(pool.size()>0){
connection=pool.get(0);
pool.remove(connection);
}
return connection;
}

public synchronized void release(Connection conn){
pool.add(0,conn);
}

}

package design.pattern.flayweight;

import java.sql.Connection;

/**
* Created by Aaron on 15/9/14.
*/
public class User {
public static void main(String args[]){
ConnectionPool pool=ConnectionPool.getInstance();
Connection connection=pool.getConnection();
System.out.println(connection);
connection=pool.getConnection();
System.out.println(connection);
pool.release(connection);
connection=pool.getConnection();
System.out.println(connection);
}
}


输出:

com.mysql.jdbc.JDBC4Connection@2d8e6db6
com.mysql.jdbc.JDBC4Connection@23ab930d
com.mysql.jdbc.JDBC4Connection@23ab930d