Java中常用的设计模式
1.模式--模板方法:
public abstract class Father { //所有子类共有的方法 public void start(){ System.out.println("开始了"); } //不同的子类做着不同的事 public abstract void doIng(); //所有子类共有的方法 public void end(){ System.out.println("结束了"); } }
public class Son1 extends Father{ @Override public void doIng() { System.out.println("第一个儿子要吃饭"); } }
public class Son2 extends Father{ @Override public void doIng() { System.out.println("第二个儿子要睡觉"); } }
/* * 模板方法: 定义一个类做为所有子类的操作流程,暴露抽象方法让子类重写完成自己特定的操作 */ public class Test { public static void main(String[] args) { Son1 son1 = new Son1(); son1.start(); son1.doIng(); son1.end(); Son2 son2 = new Son2(); son2.start(); son2.doIng(); son2.end(); } }
运行结果:
可见这样增加了程序的扩展性,当又增加一种方式的时候只需要继承Father类重写你需要做的事就可以了
模式2--单例模式
//单例模式:饿汉式与懒汉式,保证一个类仅有一个实例,并提供一个访问它的全局访问点 class LogUtil{ private static LogUtil sLogUtil; //将构造函数私有化 private LogUtil() { } public static LogUtil getInstance() { if (sLogUtil == null) { sLogUtil = new LogUtil(); } return sLogUtil; } }
如果现在有两个线程同时在执行getInstance方法,第一个线程刚执行完第2行,还没执行第3行,这个时候第二个线程执行到了第2行,它会发现sLogUtil还是null,于是进入到了if判断里面。这样你的单例模式就失败了,因为创建了两个不同的实例。
//加同步锁解决线程问题 public synchronized static LogUtil getInstance() { if (sLogUtil == null) { sLogUtil = new LogUtil(); } return sLogUtil; }
//解决每次加锁判断的效率问题 public static LogUtil getInstance() { if (sLogUtil == null) { synchronized (LogUtil.class) { if (sLogUtil == null) { sLogUtil = new LogUtil(); } } } return sLogUtil; }
模式3--单例模式,策略模式的核心思想就是把算法提取出来放到一个独立的对象中。
public interface Father { //子类需要做什么事,自己去重写 public abstract void doIng(); }
public class Son1 implements Father{ @Override public void doIng() { System.out.println("第一个儿子要吃饭"); } }
public class Son2 implements Father{ @Override public void doIng() { System.out.println("第二个儿子要睡觉"); } }
/* * 策略模式: 它定义了算法家庭,分别封装起来。让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。 */ public class Test { public static void main(String[] args) { Utils utils = new Utils(); utils.execute(new Son1()); utils.execute(new Son2()); /* * 打印结果: * 第一个儿子要吃饭 * 第二个儿子要睡觉 */ } } class Utils{ /* * 用父类接收子类对象,用父类对象去调用子类方法,father为接口,里面的方法为抽象的 * 毕竟不能调用抽象方法,所以会自动转换为传进来的子类的实例,也就会去执行子类中的方法了 */ public void execute(Father father){ father.doIng(); } }
来源于--其它模式:http://blog.csdn.net/sinyu890807/article/category/1381137