Java设计模式之结构模式

一、外观模式

分析:外观模式是为子系统的一组接口提供一个统一的界面,数据库JDBC连接应用就是外观模式的一个典型例子,
特点:降低系统的复杂度,增加灵活性。
结果:代码示例:

public class DBCompare {
  Connection conn = null;
  PreparedStatement prep = null;
  ResultSet rset = null; 
  try {
     Class.forName( "<driver>" ).newInstance();
     conn = DriverManager.getConnection( "<database>" );
    
     String sql = "SELECT * FROM <table> WHERE <column name> = ?";
     prep = conn.prepareStatement( sql );
     prep.setString( 1, "<column value>" );
     rset = prep.executeQuery();
     if( rset.next() ) {
        System.out.println( rset.getString( "<column name" ) );
     }
  } catch( SException e ) {
     e.printStackTrace();
  } finally {
     rset.close();
     prep.close();
     conn.close();
  }
}
-----------------------
-- 修改后的统一接口
public class DBCompare {

  String sql = "SELECT * FROM <table> WHERE <column name> = ?";  

  try {
     Mysql msql=new mysql(sql);
     msql.setString( 1, "<column value>" );
     rset = msql.executeQuery();
     if( rset.next() ) {
        System.out.println( rset.getString( "<column name" ) );
     }
  } catch( SException e ) {
     e.printStackTrace();
  } finally {
     mysql.close();
     mysql=null;
  }
}

二、代理模式

分析:代理模式是比较有用途的一种模式,而且变种多样,用途从小的架构设计到系统的大架构设计基本上都覆盖了,
为什么需要使用代理模式?一、授权机制(访问权限) 二、某个客户端不能直接操作到那个对象,但又和那个对象有所互动(
通过中间代理处理这种操作)。
结果:代码示例:

-- 定义权限的用户
public class ForumPermissions implements Cacheable {
/**
* Permission to read object.
*/
public static final int READ = 0;

/**
* Permission to administer the entire sytem.
*/
public static final int SYSTEM_ADMIN = 1;

/**
* Permission to administer a particular forum.
*/
public static final int FORUM_ADMIN = 2;

/**
* Permission to administer a particular user.
*/
public static final int USER_ADMIN = 3;

/**
* Permission to administer a particular group.
*/
public static final int GROUP_ADMIN = 4;

/**
* Permission to moderate threads.
*/
public static final int MODERATE_THREADS = 5;

/**
* Permission to create a new thread.
*/
public static final int CREATE_THREAD = 6;

/**
* Permission to create a new message.
*/
public static final int CREATE_MESSAGE = 7;

/**
* Permission to moderate messages.
*/
public static final int MODERATE_MESSAGES = 8;

.....

public boolean isSystemOrForumAdmin() {
  return (values[FORUM_ADMIN] || values[SYSTEM_ADMIN]);
}

.....

}
-- 只有管理员才有权限操作
public class ForumProxy implements Forum {

private ForumPermissions permissions;
private Forum forum; 
this.authorization = authorization; 

public ForumProxy(Forum forum, Authorization authorization,
ForumPermissions permissions)
{
this.forum = forum;
this.authorization = authorization;
this.permissions = permissions;
}

.....

public void setName(String name) throws UnauthorizedException,
ForumAlreadyExistsException
{
  //只有是系统或论坛管理者才可以修改名称
  if (permissions.isSystemOrForumAdmin()) {
    forum.setName(name);
  }
  else {
    throw new UnauthorizedException();
  }
}

三、适配器模式

说明:适配器模式是将两个不兼容的类纠合在一起使用,同时也属于结构性模式,一个是适配者和宁一个是被适配者两者
身份结合在一起。
为何使用?
我们经常会遇到两个没有关系的类会联系在一起使用,第一个解决方法就是,修改各自的接口类,但是我们没有源代码,或者,我们
不会为了一个应用修改这个接口类,那这种情况下,就该考虑使用适配器模式
如何使用?
用组合和继承的方法去使用该模式
结果:代码示例:

-- 两个没有关系的类
public class SquarePeg{
  public void insert(String str){
    System.out.println("SquarePeg insert():"+str);
  }

}

public class RoundPeg{
  public void insertIntohole(String msg){
    System.out.println("RoundPeg insertIntoHole():"+msg);
}
}
-- 继承关系实现
public class PegAdapter extends SquarePeg{

