java常用设计模式

本文深入讲解了单例模式、工厂模式、代理模式等多种经典设计模式的实现方式与应用场景,并通过具体示例帮助读者理解每种模式的特点及优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


单例模式.
简而言之,就是一个类只有一个实例。
Singleton.java:
package com.xfimti.sigleton;

public class Singleton
{
 /*第一种方式。*/
 private static Singleton singleton = new Singleton();
 /*第二种方式。*/
 private static Singleton mySingleton = null;
 
 private Singleton()
 {
 }
 
 /*第一种方式。*/
 public static Singleton getSingletonInstance()
 {
  return singleton;
 }
 
 /*第二种方式。*/
 public static Singleton getInstance()
 {
  if(mySingleton == null)
  {
   mySingleton = new Singleton();
  }
  return singleton;
 }
}
工厂模式
工厂模式又分为静态工厂和实例工厂方法。
a. 静态工厂。
Dao.java
package com.xfimti.factory;

public interface Dao
{
 public void save();
}

DaoImpl4Mysql.java
package com.xfimti.factory;

public class DaoImpl4Mysql implements Dao
{

 public void save()
 {
  System.out.println("save for dao...");
 }

}
(静态工厂)StaticFactory.java
package com.xfimti.factory;

/**静态工厂或简单工厂*/
public class StaticFactory
{
 public static Dao getDao(String type)
 {
  if(type.equals("mysql"))
  {
   return new DaoImpl4Mysql();
  }
  return null;
 }
}
测试类:Main.java
package com.xfimti.factory;

public class Main
{
 public static void main(String[] args)
 {
  /*使用静态工厂 。*/
//  Dao dao = StaticFactory.getDao("mysql");
//  dao.save();
  
  Dao dao = new DaoFactoryMethod().getDao("mysql");
  dao.save();
 }
}
(实例工厂方法)
DaoFactoryMethod.java
package com.xfimti.factory;

/*实例工厂方法。*/
public class DaoFactoryMethod
{
 public Dao getDao(String type)
 {
  if(type.equals("mysql"))
  {
   return new DaoImpl4Mysql();
  }
  return null;
 }
}
代理模式
代理分类静态代理和动态代理。一般使用动态代理,因为它更灵活,代码更简洁。
常规情况是:调用者—>目标对象。
代理:调用者-->代理-->目标对象。
b. 静态代理。
Dao.java
package com.xfimti.proxy;

public interface Dao
{
 public void save();
 public void update();
 public void select();
 public void delete();
}
实现类:DaoImpl.java
package com.xfimti.proxy;
public class DaoImpl implements Dao
{
 public void save()
 {
  System.out.println("save for dao..");
 }

 public void delete()
 {
  System.out.println("delete for dao...");
 }

 public void select()
 {
  System.out.println("select for dao...");
 }

 public void update()
 {
  System.out.println("update for dao...");
 }
}
静态代理:DaoStaticProxy.java
package com.xfimti.proxy;

public class DaoStaticProxy implements Dao
{
 private Dao dao = null;

 public void save()
 {
  System.out.println("before save it,log something...");
  dao.save();
 }
 
 public DaoStaticProxy()
 {
  this.dao = new DaoImpl();
 }

 public void delete()
 {
  System.out.println("before delete it,log something...");
  dao.delete();
 }

 public void select()
 {
  dao.select();
 }

 public void update()
 {
  System.out.println("before update it,log something...");
  dao.update();
 }
}
package com.xfimti.proxy;

public class Main
{

 /**
  * @param args
  */
 public static void main(String[] args)
 {
  /*常规方式*/
//  Dao dao = new DaoImpl();
//  dao.save();
  
  /*使用静态代理*/
//  Dao dao = new DaoStaticProxy();
//  dao.save();
  
  /*使用动态代理*/
  Dao dao = new DaoDynamicProxy(new DaoImpl()).getDaoProxy();
  dao.save();
  dao.select();
  dao.update();
  dao.delete();
  
  /**通过使用静态代理和动态代理,我们可以发现。使用静态代理代码太多。使用动态代理,很灵活。*/
 }
}
动态代理:DaoDynamicProxy.java
package com.xfimti.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class DaoDynamicProxy implements InvocationHandler
{
 private Dao dao;
 
 public DaoDynamicProxy(Dao dao)
 {
  this.dao = dao;
 }
 /**代理规则。*/
 public Object invoke(Object arg0, Method method, Object[] params) throws Throwable
 {
  /*获取方法名称。*/
  String methodName = method.getName();
  /*只对保存,修改,删除方法做日志记录。*/
if(methodName.equals("save") || methodName.equals("update") || methodName.equals("delete"))
  {
   System.out.println("执行"+methodName+"操作之前,做日志记录。。"); 
  }
  
  Object obj = method.invoke(dao, params);
  return obj;
 }

 /**定义一个获取目标代理的方法。*/
 public Dao getDaoProxy()
 {
  /*
   * newProxyInstance方法的参数说明。
   * 第一个参数:指明目标对象的ClassLoader。
   * 第二个参数:目标对象所实现的接口。
   * 第三个参数:处理器。
   * */
 return (Dao) Proxy.newProxyInstance(dao.getClass().getClassLoader(), dao.getClass().getInterfaces(), this);
 }
}
责任链模式
像servlet中的过滤器,就是如此。
下面模拟一个过滤字符的例子。
Filter.java
package com.xfimti.chain;

