JAVA 几种常见的设计模式
2015-01-12 23:26
561 查看
一、单例模式
单例设计模式简单说就是无论程序如何运行,采用单例设计模式的类永远只会有一个实例化对象产生。常见方法是将采用单例设计模式的类的构造方法私有化,并在其内部产生该类的实例化对象,并将其封装成private static类型,时定义一个静态方法返回该类的实例。
根据实例对象按需产生或是加载类时就产生可分为懒汉式和饿汉式
饿汉式:
懒汉式:两种方案
方案一
二、模板模式
模板模式中父类为抽象类,其中制定一个涵盖了实现逻辑的方法,并将部分逻辑以具体方法的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。
不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。
先制定一个顶级逻辑框架,而将逻辑的细节留给具体的子类去实现。
我的理解是父类方法向子类指明了实现一个方法的具体步骤,其中某个步骤可以由父类指明具体实现,有些步骤则必须有子类亲自去具体实现.
下面是一个模板模式的例子
三、装饰模式
当想要对已有的对象进行功能增强时,可以定义类,将已有对象传入,基于已有的功能,并提供加强功能。那么自定义的该类称为装饰类。装饰类通常会通过构造方法接收被装饰的对象。并基于被装饰的对象的功能,提供更强的功能。
如:自定义字符输入流的包装类,通过这个包装类对底层字符输入流进行包装,让程序通过这个包装类读取某个文本文件(时,能够在读取的每行前面都加上有行号和冒号。
这时需要自定义一个MyFileReader,并传入一个FileReader类,生成自己想要的新功能新方法。
四、工厂模式
1.简单工厂模式(结合反射)
phone---打电话
PC---Eclipse
2.工厂方法模式
前面两种工厂模式在实际使用中较少,而抽象工厂模式在开发中最为常见,可以配合配置文件切换数据库等等。
如下面的例子,有Iphone和Galaxy实现Phone接口,MacBook和Laptop实现PC接口,AppleFactory和SamsungFactory继承Factory抽象类,AppleFactor只生产Iphone和MacBook,SamsungFactory只生产Galaxy和LapTop。现在要实现不改变程序代码的情况下,只对配置文件做修改达到切换工厂,以改变生产的产品的目的。
测试:
Iphone running....
MacBook running...
三星Galaxy手机 running...
三星 PC running...
以上实现了手动切换工厂实例,现在将Factory抽象类中加入静态方法getFactory()来读取配置文件
factory=factoryTest.SamsungFactory
测试:
三星Galaxy手机 running...
三星 PC running...
更改配置文件:
factory=factoryTest.AppleFactory
打印结果:
Iphone running....
MacBook running...
如上实现了,不改变代码而且换工厂以获取不同对象的功能。在实际应用中,工厂调用者并知道phone接口和pc接口的具体实现,只是获取到实例的引用,实现了对不应该暴露给用户资源的隐藏。
单例设计模式简单说就是无论程序如何运行,采用单例设计模式的类永远只会有一个实例化对象产生。常见方法是将采用单例设计模式的类的构造方法私有化,并在其内部产生该类的实例化对象,并将其封装成private static类型,时定义一个静态方法返回该类的实例。
根据实例对象按需产生或是加载类时就产生可分为懒汉式和饿汉式
饿汉式:
public class SingleDemo { private SingleDemo(){} private static SingleDemo s=new SingleDemo(); public static SingleDemo getInstance(){ return s; } }
懒汉式:两种方案
方案一
public class SingleDemo2 { private SingleDemo2(){}; private static SingleDemo2 s=null; public SingleDemo2 getInstance(){ if(s==null){ synchronized (SingleDemo2.class) { if(s==null){ s=new SingleDemo2(); } } } return s; } }方案二
class Single1 { private Single1() { } // 定义私有的内部静态类 对外隐藏 ,外部类加载时内部类不会同时加载 private static class SingleUtil { static Single1 single_new = new Single1(); } public static Single1 getInstance() { // 此时有调用到内部类的静态方法,加载,实现了延迟加载的目的,同时类加载只加载一次,因此线程安全 return SingleUtil.single_new; } }
二、模板模式
模板模式中父类为抽象类,其中制定一个涵盖了实现逻辑的方法,并将部分逻辑以具体方法的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。
不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。
先制定一个顶级逻辑框架,而将逻辑的细节留给具体的子类去实现。
我的理解是父类方法向子类指明了实现一个方法的具体步骤,其中某个步骤可以由父类指明具体实现,有些步骤则必须有子类亲自去具体实现.
下面是一个模板模式的例子
public abstract class Produce { protected void make() { proNum();// 获取商品编号 System.out.println("生产一产品主体"); color();// 定制颜色 pack();// 包装 } protected abstract void proNum(); protected abstract void color(); protected abstract void pack(); } class MyProduce extends Produce{ @Override protected void proNum() { // TODO Auto-generated method stub System.out.println("赋予商品编号"+System.currentTimeMillis()); } @Override protected void color() { // TODO Auto-generated method stub System.out.println("赋予商品红色"); } @Override protected void pack() { // TODO Auto-generated method stub System.out.println("将产品使用环保纸盒包装"); } }测试:
public class BlogTest { public static void main(String[] args) { MyProduce produce=new MyProduce(); produce.make(); } }
三、装饰模式
当想要对已有的对象进行功能增强时,可以定义类,将已有对象传入,基于已有的功能,并提供加强功能。那么自定义的该类称为装饰类。装饰类通常会通过构造方法接收被装饰的对象。并基于被装饰的对象的功能,提供更强的功能。
如:自定义字符输入流的包装类,通过这个包装类对底层字符输入流进行包装,让程序通过这个包装类读取某个文本文件(时,能够在读取的每行前面都加上有行号和冒号。
这时需要自定义一个MyFileReader,并传入一个FileReader类,生成自己想要的新功能新方法。
public class BlogTest{ public static void main(String[] args) throws Exception { MyFileReader in = new MyFileReader(new FileReader(new File( "D:\\test4.txt"))); String line; while ((line = in.readLine()) != null) { System.out.print(line); } } } class MyFileReader { private FileReader reader; private int lineNum; public int getLineNum() { return lineNum; } public void setLineNum(int lineNum) { this.lineNum = lineNum; } public MyFileReader(FileReader reader) { this.reader = reader; } private MyFileReader() { } public String readLine() throws Exception { lineNum++; StringBuffer buf = new StringBuffer(); // buf.append(lineNum+":"); int data = 0; while ((data = reader.read()) != -1) { if ('\n' == data) break; buf.append((char) data); } if (buf.length() == 0) return null; return lineNum + ":\t" + new String(buf.toString().getBytes("UTF-8"), "UTF-8"); } }
四、工厂模式
1.简单工厂模式(结合反射)
public abstract class Electronics { abstract void run(); }
public class PC extends Electronics { @Override void run() { // TODO Auto-generated method stub System.out.println("PC---Eclipse"); } }
public class Phone extends Electronics { @Override void run() { // TODO Auto-generated method stub System.out.println("phone---打电话"); } }下面是一个工厂类,根据传入的ClassName反射生成一个实例
public class Factory { public static Object getInstance(String className) throws Exception{ Class clazz=Class.forName(className); return clazz.newInstance(); } }测试
public class MyTest { public static void main(String[] args) throws Exception { Electronics phone = (Electronics) Factory.getInstance(Phone.class.getName()); phone.run(); Electronics pc = (Electronics) Factory.getInstance(PC.class.getName()); pc.run(); } }结果:
phone---打电话
PC---Eclipse
2.工厂方法模式
interface Factory { public abstract Electronics getInstance(); } class PhoneFactory implements Factory { @Override public Electronics getInstance() { // TODO Auto-generated method stub return new Phone(); } } class PCFactory implements Factory { @Override public Electronics getInstance() { // TODO Auto-generated method stub return new PC(); } }用户需要不同设备只需调用不同工厂
public class MyTest { public static void main(String[] args) throws Exception { Factory phoneFactory = new PhoneFactory(); Electronics phone = phoneFactory.getInstance(); Factory pcFactory = new PCFactory(); Electronics pc = pcFactory.getInstance(); phone.run(); pc.run(); } }3.抽象工厂模式
前面两种工厂模式在实际使用中较少,而抽象工厂模式在开发中最为常见,可以配合配置文件切换数据库等等。
如下面的例子,有Iphone和Galaxy实现Phone接口,MacBook和Laptop实现PC接口,AppleFactory和SamsungFactory继承Factory抽象类,AppleFactor只生产Iphone和MacBook,SamsungFactory只生产Galaxy和LapTop。现在要实现不改变程序代码的情况下,只对配置文件做修改达到切换工厂,以改变生产的产品的目的。
interface PC{ void run(); }
interface Phone{ void run(); }
public class Iphone implements Phone { @Override public void run() { // TODO Auto-generated method stub System.out.println("Iphone running...."); } }
public class Galaxy implements Phone { @Override public void run() { // TODO Auto-generated method stub System.out.println("三星Galaxy手机 running..."); } }
public class LapTop implements PC{ @Override public void run() { // TODO Auto-generated method stub System.out.println("三星 PC running..."); } }
public class MacBook implements PC { @Override public void run() { // TODO Auto-generated method stub System.out.println("MacBook running..."); } }下面是工厂类:
public abstract class Factory { abstract PC getPC(); abstract Phone getPhone(); static void getFactory() { }; } class AppleFactory extends Factory { @Override public PC getPC() { // TODO Auto-generated method stub return new MacBook(); } @Override public Phone getPhone() { // TODO Auto-generated method stub return new Iphone(); } } class SamsungFactory extends Factory { @Override public PC getPC() { // TODO Auto-generated method stub return new LapTop(); } @Override public Phone getPhone() { // TODO Auto-generated method stub return new Galaxy(); } }
测试:
public class MyTest { public static void main(String[] args) throws Exception { Factory factory=new AppleFactory();//此处建立苹果工厂 Phone phone=factory.getPhone(); PC pc=factory.getPC(); phone.run(); pc.run(); } }打印结果:
Iphone running....
MacBook running...
public class MyTest { public static void main(String[] args) throws Exception { Factory factory=new SamsungFactory();//此处建立苹果工厂 Phone phone=factory.getPhone(); PC pc=factory.getPC(); phone.run(); pc.run(); } }打印结果:
三星Galaxy手机 running...
三星 PC running...
以上实现了手动切换工厂实例,现在将Factory抽象类中加入静态方法getFactory()来读取配置文件
public abstract class Factory { abstract PC getPC(); abstract Phone getPhone(); static Factory getFactory() throws Exception { Properties properties = new Properties(); properties.load(new FileReader(new File("d:\\properties.config"))); String factory = properties.getProperty("factory"); Class clazz = Class.forName(factory); return (Factory) clazz.newInstance(); }; }配置文件如下:
factory=factoryTest.SamsungFactory
测试:
public class MyTest { public static void main(String[] args) throws Exception { Factory factory=Factory.getFactory(); Phone phone=factory.getPhone(); PC pc=factory.getPC(); phone.run(); pc.run(); } }打印结果:
三星Galaxy手机 running...
三星 PC running...
更改配置文件:
factory=factoryTest.AppleFactory
打印结果:
Iphone running....
MacBook running...
如上实现了,不改变代码而且换工厂以获取不同对象的功能。在实际应用中,工厂调用者并知道phone接口和pc接口的具体实现,只是获取到实例的引用,实现了对不应该暴露给用户资源的隐藏。
相关文章推荐
- 几种常见设计模式的JAVA实现例子
- java常见的几种设计模式
- java中几种常见的设计模式
- JAVA几种常见的设计模式
- java中几种常见的设计模式
- 几种常见设计模式(Java)
- java之 ------ 几种常见的简单设计模式
- JAVA几种常见的设计模式
- Java中常用的几种设计模式
- Java 常见设计模式
- 几种常见设计模式区别与优缺点
- Java中几种常用的设计模式
- java几种简单的设计模式
- java设计模式学习笔记5 适配器模式几种实现方式
- java常见23种设计模式
- java几种常用设计模式简单示例
- 《你知道java中有几种设计模式吗???不妨进来瞅一眼吧》
- JAVA几种设计模式 浅谈并概括
- java基础,几种简单设计模式
- 几种常见设计模式的使用