  private RoundPeg roundPeg;

  public PegAdapter(RoundPeg peg)(this.roundPeg=peg;)

  public void insert(String str){super.insert(str); roundPeg.insertIntoHole(str);}

}

--第二种方式,通过接口实现的方式
-- 两个没有联系的接口类
public interface IRoundPeg{
  public void insertIntoHole(String msg);

}

public interface ISquarePeg{
  public void insert(String str);

}
-- 实现该接口的方法和熟悉
public class SquarePeg implements ISquarePeg{
  public void insert(String str){
    System.out.println("SquarePeg insert():"+str);
  }

}

public class RoundPeg implements IRoundPeg{
  public void insertIntohole(String msg){
    System.out.println("RoundPeg insertIntoHole():"+msg);
  }
}
-- 适配器模式类,实现两个没有联系的接口类
public class PegAdapter implements IRoundPeg,ISquarePeg{

  private RoundPeg roundPeg;
  private SquarePeg squarePeg;

  // 构造方法
  public PegAdapter(RoundPeg peg){this.roundPeg=peg;}
  // 构造方法
  public PegAdapter(SquarePeg peg)(this.squarePeg=peg;)

  public void insert(String str){ roundPeg.insertIntoHole(str);}

}

四、组合模式

分析:组合模式可以这样理解,在我们程序中常用的js前端的应用,大部分都是树型结构的,而组合模式就相当于
树型结构的模式,通过迭代器遍历出来。
组合模式的优势:使客户端调用简单,更容易在组合过程中加入部件属性和方法。
结果:代码示例:

---定义抽象类
public abstract class Equipment
{
  private String name; 
  //实价
  public abstract double netPrice();
  //折扣价格
  public abstract double discountPrice();
  //增加部件方法  
  public boolean add(Equipment equipment) { return false; }
  //删除部件方法
  public boolean remove(Equipment equipment) { return false; }
  //注意这里,这里就提供一种用于访问组合体类的部件方法。
  public Iterator iter() { return null; }
  
  public Equipment(final String name) { this.name=name; }
}
-- 继承该抽象类
public class Disk extends Equipment
{
  public Disk(String name) { super(name); }
  //定义Disk实价为1
  public double netPrice() { return 1.; }
  //定义了disk折扣价格是0.5 对折。
  public double discountPrice() { return .5; }
}

五、装饰者模式

分析:装饰者模式是给对象添加额外的一些职责,就像在墙上刷油漆,使用装饰者模式比生成子类实现的都灵活
为什么要使用装饰者模式?
我们通常可以继承来实现功能的拓展,若这些功能的拓展比较多,那么势必生成很多子类,增加系统的复杂性,
使用装饰者模式可以将一些功能动态的加入,提供了"即插即用"的方法,在程序运行期间可以随时插入新增一些
功能。
结果:代码示例

----定义接口
public interface Work
{ 
  public void insert();

}

--接口类的实现

public class SquarePeg implements Work{
  public void insert(){
    System.out.println("方形桩插入");
  }
}

--装饰者模式额外添加的功能
public class Decorator implements Work{

  private Work work;
  //额外增加的功能被打包在这个List中
  private ArrayList others = new ArrayList();

  //在构造器中使用组合new方式,引入Work对象;
  public Decorator(Work work)
  {
    this.work=work;
   
    others.add("挖坑");

    others.add("钉木板");
  }