public interface Filter
{
 public String doFilter(String msg,FilterChain chain);
}
KeyWordFilter.java
package com.xfimti.chain;

public class KeyWordFilter implements Filter
{
 public String doFilter(String msg,FilterChain chain)
 {
  System.out.println("KeyWordFilter request>>>>>>>>");
  msg = msg.replaceAll("delete", "[delete]").replaceAll("insert", "[insert]").replaceAll("update", "[update]");
  chain.doFilter(msg,chain);
  System.out.println("KeyWordFilter response<<<<<<<");
  return msg;
 }
}
FilterChain.java
package com.xfimti.chain;

import java.util.ArrayList;
import java.util.List;

public class FilterChain implements Filter
{
 public List<Filter> getList()
 {
  return list;
 }

 public void setList(List<Filter> list)
 {
  this.list = list;
 }

 public FilterChain()
 {
  list = new ArrayList<Filter>();
 }
 
 private List<Filter> list;
 
 public FilterChain addFilter(Filter filter)
 {
  list.add(filter);
  return this;
 }
 
 public String doFilter(String msg,FilterChain chain)
 {
  String result = msg;
  int index = 0;
  if(index < chain.getList().size())
  {
   Filter filter = chain.getList().get(index);
   List<Filter> ls = chain.getList();
   ls.remove(index);
   chain.setList(ls);
   result = filter.doFilter(msg,chain);
   index++;   
  }
  return result;
 }

}
测试类:Main.java
package com.xfimti.chain;

public class Main
{

 /**
  * @param args
  */
 public static void main(String[] args)
 {
  /*过滤字符串*/
  String str = "<html>,delete,insert,update";
  FilterChain chain = new FilterChain();
  chain.addFilter(new KeyWordFilter()).addFilter(new WordFilter());
  str = chain.doFilter(str,chain);
  System.out.println(str);
 }
}
运行结果:
KeyWordFilter request>>>>>>>>
WordFilter request>>>>>>>>
WordFilter response<<<<<<<
KeyWordFilter response<<<<<<<
<html>,[delete],[insert],[update]
观察者模式
java.awt中的事件处理就是如此。
看下面的例子。
事件处理类:Boy.java
package com.xfimti.observer;

public interface Boy
{
 public void happy(Girl g);
 public void unhappy(Girl g);
}
Gril.java
package com.xfimti.observer;

import java.util.ArrayList;
import java.util.List;

/**事件源。*/
public class Girl
{
 private String state;
 private String name;
 private  List<Boy> boys;
 
 public String getName()
 {
  return name;
 }

 public void setName(String name)
 {
  this.name = name;
 }

 public Girl(String name)
 {
  this.name = name;
  boys = new ArrayList<Boy>();
 }
 
 /**添加事件处理器。*/
 public void addListener(Boy boy)
 {
  boys.add(boy);
 }
 
 public void setState(String state)
 {
  this.state = state;
  if(this.state.equals("happy"))
  {
   for(Boy boy:boys)
   {
    boy.happy(this);
   }
  }
  else if(this.state.equals("unhappy"))
  {
   for(Boy boy:boys)
   {
    boy.unhappy(this);
   }
  }
  else
  {
   throw new RuntimeException("无法处理。");
  }
 }
}
测试类:Main.java
package com.xfimti.observer;
public class Main
{
 public static void main(String[] args)
 {
  Girl g = new Girl("校花");
  
  g.addListener(new Boy()
  {
   public void happy(Girl g)
   {
System.out.println("<"+g.getName()+">[boy1处理方案:]<happy>->>>>"+"看电影去。");
   }

   public void unhappy(Girl g)
   {
System.out.println("<"+g.getName()+">[boy1处理方案:]<unhappy>->>>>上网去。");
   }
  }
  );
  g.addListener(new Boy()
  {
   public void happy(Girl g)
   {
System.out.println("<"+g.getName()+">[boy2处理方案:]<happy>->>>>"+"看风景。");
   }

   public void unhappy(Girl g)
   {
System.out.println("<"+g.getName()+">[boy2处理方案:]<unhappy>->>>>买东西。");
   }
  }
  );
  g.setState("happy");
  g.setState("unhappy");
  g.setState("unkonwn");
 }

}
运行结果:
<校花>[boy1处理方案:]<happy>->>>>看电影去。
<校花>[boy2处理方案:]<happy>->>>>看风景。
<校花>[boy1处理方案:]<unhappy>->>>>上网去。
<校花>[boy2处理方案:]<unhappy>->>>>买东西。
Exception in thread "main" java.lang.RuntimeException: 无法处理。
 at com.xfimti.observer.Girl.setState(Girl.java:54)
 at com.xfimti.observer.Main.main(Main.java:37)

