java设计模式(二)—— 装饰、门面、享元、原型、状态、策略

一、Decorator装饰设计模式

Decorator装饰设计模式是动态给一个对象添加一些额外的职责,但同时又不影响对象本身已有的功能。

Decorator装饰设计模式中的两种角色:

Decoratee被装饰者:即需要功能增强的原始对象,即目标对象。

Decorator装饰者:为原始对象提供功能增强的对象。

interface VisualComponent {
	public void draw();
}

// Decoratee被装饰者
class TextArea implements VisualComponent {
	public void draw() {
		System.out.println("Draw TextArea");
	}
}

// 抽象Decorator装饰者
abstract class Decorator implements VisualComponent {
	protected VisualComponent component;

	public Decorator(VisualComponent component) {
		this.component = component;
	}

	public void draw() {
		component.draw();
	}
}

// 滚动条Decorator
class ScrollDecorator extends Decorator {
	public ScrollDecorator(VisualComponent component) {
		super(component);
	}

	public void draw() {
		super.draw();
		scrollTo();
	}

	public void scrollTo() {
		System.out.println("TextArea scroll to…");
	}
}

// 边框Decorator
class BorderDecorator extends Decorator {
	public BorderDecorator(VisualComponent component) {
		super(component);
	}

	public void draw() {
		super.draw();
		drawBorder();
	}

	public void drawBorder() {
		System.out.println("Draw border for TextArea …");
	}
}

public class DecoratorPattern {
    public static void main(String[] args) {
        // 画一个普通的TextArea
        TextArea textArea = new TextArea();
        textArea.draw();
        // 画一个带滚动条的TextArea
        ScrollDecorator scroll = new ScrollDecorator(new TextArea());
        scroll.draw();
        // 画一个带边框的TextArea
        BorderDecorator border = new BorderDecorator(new TextArea());
        border.draw();
        // 画一个既带边框又带滚动条的TextArea
        BorderDecorator border2 = new BorderDecorator(new ScrollDecorator(
                new TextArea()));
        border2.draw();
    }
}

输出结果:

Draw TextArea

Draw TextArea
TextArea scroll to…

Draw TextArea
Draw border for TextArea …

Draw TextArea
TextArea scroll to…
Draw border for TextArea …

二、Facade门面设计模式

门面设计模式为子系统中的一组接口提供一个一致的界面,应用程序本身将不再直接依赖于子系统原件,而是依赖一个门面,当想要修改某个原件的行为时,只需要修改实现类即可,应用程序本身不需要做任何修改。其实门面设计模式就是我们平时写的最多的一个接口,然后一个实现类。
MySql和Oracle不但JDBC连接的属性不同,一些sql语法也不太相同,使用门面模式之后,
将MySql换成Oracle,只需要将具体的实现类替换就可以了,不会影响应用程序。

public class FacadePattern {
	private static final String SQL = "select * from aaa";
	private static Statement st;
	private static ResultSet rs;

	public static void main(String[] args) {
		// MySql
		JDBCUtil util = new MySqlUtil();
		st = util.getStatement();
		rs = util.getResult(st, SQL);
		util.close(st, rs);
		// Oracle
		util = new OracleUtil();
		st = util.getStatement();
		rs = util.getResult(st, SQL);
		util.close(st, rs);
	}
}

// JDBC Facade
interface JDBCUtil {
	public Statement getStatement();

	public ResultSet getResult(Statement st, String sql);

	public void close(Statement st, ResultSet rs);
}

// MySql JDBC
class MySqlUtil implements JDBCUtil {
	private static Connection conn = null;
	private static Statement st = null;
	private static ResultSet rs = null;
	private static final String DRIVER = "com.mysql.jdbc.Driver";
	private static final String URL = "jdbc:mysql://localhost:3306/test";
	private static final String USERNAME = "root";
	private static final String PASSWORD = "root";
	static {
		// 写入驱动所在处,打开驱动
		try {
			Class.forName(DRIVER);
			conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
		} catch (Exception e) {
			System.err.println("MySql数据库连接失败,失败原因:" + e.getMessage());
			e.printStackTrace();
		}
	}

