所谓设计模式,就是一套被反复使用的代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人了解、保证代码可靠性。Java设计模式大体上分为三大类,如下:
- 创建型模式(5种):工厂方法模式( Factory Method)、抽象工厂模式( Abatract Factory)、单例模式( Singleton)、建造者模式( Builder)、原型模式( Prototype)
- 结构型模式(7种):适配器模式( Adapter)、装饰器模式( Decorator)、代理模式( Proxy)、外观模式( Facade)、桥接模式( Bridge)、组合模式( Composite)、享元模式( Flyweight)
- 行为型模式(11种):策略模式( Strategy)、模板方法模式( Template Method)、观察者模式( Observer)、迭代子模式( Iterator)、责任链模式( Chain Of Responsibility)、命令模式( Command)、备忘录模式( Memento)、状态模式( State)、访问者模式( Visitor)、中介者模式( Mediator)、解释器模式( Interpreter)
对以下最常用的几种模式展开描述。更全面的模式详解,请参考http://c.biancheng.net/view/1359.html
1.工厂方法模式-Factory Method
“创建与使用分离”的特点。工厂类可以根据条件生成不同的子类实例,这些子类有一个公共的抽象父类并且实现了相同的方法,但是这些方法针对不同的数据进行了不同的操作(多态方法)。当得到子类的实例后,开发人员可以调用基类中的方法而不必考虑到底返回的是哪一个子类的实例。
public class AbstractFactoryTest
{
public static void main(String[] args)
{
try
{
Product a;
AbstractFactory af;
af=(AbstractFactory) ReadXML1.getObject();
a=af.newProduct();
a.show();
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
}
}
//抽象产品:提供了产品的接口
interface Product
{
public void show();
}
//具体产品1:实现抽象产品中的抽象方法
class ConcreteProduct1 implements Product
{
public void show()
{
System.out.println("具体产品1显示...");
}
}
//具体产品2:实现抽象产品中的抽象方法
class ConcreteProduct2 implements Product
{
public void show()
{
System.out.println("具体产品2显示...");
}
}
//抽象工厂:提供了厂品的生成方法
interface AbstractFactory
{
public Product newProduct();
}
//具体工厂1:实现了厂品的生成方法
class ConcreteFactory1 implements AbstractFactory
{
public Product newProduct()
{
System.out.println("具体工厂1生成-->具体产品1...");
return new ConcreteProduct1();
}
}
//具体工厂2:实现了厂品的生成方法
class ConcreteFactory2 implements AbstractFactory
{
public Product newProduct()
{
System.out.println("具体工厂2生成-->具体产品2...");
return new ConcreteProduct2();
}
}
2.抽象工厂模式-Abstract Factory
抽象工厂模式:是一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构。 和工厂方法模式的区别:是工厂方法模式的升级版本,工厂方法模式只生产一个等级的产品,而抽象工厂模式可生产多个等级的产品。
//以下举例相对简单,详细且复杂的,请参考上面的链接
interface AbstractFactory{
public Product1 newProduct1();
public Product2 newProduct2();
}
//产品族的定义,可根据不同的情况,创建多个不同的产品族类
class ConcreteFactory1 implements AbstractFactory{
//以下是不同等级的产品构成一个产品族
public Product1 newProduct1() {
System.out.println("具体工厂 1 生成-->具体产品 11...");
return new ConcreteFactory11();
}
public Product2 newProduct2() {
System.out.println("具体工厂 1 生成-->具体产品 21...");
return new ConcreteFactory21();
}
}
3.代理模式-Proxy
由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。实际开发中,按照使用目的不同,代理可以分为:远程代理、虚拟代理、保护代理、Cache代理、防火墙代理、同步化代理、智能引用代理。
public class ProxyTest
{
public static void main(String[] args)
{
Proxy proxy=new Proxy();
proxy.Request();
}
}
//抽象主题
interface Subject
{
void Request();
}
//真实主题
class RealSubject implements Subject
{
public void Request()
{ System.out.println("访问真实主题方法..."); }
}
//代理
class Proxy implements Subject
{
private RealSubject realSubject;
public void Request()
{
if (realSubject==null)
{
realSubject=new RealSubject();
}
realSubject.Request();
System.out.println("代理执行request方法");
}
}
4.单例模式-Singleton
单例模式的定义:一个类只有一个实例,且该类能自行创建这个实例的一种模式。在类的内部创建一个实例,构造器全部设置为private,所有方法均在该实例上改动,在创建上要注意类的实例化只能执行一次,可以采用多种方法实现,如Synchronized关键字或者内部类等机制。
单例模式有3个特点:①单例类只有一个实例对象;②该单例对象必须由单例类自行创建;③单例类对外提供一个访问该单例的全局访问点。
//3.1懒汉式:类加载时没有生成单例,只有当第一次调用getInstance方法时才去创建这个单例
class LazySingleton{
//保证实例在所有线程中同步
private static volatile LazySingleton instance = null;
//private避免类在外部被实例化
private LazySingleton(){}
public static synchronized LazySingleton getInstance(){
//getInstance方法前加同步
if(instance==null){
instance = new LazySingleton();
}
return instance;
}
}
//3.2饿汉式:类一旦加载就创建一个单例,保证在调用getInstance方法之前单例已经存在
class HungrySingleton{
private static final HungrySingleton instance = new HungrySingleton();
private HungrySingleton(){}
public static HungrySingleton getInstance(){
return instance;
}
}
//3.3双重检测锁模式单例
class Singleton{
private static Singleton instance = null;
private Singleton(){}
public static Singleton getInstance(){
if(instance==null){
synchronized (Singleton.class){
if(instance==null){
instance=new Singleton();
}
}
}
return instance;
}
}
5.适配器模式
将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作。适配器模式分为类结构型模式和对象结构型模式两种,前者类之间的耦合度比后者高,且要求程序员了解现有组件库中的相关组件的内部结构,所以应用相对较少些。
优点:①客户端通过适配器可以透明地调用目标接口;②复用了现存的类,程序员不需要修改原有代码而重用现有的适配者类;③将目标类和适配者类解耦,解决了目标类和适配者类接口不一致的问题。
interface Target{
public void request();
}
class Adaptee{
public void specificRequest(){
System.out.println("适配者中的业务代码被调用!");
}
}
//类适配器类
class ClassAdapter extends Adaptee implements Target{
public void request(){
specificRequest();
}
}
//对象适配器代码
class ObjectAdapter extends Adaptee implements Target{
private Adaptee adaptee;
public ObjectAdapter(Adaptee adaptee){
this.adaptee=adaptee;
}
public void request(){
adaptee.specificRequest();
}
}
//main方法调用(省略)