  public void insert(){

    newMethod();
  }

  
  //在新方法中,我们在insert之前增加其他方法,这里次序先后是用户灵活指定的    
  public void newMethod()
  {
    otherMethod();
    work.insert();


  } 
  public void otherMethod()
  {
    ListIterator listIterator = others.listIterator();
    while (listIterator.hasNext())
    {
      System.out.println(((String)(listIterator.next())) + " 正在进行");
    }

  } 
}

六、桥接模式

分析:任何事物对象都有抽象和行为之分,例如人,人是一种抽象,人分男人和女人等;人有行为,行为也有各种体现,
所以,人与人的行为这两个概念也反映了抽象与行为之分。在面向对象设计中,对象概念实际是由属性与行为两个部分组成的,
属性我们可以认为是一种静止的,是一种抽象,一般情况下,行为是包含在一个对象中的,但是,在有的情况下,
我们需要将这些行为也进行归类,形成一个总的行为接口,这也是桥接模式的优势。
为什么使用桥接模式?
不希望抽象部分和行为有一种固定的绑定联系,而是应该可以动态联系的。
结果:代码示例:

-- 抽象接口类
public abstract class Coffee
{
   CoffeeImp coffeeImp;

   public void setCoffeeImp() {
     this.CoffeeImp = CoffeeImpSingleton.getTheCoffeImp();
   }

  public CoffeeImp getCoffeeImp() {return this.CoffeeImp;}

   public abstract void pourCoffee();
}

public abstract class CoffeeImp
{
   public abstract void pourCoffeeImp();
}
--- 继承类
public class MediumCoffee extends Coffee
{
   public MediumCoffee() {setCoffeeImp();}

   public void pourCoffee()
   {
     CoffeeImp coffeeImp = this.getCoffeeImp();
     //我们以重复次数来说明是冲中杯还是大杯 ,重复2次是中杯
     for (int i = 0; i < 2; i++)
     {

      coffeeImp.pourCoffeeImp();
    }
  
   }
}
//大杯
public class SuperSizeCoffee extends Coffee
{
   public SuperSizeCoffee() {setCoffeeImp();}

   public void pourCoffee()
   {
     CoffeeImp coffeeImp = this.getCoffeeImp();
     //我们以重复次数来说明是冲中杯还是大杯 ,重复5次是大杯
     for (int i = 0; i < 5; i++)
     {

      coffeeImp.pourCoffeeImp();
    }
  
   }
}
-- 主方法
public static void main(String[] args){

MediumCoffee mediumCoffee = new MediumCoffee();
mediumCoffee.pourCoffee();
}

七、享元模式

分析:享元模式是避免大量拥有相同的小类的开销(如耗费内存),使大家共享一个类(元类)
为什么使用?
该模式是提高效率和性能的模式,会大大加快程序的运行速度,应用场合很多,比如你要从数据库读取一系列
字符窜,这些字符窜是有许多是重复的,因此,将这些字符窜存储在池中。
结果:代码示例:

--接口定义
 public interface Flyweight 
{
  public void operation( ExtrinsicState state );
}

//用于本模式的抽象数据类型(自行设计)
public interface ExtrinsicState { }

--实现该接口
public class ConcreteFlyweight implements Flyweight {
  private IntrinsicState state; 
  
  public void operation( ExtrinsicState state ) 
  { 
      //具体操作
  }
}


-- 享元模式类
public class FlyweightFactory { 
  //Flyweight pool
  private Hashtable flyweights = new Hashtable(); 

  public Flyweight getFlyweight( Object key ) { 
    Flyweight flyweight = (Flyweight) flyweights.get(key); 
    if( flyweight == null ) {
      //产生新的ConcreteFlyweight
      flyweight = new ConcreteFlyweight(); 
      flyweights.put( key, flyweight ); 
    } 
    return flyweight; 
  } 
} 
-- 主方法(实现 享元模式)
public static void main(String[] args)
{
  FlyweightFactory factory = new FlyweightFactory(); 
Flyweight fly1 = factory.getFlyweight( "Fred" ); 
Flyweight fly2 = factory.getFlyweight( "Wilma" );
}

 

posted @ 2017-10-17 22:01  怀念-2018  阅读(843)  评论(0编辑  收藏  举报