	public Statement getStatement() {
		try {
			st = conn.createStatement();
		} catch (Exception e) {
			System.err.println("MySql获取Statement失败,失败原因:" + e.getMessage());
			e.printStackTrace();
			return null;
		}
		return st;
	}

	public ResultSet getResult(Statement st, String sql) {
		try {
			rs = st.executeQuery(sql);
		} catch (Exception e) {
			System.err.println("MySql获取ResultSet失败,失败原因:" + e.getMessage());
			e.printStackTrace();
			return null;
		}
		return rs;
	}

	public void close(Statement st, ResultSet rs) {
		try {
			if (rs != null)
				rs.close();
			if (st != null)
				st.close();
			if (conn != null)
				conn.close();
		} catch (Exception e) {
			System.err.println("MySql数据库连接关闭失败,失败原因:" + e.getMessage());
			e.printStackTrace();
		}
	}
}

// Oracle JDBC
class OracleUtil implements JDBCUtil {
	private static Connection conn = null;
	private static Statement st = null;
	private static ResultSet rs = null;
	private static final String DRIVER = "oracle.jdbc.driver.OracleDriver";
	private static final String USERNAME = "scott";
	private static final String PASSWORD = "tiger";
	private static final String URL = "jdbc:oracle:thin:@10.9.143.59:1521:oss";
	static {
		// 写入驱动所在处,打开驱动
		try {
			Class.forName(DRIVER);
			conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
		} catch (Exception e) {
			System.err.println("Oracle数据库连接失败,失败原因:" + e.getMessage());
			e.printStackTrace();
		}
	}

	public Statement getStatement() {
		try {
			st = conn.createStatement();
		} catch (Exception e) {
			System.err.println("Oracle获取Statement失败,失败原因:" + e.getMessage());
			e.printStackTrace();
			return null;
		}
		return st;
	}

	public ResultSet getResult(Statement st, String sql) {
		try {
			rs = st.executeQuery(sql);
		} catch (Exception e) {
			System.err.println("Oracle获取ResultSet失败,失败原因:" + e.getMessage());
			e.printStackTrace();
			return null;
		}
		return rs;
	}

	public void close(Statement st, ResultSet rs) {
		try {
			if (rs != null)
				rs.close();
			if (st != null)
				st.close();
			if (conn != null)
				conn.close();
		} catch (Exception e) {
			System.err.println("Oracle数据库连接关闭失败,失败原因:" + e.getMessage());
			e.printStackTrace();
		}
	}
}
三、Flyweight享元设计模式

享元设计模式是为了避免大量拥有相同内容的小类重复创建,而使大家共享一个类的模式。

//享元工厂
class AuthorFactory{
	private static Map<String, Author> authors = new HashMap<String, Author>();
	public static Author getAuthor(String name) {
		Author author = authors.get(name);
		if (author == null) {
			author = new Author(name);
			authors.put(name, author);
		}
		return author;
	}
}

// 将Author作者类设计为可共享的享元
class Author {
	
	private String name;

	public String getName() {
		return name;
	}

	public Author(String name) {
		this.name = name;
	}
}

public class FlyweightPattern {
    public static void main(String[] args) {
        Author a = AuthorFactory.getAuthor("hzb");
        System.out.println(a);
        Author b = AuthorFactory.getAuthor("cxd");
        System.out.println(b);
        Author c = AuthorFactory.getAuthor("hzb");
        System.out.println(c);
    }
}

输出结果:

com.hzb.flyweight.Author@1fb8ee3
com.hzb.flyweight.Author@61de33
com.hzb.flyweight.Author@1fb8ee3

四、Prototype原型设计模式

原型设计模式是指用原型实例指定创建对象的种类,并且通过拷贝这些原型来创建新的对象。
Prototype原型模式允许一个对象再创建另外一个可定制的对象,根本无需知道任何关于对象创建的细节。
克隆只是实现Prototype原型模式的一种方法,也可以直接通过new对象的方式创建原型实例,二者区别在于:
(1).通过new方式创建的原型和现存的实例对象没有任何联系。
(2).通过克隆方法创建的原型,虽然也是创建新对象,但是将原型实例对象的数据复制到了新的对象中,
相当于使用被克隆对象的数据作为克隆对象的初始数据。
Prototype原型设计模式和Singleton单类设计模式是相对的,单类模式中,在整个程序生命周期里,单类模式类的实例对象只有一个。
而Prototype原型设计模式则正好相反,每次都返回的是原型类的不同实例对象。

