设计模式

1. 设计模式概述

设计模式是前人开发过程中总结出来的一套设计经验。这种经验经过软件工程验证后得到广泛认可,能够解决软件开发过程中遇到的问题,在软件工程中应用广泛。

设计模式可以提高代码可复用性、可维护性、可扩展性,正是基于上述优点,很多优秀开源框架、代码内核均使用设计模式,设计模式在软件工程化中使用越来越广泛。

2. 常用的设计模式

设计模式种类很多,通常讲的设计有23种,在这23中设计模式中,更常见的设计模式包含单例模式、简单工厂模式、工厂模式、代理模式、观察者模式等。下面主要对上述5中设计模式做一个详细阐述。

2.1    单例模式

所谓单例,即指某个类在程序运行期间只有单个实例。单例模式会阻止其他对象实例化自己的单例对象的副本,从而确保所有对象都访问唯一实例。

单例模式常见的实现方法有恶汉式、懒汉时、线程安全方式、DCL(Double Check Lock)方式,本文讲的单例模式通过枚举类实现,如下所示:

SingleInstance.java

package com.singleinstance;

public enum SingleInstance {

    INSTANCE;
    
    private int count = 0;
    
    public int getCount(){
        return count;
    }
    public void setCount(int count){
        this.count = count;
    }
}

Main.java

package com.singleinstance;

public class Main {
    public static void main(String[] args) {
        SingleInstance singleInstance = SingleInstance.INSTANCE;
        singleInstance.setCount(999);
        System.out.println(singleInstance.getCount());
    }
}

程序输出:

999

枚举类型天然具有单例的属性,因为枚举类在编译后就是一个final类,私有的构造函数,下面是SingleInstance.java类编译后的字节码,注意继承关系:

Compiled from "SingleInstance.java"
public final class com.singleinstance.SingleInstance 
				extends java.lang.Enum<com.singleinstance.SingleInstance> {
  public static final com.singleinstance.SingleInstance INSTANCE;

  public static com.singleinstance.SingleInstance[] values();
    Code:
       0: getstatic     #1                  // Field $VALUES:[Lcom/singleinstance/SingleInstance;
       3: invokevirtual #2                  // Method "[Lcom/singleinstance/SingleInstance;".clone:()Ljava/lang/Object;
       6: checkcast     #3                  // class "[Lcom/singleinstance/SingleInstance;"
       9: areturn       

  public static com.singleinstance.SingleInstance valueOf(java.lang.String);
2.2 简单工厂模式

简单工厂模式可以根据输入条件不同而返回不同属性的产品,灵活切换,简化外部调用方法。

Product.java

package com.simplefactory;

public interface Product {
    public static void product();
}

ProductA.java

package com.simplefactory;

public class ProductA implements Product {
    public void product(){
        System.out.println("ProductA");
    }
}

ProductB.java

package com.simplefactory;

public class ProductB implements Product {
    public void product(){
        System.out.println("ProductB");
    }
}

Factory.java

package com.simplefactory;

public class Factory {
    public Product getProduct(int id){
        switch (id){
            case 0:
                return new ProductA();
            case 1:
                return new ProductB();
            default:
                return null;
        }
    }
}

Main.java

package com.simplefactory;

public class Main {
    public static void main(String[] args) {
        ProductA productA = new ProductA();
        ProductB productB = new ProductB();
        Factory factory = new Factory();
        factory.getProduct(0).product();
        factory.getProduct(1).product();
    }
}

程序输出:

ProductA
ProductB
2.3   工厂模式

Product.java

package com.factory;

public interface Product {
    public void product();
}

ProductA.java

package com.factory;

public class ProductA implements Product {
    public void product(){
        System.out.println("ProductA");
    }
}

ProductB.java

package com.factory;

public class ProductB implements Product {
    public void product(){
        System.out.println("ProductB");
    }
}

AbstractFactory.java

package com.factory;

public interface AbstractFactory {
	public Product getProduct();
}

FactoryM.java

package com.factory;

public class FactoryM implements AbstractFactory{
	public Product getProduct(){
		return new ProductA();
	}
}

FactoryN.java

package com.factory;

public class FactoryN implements AbstractFactory{
	public Product getProduct(){
		return new ProductB();
	}
}

Main.java

package com.factory;

public class Main {
    public static void main(String[] args){
        FactoryM factoryM = new FactoryM();
        FactoryN factoryN = new FactoryN();
        factoryM.getProduct().product();
        factoryN.getProduct().product();
    }
}

程序输出为:

ProductA
ProductB

简单工厂模式与工厂模式的区别:

简单工厂模式不符合开闭原则,工厂模式符合开闭原则。

2.4    代理模式

Contract.java

public interface Contract {
    public void test0();
    public void test1();
    public void test2();
}

Source.java

public class Source implements Contract {
    public void test0(){
        System.out.println("test0");
    }
    public void test1(){
        System.out.println("test1");
    }
    public void test2(){
        System.out.println("test2");
    }
}

Proxy.java

public class Proxy {
    Contract contract;
    public Proxy(Contract contract){
        this.contract = contract;
    }
    public void test0(){
        contract.test0();
    }
    public void test1(){
        contract.test1();
    }
    public void test2(){
        contract.test2();
    }
}

Main.java

public class Main {
    public static void main(String[] args){
        Source source = new Source();
        Proxy proxy = new Proxy(source);
        proxy.test0();
        proxy.test1();
        proxy.test2();
    }
}

程序输出:

test0
test1
test2

注意,Proxy类实现代理test方法功能时采用了一个小技巧,通过构造函数注入Source基类,而不是直接通过Proxy与Source类的组合实现test代理,这样可以除去Proxy与Source类强耦合关系。

2.5    观察者模式

观察模式使用很广泛,主要一个目标变化时,快速通知这个目标的观察者,观察者可能存在多个。

观察者模式最常见的一个应用就是Android平台的按钮响应,系统就是通过观察模式实现对按键的监听。

AbstractTarget.java

public interface AbstractTarget {
    public void addObserver(Observer obj);
    public void removeObserver(Observer obj);
    public void notisfyAll(String info);
}

Target.java

import java.util.List;
import java.util.ArrayList;

public class Target implements AbstractTarget {
    List<Observer> list = new ArrayList<>();
    public void addObserver(Observer obj){
        list.add(obj);
    }
    public void removeObserver(Observer obj){
        list.remove(obj);
    }
    public void notisfyAll(String info){
        for (Observer obj : list){
            obj.update(info);
        }
    }
}

Observer.java

public interface Observer {
    public void update(String info);
}

FinalObserver.java

public class FinalObserver implements Observer {
    String s;
    public FinalObserver(String s){
        this.s = s;
    }
    public void update(String info){
        System.out.println(s + " " + info);
    }
}

Main.java

public class Main{
    public static void main(String[] args){
        Target target = new Target();
        FinalObserver observer0 = new FinalObserver("Observer0");
        FinalObserver observer1 = new FinalObserver("Observer1");
        FinalObserver observer2 = new FinalObserver("Observer2");
        FinalObserver observer3 = new FinalObserver("Observer3");
        target.addObserver(observer0);
        target.addObserver(observer1);
        target.addObserver(observer2);
        target.addObserver(observer3);
        target.notisfyAll("update");
        System.out.println();
        target.removeObserver(observer2);
        target.notisfyAll("update");
    }
}

程序输出为:

Observer0 update
Observer1 update
Observer2 update
Observer3 update

Observer0 update
Observer1 update
Observer3 update

3 总结

设计模式是一种设计经验,是一种代码设计指导思想,有助于代码工程化,但是过犹不及,过度使用设计模式,会使得代码变得臃肿,会给深入研究代码具体实现的阅读者带来一定的困难。因此,具体设计时,可依据场景及需要,适度引入设计模式。



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值