模板模式
模板就不用多说了。看下面的例子。
Dao.java(定义了N多方法。)
package com.xfimti.template;

public interface Dao
{
 public void save(Object obj);
 public <T> T find(Integer id);
 public <T> T findByName(String name);
 public void update(Object obj);
 public void delete(Integer id);
}
DaoSupport.java(它实现了Dao.java中的所有方法。)
package com.xfimti.template;

public abstract class DaoSupport implements Dao
{

 public void delete(Integer id)
 {

 }

 public Object find(Integer id)
 {
  return null;
 }

 public Object findByName(String name)
 {
  return null;
 }

 public void save(Object obj)
 {

 }

 public void update(Object obj)
 {

 }
}
UserDaoImpl.java
package com.xfimti.template;

/**AbstractDao实现了Dao的所有方法。继承它就拥有它的所有功能,你可以扩展自己的功能。*/
public class UserDaoImpl extends DaoSupport implements Dao
{
 /**扩展新的功能。*/
 public void updateByName(String name)
 {
  
 }
}
User.java
package com.xfimti.template;

public class User
{
 private int id;
 private String name;
 private int age;
 public int getAge()
 {
  return age;
 }
 public void setAge(int age)
 {
  this.age = age;
 }
 public int getId()
 {
  return id;
 }
 public void setId(int id)
 {
  this.id = id;
 }
 public String getName()
 {
  return name;
 }
 public void setName(String name)
 {
  this.name = name;
 }
}
在这里,DaoSupport.java就是一个模板。你其他的像Product模块等可以通过这样的方式实现,减少代码。代码复用度高。
策略模式

策略模式感觉挺深奥,其实我们平常可以就用过了。看下面的例子。
Dao.java
package com.xfimti.strategy;

public interface Dao
{
 public Object get(String sql,Object[] args);
}
AbstractDao.java
package com.xfimti.strategy;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public abstract class AbstractDao implements Dao
{

 /**在这里假定参数类型一致,args以String为例。*/
 public Object get(String sql, Object[] args)
 {
  Object obj = null;
  Connection con = null;
  PreparedStatement ps = null;
  ResultSet rs = null;
  
  try
  {
   con = DriverManager.getConnection("");
   ps = con.prepareStatement(sql);
   for(int i=0;i<args.length;i++)
   {
    ps.setString(i+1, (String)args[i]);
   }
   rs = ps.executeQuery();
   obj = ObjectMapper(rs);
  } catch (SQLException e)
  {
   e.printStackTrace();
  }
  return obj;
 }
 
 /**将ResultSet封闭对象信息部分抽取出来。*/
 public abstract Object ObjectMapper(ResultSet rs)throws SQLException;
}

Customer.java
package com.xfimti.strategy;

public class Customer
{
 private int id;
 private String name;
 private int age;
 public int getAge()
 {
  return age;
 }
 public void setAge(int age)
 {
  this.age = age;
 }
 public int getId()
 {
  return id;
 }
 public void setId(int id)
 {
  this.id = id;
 }
 public String getName()
 {
  return name;
 }
 public void setName(String name)
 {
  this.name = name;
 }
}
CustomerDaoImpl.java
package com.xfimti.strategy;

import java.sql.ResultSet;
import java.sql.SQLException;

/**继承AbstractDao,它实现了Dao中的方法,所以这里只需要实现ObjectMapper就可以了。*/
public class CustomerDaoImpl extends AbstractDao
{
 public Object ObjectMapper(ResultSet rs) throws SQLException
 {
  Customer c = new Customer();
  while(rs.next())
  {
   c.setId(rs.getInt("id"));
   c.setName(rs.getString("name"));
   c.setAge(rs.getInt("age"));
  }
  if(rs != null)
   rs.close();
  return c;
 }
}
这里面可能不只Customer,还有其他的。都可以这样做。减少代码。代码复用度高。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值