Java 设计模式
5种创建型模式
工厂方法模式
普通工厂模式
public Sender produce(String type){
if(“mail”.equals(type)){
return new MailSender();
}else if (“sms”.equals(type)){
return new SmsSener();
}else {
System.out.println(“请输入正确的类型!”);
return null;
}
}
多个工厂方法模式
public Sender produceMail(){
return new MailSender();
}
public Sender produceSms(){
return new SmsSender();
}
静态工厂方法模式
public static Sender produceMail(){
return new MailSender();
}
public static Sender produceSms(){
return new SmsSender();
}
抽象工厂模式
public interface Sender{
public void Send();
}
public class MailSender implements Sender{
@Override
public void Send(){
System.out.println(“this is mailsender!”)
}
}
public class SmsSender implements Sender{
@Override
public void Send(){
System.out.println(“this is mailsender!”)
}
}
工厂方法模式有一个问题就是,类的创建依赖工厂类,也就是说,想要拓展程序,必须对工厂类进行修改,这违背了闭包原则,所以,从设计角度考虑,有一定的问题,如何解决。
如果现在想添加一个功能,发及时消息,则只需要做一个实现类,实现Sender接口,同时做一个工厂类,实现Provider接口,就ok了。无需去改动现成的代码。
我的理解:就是利用java的多态来实现,使用父类的句柄,来控制子类的实现。这样的话,它可以有现象子类的实现。而且不会影响之前的代码逻辑。
单例模式
public static Singleton getInstance(){
if(instance==null){
instance= new Singleton();
}
}
线程安全
public static synchronized Singleton getInstance(){
if(instance==null){
instance=new Singleton();
}
}
public static Singleton getInstance(){
if(instance==null){
synchronzied(instance){
if(instance==null){
instance=new Singleton();
}
}
}
return instance;
}
public static class SingletonFactory{
private static Singleton instance=new Singleton();
}
反正很多,也是需要细心了解和学习的。
建造者模式
public class Builder{
private List Sender list =new ArrayList Sender();
public void produceMailSender(int count){
for (int i=0;i
原型模式
public class Prototype implements Cloneable{
public Object clone()throws CloneNotSupportedException{
Prototype proto=(Prototype)super.clone();
return proto;
}
}
浅复制:将一个对象复制后,基本数据类型的变量都会重新创建,而引用类型,指向的还是元对象所指向的。
深复制:将一个对象复制后,不论是基本数据类型还有引用类型,都是重新创建的。简单来说,就是深复制进行了完全彻底的复制,而浅复制不彻底。
要实现深复制,需要采用流的形式读入当前对象的二进制输入,再写入二进制数据对应的对象。
public class Prototype implements Cloneable, Serializable {
private static final long serialVersionUID = 1L;
private String string;
private SerializableObject obj;
/* 浅复制 */
public Object clone() throws CloneNotSupportedException {
Prototype proto = (Prototype) super.clone();
return proto;
}
/* 深复制 */
public Object deepClone() throws IOException, ClassNotFoundException {
/* 写入当前对象的二进制流 */
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
/* 读出二进制流产生的新对象 */
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return ois.readObject();
}
public String getString() {
return string;
}
public void setString(String string) {
this.string = string;
}
public SerializableObject getObj() {
return obj;
}
public void setObj(SerializableObject obj) {
this.obj = obj;
}
}
class SerializableObject implements Serializable {
private static final long serialVersionUID = 1L;
}
结构型模式
适配器模式
适配器模式将某个类的接口转换成客户端期望的另外一个接口表示,目的是消除由于接口不匹配造成的类的兼容问题。主要分为三类:类的适配器模式、对象的适配模式、接口的适配器模式。
public class Source{
public void method1(){
System.out.println("this is original method!");
}
}
public interface Targetable{
public void method1();
public void method2();
}
public class Adapter extends Source implements Targetable{
@override
public void method2(){
System.out.println("this is the targetable method!");
}
}
public class AdapterTest{
public static void main(String[] args){
Targetable target=new Adapter();
target.method1();
target.method2();
}
}
我的理解:
类的适配器
Object A extend Object B implement Object C
Object A 可以使用自己的方法和Object B中的方法
对象的适配器
其实和类的适配差不多,只不过将Object B,初始化的时候,放入Object A中。
接口的适配器
classA extend abstractB implement Interface C
classD extend abstractB implement Interface C
类的适配器模式:当希望将一个类装好成满足另外一个新接口的类时,可以使用类的适配器模式,创建一个心累,继承原有的类,实现新的接口接口.
对象的适配器模式:当希望将一个对象转换成满足量一个新接口的对象时,可以创建一个Wrapper类,持有原类的一个十里,在wrapper类的方法中,调用实例的方法就行。
接口的适配器模式:当不希望实现一个接口中所有的方法是,可以创建一个抽象类Wrapper,实现所有方法,我们写别的类的时候,继承抽象类即可。
装饰器模式
装饰器模式就是给一个对象增加一些新的而功能,而且是动态的,要求装饰对象和被装饰对象实现同一个接口,装饰对象持有被装饰对象的实例。
1.需要扩展一个类的功能。
2.动态的卫一个对象增加功能,而且还能动态撤销。
代理模式
有点像AOP
1. 修改原有的方法来适应。
2. 就是采用一个代理类调用原来的方法,且对产生的结果进行控制。这种方法就是代理模式。
外观模式
外观模式是为了解决类与类之间的依赖关系,就像Spring一样。
就是我们平时代码中,控制初始化和结束的,统一控制。
桥接模式
桥接的用意是:将抽象化与实现化解耦,使得二者可以独立变化.
组合模式
将多个对象组合在一起进行操作.
享元模式
主要目的是实现对象的共享,即共享池,当系统中对象多的时候可以减少内存的开销,通常与工厂模式一起使用。
FlyWeighFactory负责创建和管理享元单元,当一个客户端请求时,工厂需要检查当前对象池中是否有符合条件的对象,如果有,就返回已经存在的对象,如果没有,则创建一个新对象,FlyWeigh是超类。
通过连接池的管理,实现了数据库连接的共享,不需要每一次都重新创建连接,节省了数据库重新创建的开销,提高了系统的性能。
行为型模式
- 父类与子类
- 策略模式
- 模板方法模式
- 两个类之间
- 观察者模式
- 迭代子模式
- 责任链模式
- 命令模式
- 类的状态
- 备忘录模式
- 状态模式
- 通过中间类
- 访问者模式
- 中介模式
- 解释器模式
策略模式
public interface ICalculator{
public int calculate(String exp);
}
public abstract class AbstractCalculator{
public int[] split(String exp,String opt){
String array[]=exp.split(opt);
int arrayInt[]=new int[2];
arrayInt[0]=Integer.parseInt(array[0]);
arrayInt[1=Integer.parseInt(array[1]);
return arrayInt;
}
}
public class Plus extends AbstractCalculator implements ICalculator{
@Override
public int calculate(String exp){
int arrayInt[]=split(exp,"\\+");
return arrayInt[0]+arrayInt[1];
}
}
public class Minus extends AbstractCalculator implements ICalculator{
@Override
public int calculate(String exp){
int arrayInt[]=split(exp,"-");
return arrayInt[0]-arrayInt[1];
}
}
public class Multiply extends AbstractCalculator implements ICalculator{
@Override
public int calculate(String exp){
int arrayInt[]=split(exp,"\\*");
return arrayInt[0]*
}
}
public class StrategyTest{
public static void main(String[]args){
String exp="2+8";
ICalculator cal=new Plus();
int result=cal.calculate(exp);
System.out.println(result);
}
}
策略模式的决定权在用户,系统本身提供不同算法的实现,新增或者删除算法,对各种算法做封装。因此,策略模式多用在算法决策系统中,外部用户只需要决定用哪个算法即可。
模板方法模式
一个抽象类中,有一个主方法,再定义1..n个方法,可以是抽象的,也可以是实际的方法,定义一个类,继承该抽象,重写抽象方法,通过调用抽象类,实现对子类的调用。
public abstract class AbstactCalculator{
public final int calculate(String exp,String opt){
int array[]=split(exp,opt);
return calculate(array[0],array[1]);
}
}
abstract public int calculate(int num1,int num2);
public int[] split(String exp,String opt){
String array[]=exp.split(opt);
int arrayInt[]=new int[2];
arrayInt[0]=Integer.parseInt(array[0]);
arrayInt[1]=Integer.paresInt(array[1]);
return arrayInt;
}
public class Plus extends AbstactCalculator{
@Override
public int calculate(int num1,int num2){
return num1+num2;
}
}
public class StrategyTest{
public static void main(String[] args){
String exp="8+8";
AbstractCalculator cal=new Plus();
int result=cal.calculate(exp,"\\+");
System.out.println(result);
}
}
感觉开始有难度了,主要是抽象类中的抽象方法,但是在抽象类中定义了一些基本算法,然后由子类继承抽象方法,在完成实现的方法。
观察者模式
观察者模式很好理解,当你订阅了该文章,如果后续有更新,当我们浏览一些博客或wiki时,经常会看到RSS图标,当你一个对象辩护是,其它依赖该对象都会受到通知,并且随着变化~对象之间是一种一对多的关系。
public interface Observer{
public void update();
}
public class Observer1 implemnts Observer{
@Override
public void update(){
System.out.println("observer1 has received!")
}
}
public class Observer2 implements Observer{
@Override
public void update(){
System.out.println("observer2 has received!")
}
}
public interface Subject{
public void add(Observer observer);
public void del(Observer observer);
public void notifiyObservers();
public void operation();
}
public abstract class AbstractSubject implements Subject{
private Vector<Observer> vector=new Vector<Observer>();
@Override
public void add(Observer observer){
vector.add(observer);
}
@Override
public void del(Observer observer){
vector.remove(observer);
}
@Override
public void notifyObservers(){
Enumeration<Observer> enumo=vector.elements();
while(enumo.hasMoreElements()){
enumo.nextElement().update();
}
}
}
public class MySubject extends AbstractSubject{
@Override
public void operation(){
System.out.println("update self!");
notifyObservers();
}
}
public class ObserverTest{
public static void main(String[]args){
Subject sub=new MySubject();
sub.add(new Observer1());
sub.add(new Observer2());
sub.operation();
}
}
迭代子模式
这个思路和我们常见的一模一样,MyCollection中定义了集合的一些操作,MyIterator中定义了一系列迭代操作,且持有Collection实例。
责任链模式
有多个对象,每个对象持有对下一个对象的引用,这样就会形成一条链,请求在这条链上传递,直到某一对象决定处理该请求。但是发出者冰不清楚到底最终那个对象会处理该请求,所以,责任链模式可以实现,在隐藏客户端的情况下,对系统进行动态的调整。
命令模式
命令模式很好理解,命令模式的目的就是达到命令的发出者和执行者之间解耦,实现请求和执行分开,熟悉strusts的同学应该知道,Struts其实就是一种将请求和呈现分离的技术,其中必然涉及命令模式的思路。
备忘录模式
主要目的是保存一个对象的某个状态,以便在适当的时候恢复对象,个人觉得叫备份模式。假设有原始类A,A中有各种属性,A可以决定需要备份的属性,备忘录类B是用来存储A的一些内部状态,类C呢,就是一个用来存储备忘录的,不能修改等操作。
我的理解: 就是新建一个类去存储旧类的值,我觉得这种设计意义不是太大,或者说我不知道这个运用场景。
状态模式(State)
当对象的状态改变是,同时改变其行为,很好理解!就拿qq来说,有几种状态,在线、隐身、忙碌等。
1. 可以通过改变状态来获得不同的行为
2. 你的好友能同时看到你的变化
我的理解 就是在触发操作的时候,我们需要在后面的操作添加一些变量的操作,用来更新其它的操作。
访问者模式(Vistor)
访问模式把数据结构和作用于结构上的操作解耦合,使得操作集合可相对自由地演化。访问者模式适用于数据结构相对稳定算法又易变化的系统。因为访问者模式使得算法操作增加变得容易。若系统数据结构对象易于变化,经常有新的数据对象增加进来,则不适合适用访问者模式。访问者模式的优点是增加操作很容易,因为增加操作意味着增加新的访问者。访问者模式将有关行为几种到一个访问者对象中,其改变不影响系统数据结构。
简单来说,访问者模式就是一种分离对象数据结构与行为的方法,通过这种分离,可达到为一个被访问者动态增加新的操作而无需做其它的修改的效果。
中介者模式
我的理解就是对象归对象,行为归行为。将行为剥离出来,这样就避免两个对象的相互引用,也避免了耦合度高的问题。
解释器模式(Interpreter)
一般主要应用于oop开发中的编辑器的开发中,所以适用面比较窄。
我的理解就是为了解释说明来用的。