1. 程式人生 > >Java設計模式之結構模式

Java設計模式之結構模式

tin 提高 mode his base 說明 concrete 抽象類 table

一、外觀模式

分析:外觀模式是為子系統的一組接口提供一個統一的界面,數據庫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" );
}

Java設計模式之結構模式