public class Prototype {
	public static void main(String[] args) {
		Shape shape = new Circle();
		System.out.println(shape.getShapeName());
		// 通过clone()方法获得一个对象拷贝
		Shape shape2 = (Shape) shape.clone();
		System.out.println(shape2.getShapeName());
	}

}
// 抽象原型类
abstract class Shape implements Cloneable {
	String shapeName;

	public String getShapeName() {
		return shapeName;
	}

	public void setShapeName(String shapeName) {
		this.shapeName = shapeName;
	}

	// 实现了Colneable接口的类,可以使用clone()方法复制对象
	public Object clone() {
		try {
			return super.clone();
		} catch (CloneNotSupportedException e) {
			System.err.println("此对象不支持复制");
		}
		return null;
	}
}
// 具体原型类
class Circle extends Shape {
	public Circle() {
		setShapeName("Circle shape");
	}
}
输出结果:

Circle shape
Circle shape

五、Status状态设计模式

状态设计模式:用于改变对象的行为,在代理的生命周期里,随着状态变化从一个目标实现程序切换到另一个目标实现程序。

public class Status {
    public static void main(String[] args){ 
    	ServiceProvider sp = new ServiceProvider(new implementation1());
    	sp.service();
        sp.changeState(new implementation2()); 
        sp.service();
        sp.changeState(new implementation3());
        sp.service();
    } 
}

//状态接口  
interface State{  
   public void operation();  
}  
//状态实现类1  
class implementation1 implements State{  
    public void operation(){  
        System.out.println("Implementation1.operation()");  
    }   
}  
//状态实现类2  
class implementation2 implements State{  
    public void operation(){  
        System.out.println("Implementation2.operation()");  
    }   
}  
//状态实现类3  
class implementation3 implements State{  
    public void operation(){  
        System.out.println("Implementation3.operation()");  
    }   
} 
//服务提供者  
class ServiceProvider{  
    private State state;  
    public ServiceProvider(State state){  
         this.state = state;  
    }  
    //状态更改  
    public void changeState(State newState){  
         state = newState;  
    }  
    
    public void service(){  
          state.operation();  
    }  
}  
输出结果:

Implementation1.operation()
Implementation2.operation()
Implementation3.operation()

六、Strategy策略设计模式

策略设计模式主要是定义一系列的算法,把这些算法封装成单独的类,在运行时动态选择需要的算法

public class StrategyPattern {
	public static void main(String[] args){  
	    String testText = "aaaabbbb";   
	    TextStrategy strategy = null;
	    Random r = new Random();
	    if(r.nextInt(2)==0){
	    	strategy = new StrategyOne(testText);
	    	System.out.println(strategy.replace());
	    }else{
	    	strategy = new StrategyTwo(testText);
	    	System.out.println(strategy.replace());
	    }
	} 
}

//文本替换策略  
abstract class TextStrategy {   
    public String text;  
    public TextStrategy(String text) {   
        this.text = text;   
    }  
    public abstract String replace();   
}    
//替换算法1:将文本中"a"替换为"*"  
class StrategyOne extends TextStrategy {   
    public StrategyOne(String text) {   
        super(text);   
    }  
    public String replace() {   
        System.out.println("StrategyOne:");  
        String result = text.replaceAll("a", "*");   
        return result;   
    }  
}    
//替换算法2:将文本中"b"替换为"*"  
class StrategyTwo extends TextStrategy {   
    public StrategyTwo(String text) {   
        super(text);   
    }  
    public String replace() {   
        System.out.println("StrategyTwo:");  
        String result = text.replaceAll("b", "*");  
        return result;   
    }  
}    
输出结果:

StrategyOne:
****bbbb

StrategyTwo:
aaaa****


备注:java设计模式的学习主要是参考一位牛人http://blog.csdn.net/chjttony和从网上查找到的学习资料,装载请注明出处。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值