程序设计最终将归结为"算法"和"设计模式",其中设计模式是我们进行良好程序设计的思想和"纲要";接下来本人将以通俗的实例来展示几种常用的设计模式,以及它们在java程序设计中需要注意的问题.
在此需要提醒一下,很多设计模式,只是思想上有稍微的区别,但是在程序设计(模板)中这种区别可能无法显著的表达出来,对于一个"靠天吃饭"的码农,我们了解它们的思想就已经足够了.
一.Singleton(单例模式):
单例模式,是一个神奇的模式,从狭隘的角度考虑,这种模式的实现,极度依赖于程序运行"容器"以及实例的生命周期,简单的归纳为:在指定"运行环境"中,任何时刻只能有一个实例存在.在java层面,单例和Classloader有必然关联关系,严格意义上说,一个classloader只能有一个单例的实例.
java序列化和反序列化、反射机制将有可能"打破"单例的设计,需要注意.
public class SingleTon implements Serializable{ private static final long serialVersionUID = 768457893059530646L; /** * 私有构造器,将可以避免通过"new Object()"方式创建对象 */ private SingleTon(){ //检测instance是否已经初始化 //避免反射机制,导致的多例问题,通过反射机制仍然可以对私有构造函数进行操作 //---------------反射机制打破单例--- //Constructor[] constructors = SingleTon.class.getDeclaredConstructors(); //Constructor<SingleTon> c = constructors[0]; //c.setAccessible(true); //SingleTon s2 = c.newInstance(null); //----------------------------------- if(instance != null){ return; } } private static final SingleTon instance = new SingleTon(); public static SingleTon getInstance(){ return instance; } private void readObject(java.io.ObjectInputStream in) throws IOException{ //与writeObject对应,根据writeObject中write的顺序,进行read //你可以决定,是否在此方法中,进行重置instance的属性值. //this.age = in.readInt(); } private void writeObject(ObjectOutputStream out) throws IOException{ //out.writeInt(this.age); } /** * 严格单例,确保remote instance不会干扰单例模式,避免在反序列化过程中对单例的影响. * @return * @throws ObjectStreamException */ public Object readResolve() throws ObjectStreamException{ return instance; } }
二.Factory(工厂模式):
工厂模式,根据其实施手段的不同,分为"抽象工厂""静态工厂"等等,这些变种也是"万变不离其宗";工厂模式的精髓在于,让对象的创建过程和对象的消费者分离,生成的对象具有的特性与其交付给工厂方法的API参与而定..你可以把工厂模式,想象成现实生活中的工厂,你提交给工厂的订单参数,直接决定工厂为你生成的商品特性;再者,工厂就是为生产商品而生.
工厂模式,在我们的日常开发中,经常被使用到,或许这种模式已经被你踩在脚下,你却不能看清它的面目.
public class ConnectionFactory { private String hostname; private int port; private List<Connection> pool = new LinkedList<Connection>(); private int corePoolSize; private static final int DEFAULT_SIZE = 8; public ConnectionFactory(String hostname,int port){ this(hostname,port,DEFAULT_SIZE); } public ConnectionFactory(String hostname,int port,int corePoolSize){ this.hostname = hostname; this.port = port; if(corePoolSize > 0){ this.corePoolSize = corePoolSize; } } public synchronized Connection createConnection(){ if(pool.isEmpty()){ return new Connection(hostname, port); } return pool.remove(0); } /** * static factory method */ public static Connection createConnection(String hostname,int port){ return new Connection(hostname, port); } public void returnSource(Connection connection){ if(pool.size() > corePoolSize){ return; } pool.add(0, connection); } static class Connection{ private String hostname; private int port; private Socket socket; private boolean init; public Connection(String hostname,int port){ this.hostname = hostname; this.port = port; } public synchronized void connect() throws IOException{ if(init){ return; } socket = new Socket(hostname,port); init = true; } public byte[] read(){return null;} public void write(byte[] bytes){} } }
三.Builder(构建模式):
构建模式:如果创建一个对象需要多个环节,只有按照一定的"步骤"才能正确创建一个对象实例,那么这个过程就是构建.对此过程的封装,就是"构建模式".不过我怎么感觉“StringBuilder”是构建模式的体现呢?!
/** * 构建一个sql语句 */ public class QueryBuilder { private Query query; /** * build模式,意味着一个"起始点"和"结束点" * build过程起始点 * @param tableName */ private QueryBuilder(String tableName){ this.query = new Query(tableName); } public static QueryBuilder from(String tableName){ return new QueryBuilder(tableName); } /** * 过程 * @param orderType * @return */ public QueryBuilder order(String orderType){ query.setOrderType(orderType); return this; } /** * 过程 * @param key * @param value * @return */ public QueryBuilder addParam(String key,String value){ query.getParams().put(key, value); return this; } /** * "结束点",获得"构建"的结果 * @return */ public String build(){ StringBuilder sb = new StringBuilder(); sb.append("select * from "); sb.append(query.getTableName()); Map<String,String> params = query.getParams(); for(Entry<String,String> entry : params.entrySet()){ sb.append(" "); sb.append(entry.getKey()); sb.append("="); sb.append(entry.getValue()); } return sb.toString(); } private class Query{ private String orderType; private Map<String, String> params; private String tableName; public Query(String tableName){ this.tableName = tableName; } public String getOrderType() { return orderType; } public void setOrderType(String orderType) { this.orderType = orderType; } public String getTableName() { return tableName; } public void setTableName(String tableName) { this.tableName = tableName; } public Map<String, String> getParams() { return params; } } public static void main(String[] args){ QueryBuilder builder = QueryBuilder.from("user"); builder.order("desc") .addParam("name", "zhangsan") .addParam("status", "1"); String statement = builder.build(); } }
四.Observer(观察者模式):
当一个对象的某个操作,会对其他对象带来"关联性"影响时,如果被影响者能够"获得通知",那么这种模式就为"观察者模式".在java中,已经提供了"观察者"模式的API,我们看看改如何使用它们.
观察者模式中需要"观察者"和"被观察者"2个角色.
public class ObserverSample { static class TestObserable extends Observable{ private String name; public TestObserable(){ super(); } public TestObserable(String name){ super(); this.name = name; } public void update(String data){ //.. super.setChanged(); super.notifyObservers(data);//通知 super.clearChanged(); } @Override public String toString(){ return this.name == null ? super.toString() : this.name; } } /** * 观察者 * */ static class TestObserver implements Observer{ private String name; public TestObserver(String name){ this.name = name; } @Override public void update(Observable o, Object arg) { System.out.println(name + " find " + o.toString() + " changed"); System.out.println("changed data:" + arg.toString()); } } public static void main(String[] args){ TestObserver t1 = new TestObserver("t1"); TestObserver t2 = new TestObserver("t2"); TestObserable obserable = new TestObserable("observer"); //顺序很重要 obserable.addObserver(t1); obserable.addObserver(t2); obserable.update("update-test"); } }
五.Chain(责任链模式)
chain,就是链,代码写起来也像"链条":如果一个"操作"需要被多个"处理器(processor)"依次顺序执行时,那么"责任链"模式,将会是最好的选择.不过,貌似 servlet中Filter是不是一种“责任链”的体现?!
public class PrinterSample { private Printer printer; public PrinterSample(Printer printer){ this.printer = printer; } public void printer(String data){ printer.execute(data); } static interface Printer { public void execute(String data); } static abstract class AbstractPrinter implements Printer{ protected Printer nextPrinter; protected AbstractPrinter(Printer next){ this.nextPrinter = next; } } static class LengthPrinter extends AbstractPrinter{ protected LengthPrinter(Printer next) { super(next); } @Override public void execute(String data) { System.out.println("length:" + data.length()); if(nextPrinter != null){ this.nextPrinter.execute(data); } } } static class HashcodePrinter extends AbstractPrinter{ protected HashcodePrinter(Printer next) { super(next); // TODO Auto-generated constructor stub } @Override public void execute(String data) { System.out.println("Hashcode:" + data.hashCode()); if(nextPrinter != null){ nextPrinter.execute(data); } } } static class ChecksumPrinter extends AbstractPrinter{ private static final Charset charset = Charset.forName("utf-8"); protected ChecksumPrinter(Printer next) { super(next); } @Override public void execute(String data) { Adler32 checksum = new Adler32(); checksum.update(data.getBytes(charset)); System.out.println("Checksum:" + checksum.getValue()); if(nextPrinter != null){ nextPrinter.execute(data); } } } public static void main(String[] args){ //build chain: ChecksumPrinter csp = new ChecksumPrinter(null); HashcodePrinter hp = new HashcodePrinter(csp); LengthPrinter lp = new LengthPrinter(hp); // PrinterSample sample = new PrinterSample(lp); sample.printer("This is chain-model sample!"); } }
六.Strategy(策略模式):
针对输入的数据,而采取相应的“算法”输出结果的方式。如下例子为,根据输入的key而输出相应的hash模的值。
public class HashStrategy { public static long hashMode(Object key,int mod){ if(key == null){ throw new NullPointerException("key cant be null!"); } if(key instanceof Number){ return NumberHashcode.hashcode(key) % mod; }else{ return ObjectHashcode.hashcode(key) % mod; } } static class NumberHashcode{ public static long hashcode(Object key) { return ((Number)key).longValue(); } } static class ObjectHashcode{ public static long hashcode(Object key) { return key.toString().hashCode() & 0x7FFFFFFF; } } public static void main(String[] args){ System.out.println(HashStrategy.hashMode("test hashStrategy", 3)); System.out.println(HashStrategy.hashMode(12312412L, 3)); } }
七.Proxy(代理模式):
代理模式,避免对实例方法的直接访问,而是使用代理对象来间接的去访问,这样一面可以在“实际调用”之前或者之后做一些补充性操作(比如参数变更,权限检测),另一面代理对象可以屏蔽掉实际实例的部分操作(让一些方法不可用)等。
public class ProxySample { static interface Printer{ public void print(String value); } static class TimestampPrinter implements Printer{ @Override public void print(String value) { System.out.println("Value:" + value); System.out.println("Timestamp:" + System.currentTimeMillis()); } } /** * 静态代理类,通常和“被代理者”有着相同的接口列表,通常子类通过扩展接口的方式实现 * */ static class StaticProxy implements Printer { //must "new Object" private Printer printer = new TimestampPrinter(); public void print(String value){ System.out.println("Static proxy: before invoke..."); printer.print(value); System.out.println("Static proxy: after invoke..."); } } static class DynamicProxy{ private Printer printer = new TimestampPrinter();//被代理者 private Printer proxy;//代理者 public DynamicProxy(){ proxy = (Printer)Proxy.newProxyInstance(DynamicProxy.class.getClassLoader(), new Class[]{Printer.class}, new Invocation(printer)); } public void print(String value) { proxy.print(value); } } static class Invocation implements InvocationHandler{ private Object obj;//被代理实例 public Invocation(Object obj){ this.obj = obj; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("Dynamic proxy: before invoke"); Object result = method.invoke(obj, args); System.out.println("Dynamic proxy: after invoke"); return result; } } /** * @param args */ public static void main(String[] args) { DynamicProxy dproxy = new DynamicProxy(); dproxy.print("I am dynamic..."); StaticProxy sproxy = new StaticProxy(); sproxy.print("I am static..."); } }
---先到此结束..
相关推荐
JAVA常用设计模式JAVA常用设计模式JAVA常用设计模式JAVA常用设计模式JAVA常用设计模式JAVA常用设计模式JAVA常用设计模式JAVA常用设计模式JAVA常用设计模式JAVA常用设计模式
以下是对Java中常用设计模式的详细解释: 1. **单例模式**:单例模式确保一个类只有一个实例,并提供一个全局访问点。这种模式常用于配置管理、线程池或者数据库连接池等场景。实现方式有懒汉式(线程不安全)、...
以下是关于标题和描述中提到的Java常用设计模式的详细解释: 1. **单例模式**:确保一个类只有一个实例,并提供一个全局访问点。在Java中,通常通过私有构造器和静态工厂方法实现。双检锁(Double-Check Locking)...
java常用的设计模式一个简单总结,如工厂模式、单例模式、代理模式等等。(楼主也是未入门的菜鸟,如有错误请及时联系楼主更正,谢谢!)
总体来说设计模式分为三大类: 创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。 结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元...
该文件里面包含JAVA开发常用的设计模式,通过举例、分析、代码示意的方式让读者很容易理解
### 常用设计模式及Java程序设计 #### 设计模式概述 设计模式是一种软件设计领域中的通用解决方案,用于描述解决常见设计问题的最佳实践。它不仅有助于提高代码的复用性和可读性,还能增强软件架构的灵活性和扩展...
本资料包聚焦于“JAVA程序常用设计模式”,旨在帮助中高级JAVA程序员进一步提升编程能力。 1. 单例模式:确保一个类只有一个实例,并提供一个全局访问点。在Java中,单例模式通常通过双重检查锁定、静态内部类或...
在Java中,设计模式尤其重要,因为它们可以帮助我们编写出更灵活、可维护和易于扩展的代码。以下是对给定文件中提到的几种设计模式的详细解释: 1. **简单工厂模式(Simple Factory)**: - 简单工厂模式是一种...
java 常用设计模式 ppt格式 分类 创建模式 结构模式 行为模式 优点 面向界面编程 降低耦合性 增加灵活性
五种常用的Java设计模式 Java设计模式是软件开发中的一种重要概念,主要用来解决软件设计中的一些问题。下面将总结五种常用的Java设计模式,分别是单例模式、工厂模式、建造模式、_observer模式和迭代器模式。 ...
以JAVA为例,汇总了十几种常用的设计模式,包括了:单例模式、工厂模式、建造者模式、适配器模式、装饰器模式、外观模式、命令模式、观察者模式、状态模式、策略模式、模板方法模式等。仅供学习使用。 相关文章请看...
Java设计模式是面向对象编程...在阅读《Chapter1___Java常用设计模式(SingleTon、FactoryMethod、AbstractFactory)》的相关资料时,你可以更深入地学习这些模式的细节,包括适用场景、优缺点以及如何在实际项目中实现。
设计模式是软件工程中经过长期实践总结出的通用解决方案,它们描述了在特定情况下如何解决...通过阅读和学习提供的"常用设计模式java实现"压缩包中的例子,可以更好地理解和实践这些设计模式,从而提升Java编程技能。
在Java编程中,运用合适的设计模式可以提高代码的可维护性、可扩展性和可复用性。以下是关于Java版本设计模式实现demo的一些补充说明: 1. 设计模式分类 设计模式通常分为三大类:创建型模式、结构型模式和行为型模式...
-------------------------------java几种常用的设计模式--------------------------------------------------------------------------------------------------------------------------
### Java设计模式详解 #### 一、引言 ...本文介绍了几种常用的设计模式,包括J2EE设计模式和软件开发设计模式,并详细探讨了它们的应用场景。希望这些知识能够帮助你在开发过程中更加高效地解决问题。