Java常用10种设计模式详解


一、单例模式

单例模式属于创建型模式,解决某个类频繁的创建与销毁。该模式保证了其对象在JVM中只有一个实例对象存在。必须保证私有化构造函数,只能有一个实例对象存在。

优点:

  • 减少new关键字的使用,降低系统内存的使用频率,同时减轻GC工作
  • 避免了资源的多重使用

缺点:

  • 不可继承,没有接口。

1、饿汉式

  • 优点:没有加锁同步,执行效率高

  • 缺点:当类加载时就初始化,没有懒加载,浪费内存。通过classloader 机制避免了多线程的同步问题

HungrySingleton.java

public class HungrySingleton {

    private static HungrySingleton hSingleton = new HungrySingleton();

    private HungrySingleton() {}

    public static HungrySingleton getInstance() {
        return hSingleton;
    }
}

2、懒汉式

实现方式(1)
  • 优点:实现懒加载,实例化对象是在调用getInstance()

  • 缺点:没有加锁 synchronized,多线程下使用存在问题

LazySingleton.java

public class LazySingleton {
	
	private static LazySingleton instance = null;

	private LazySingleton(){}

	public static LazySingleton getInstance(){
		if(instance == null){
			instance = new LazySingleton();
		}
		return instance;	
	}
}
实现方式(2)
  • 改进:增加 synchronized 关键字,解决多线程问题

  • 不足:synchronized锁住了这个对象,每次调用getInstance()都会对对象上锁,这样大大降低了性能,事实上我们只有在第一次instance为空时才需要加锁

SyncLazySingleton.java

public class SyncLazySingleton {

    private static SyncLazySingleton instance = null;

    private SyncLazySingleton(){}

    public static synchronized SyncLazySingleton getInstance(){
        if (instance == null){
            instance = new SyncLazySingleton();
        }
        return instance;
    }
}
实现方式(3)(双重检测)
  • 该进:对instance做了判断,只有当instance为空时才对对象加锁,提升性能

  • 不足:依然存在小点问题(无序写入问题),例如:

  • 1、线程1、线程2进入getInstance()

  • 2、线程1首先进入synchronized线程同步,线程2等待线程1执行完成

  • 3、线程1判断instance为空则分配地址内存空间并实例化该类对象

  • 4、线程1执行完成退出

  • 5、线程2进入synchronized同步,此时instance已被线程1实例化,insatnce不为空,则返回线程1创建的instance实例。

  • 由于JVM无序写入问题,导致线程2有可能返回instance == null

SyncLazySingleton2.java

public class SyncLazySingleton2 {

    private static SyncLazySingleton2 instance = null;

    private SyncLazySingleton2 (){}

    public static SyncLazySingleton2 getInstance(){
        if (instance ==null){
            synchronized (SyncLazySingleton2.class){
                if (instance == null){
                    instance = new SyncLazySingleton2();
                }
            }
        }
        return instance;
    }
}

3、静态内部类

  • 优点:懒加载策略,线程安全。利用classloader加载机制实现初始化时只有一个线程,当InnerSingleton被加载时,instance不一定被初始化,应为没有调用SingleFactory没有被主动调用

  • 缺点:如果在构造函数中抛出异常,则将得不到实例

InnerSingleton .java

public class InnerSingleton {

    private static class SingleFactory{
        public static InnerSingleton instance = new InnerSingleton();
    }

    public static InnerSingleton getInstance(){
        return SingleFactory.instance;
    }

    public Object serialize(){
        return getInstance();
    }
}

3、枚举实现

枚举详情参考

  • 过关键字enum创建枚举类型在编译后生成一个继承自java.lang.Enum类的类和另外一个类,其中Enum是抽象类,编译器还为我们生成了两个静态方法,分别是values()valueOf(),values()方法的作用就是获取枚举类中的所有变量,并作为数组返回,而valueOf(String name)方法与Enum类中的valueOf方法的作用类似根据名称获取枚举变量,上述两个方法需枚举实例向上转型为Enum

  • 使用枚举单例的写法,我们完全不用考虑序列化和反射的问题。枚举序列化是由JVM保证的,每一个枚举类型和定义的枚举变量在JVM中都是唯一的,在枚举类型的序列化和反序列化上,Java做了特殊的规定:在序列化时Java仅仅是将枚举对象的name属性输出到结果中,反序列化的时候则是通过java.lang.EnumvalueOf方法来根据名字查找枚举对象。同时,编译器是不允许任何对这种序列化机制的定制的并禁用了writeObjectreadObjectreadObjectNoDatawriteReplacereadResolve等方法,从而保证了枚举实例的唯一性。

  • 优点:线程安全,支持序列化机制,实现单例模式最佳做法(少数使用)

  • 缺点:未实现懒加载

public enum EnumSingleton {
    INSTANCE;
    private String name;
    public String getName(){
        return name;
    }
    public void setName(String name){
        this.name = name;
    }
}
实现结果图

这里写图片描述


二、工厂模式

特点:

  • 提供一种创建对象的最佳方式,在创建对象时不提供对外暴露创建逻辑,并且通过一个共同的接口来指向新创建的对象

  • 定义一个创建对象的接口,让子类来决定实例化哪一个具体的工厂类,延迟到子类去执行

  • 主要解决选择接口的问题

  • 扩展性高,只增加相应工厂类即可,知道名称即可创建对象,屏蔽具体的实现,调用者只关心接口

  • 增加需求时,需要增加具体类与工厂实现,导致类个数成倍增加,增加系统复杂度

  • 只有需要生成复杂类对象时才需要使用工厂模式,且简单工厂模式不属于23种设计模式

(1)、简单工厂

PersonAction.java

public interface PersonAction {
    public void eat();
}

WomanFactory .java

public class WomanFactory implements PersonAction {
    @Override
    public void eat() {
        Log.i("msg","woman");
    }
}

ManFactory.java

public class ManFactory implements PersonAction {
    @Override
    public void eat() {
        Log.i("msg","man");
    }
}

PersonFactory 工厂类

public class PersonFactory {
    public PersonAction eat(String type){
        if("woman".equals(type)){
            return new WomanFactory();
        }else if ("man".equals(type)){
            return new ManFactory();
        }else {
            Log.i("msg","输入类型不正确");
            return null;
        }
    }
}

使用如下

public void onClick(View view){
        PersonFactory personFactory = new PersonFactory();
        PersonAction man = personFactory.eat("man");
        man.eat();
        PersonAction woman = personFactory.eat("woman");
        woman.eat();
    }
(2)、多个方法

修改PersonFactory.java如下

public class PersonFactory {

    public PersonAction manEat(){
        return new ManFactory();
    }
    
     public PersonAction womanEat(){
        return new WomanFactory();
    }
}
(3)、静态方法

修改PersonFactory.java如下

public class PersonFactory {

    public static PersonAction manEat(){
        return new ManFactory();
    }
    
     public static  PersonAction womanEat(){
        return new WomanFactory();
    }
}

直接可通过类名调用方法

1、工厂方法模式

PersonAction.java

public interface PersonAction {
    public void eat();
}

WomanEat.java

public class WomanEat implements PersonAction {
    @Override
    public void eat() {
        Log.i("msg","woman is eating");
    }
}

ManEat.java

public class ManEat implements PersonAction {
    @Override
    public void eat() {
        Log.i("msg","man is eating");
    }
}

Provider.java

public interface Provider {
    public PersonAction produce();
}

WomanFactory .java

public class WomanFactory implements Provider {
    @Override
    public PersonAction produce() {
        return new WomanEat();
    }
}

ManFactory.java

public class ManFactory implements Provider {
    @Override
    public PersonAction produce() {
        return new ManEat();
    }
}

具体使用如下:

ManFactory manFactory = new ManFactory();
PersonAction action = manFactory.produce();
action.eat();
2、抽象工厂方法模式

自己简化版

LandAnimal.java

public interface LandAnimal {
    public void run();
}

WaterAnimal .java

public interface WaterAnimal {
    public void swim();
}

Cat .java

public class Cat implements LandAnimal {
    @Override
    public void run() {
        Log.i("msg","cat is runing");
    }
}

Dog .java

public class Dog implements LandAnimal {
    @Override
    public void run() {
        Log.i("msg","dog is runing");
    }
}

Fish .java

public class Fish implements WaterAnimal {
    @Override
    public void swim() {
        Log.i("msg","Fish is swiming");
    }
}

Shark .java

public class Shark implements WaterAnimal {
    @Override
    public void swim() {
        Log.i("msg","Shark is swiming");
    }
}

AbstractFactory .java

public abstract class AbstractFactory {
    public abstract LandAnimal getDog();
    public abstract LandAnimal getCat();
    public abstract WaterAnimal getFish();
    public abstract WaterAnimal getShark();
}

AnimalFactory.java

public class AnimalFactory extends AbstractFactory {
    @Override
    public LandAnimal getDog() {
        return new Dog();
    }

    @Override
    public LandAnimal getCat() {
        return new Cat();
    }

    @Override
    public WaterAnimal getFish() {
        return new Fish();
    }

    @Override
    public WaterAnimal getShark() {
        return new Shark();
    }
}

使用方法如下:

AnimalFactory factory = new AnimalFactory();
LandAnimal cat = factory.getCat();
LandAnimal dog = factory.getDog();
WaterAnimal fish = factory.getFish();
WaterAnimal shark = factory.getShark();
cat.run();
dog.run();
fish.swim();
shark.swim();

三、建造者模式(Builder)

特点:

  • 在需要生成复杂内部结构时使用,即将多个简单的对象一步一步构建称为一个复杂对象。

构建方式(1)

新建Person.java类

public class Person {
    public int age;
    public String name;
    public String sex;
    public String address;
    public String born;

    @Override
    public String toString() {
        return "Person{" +
                "age=" + age +
                ", name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", address='" + address + '\'' +
                ", born='" + born + '\'' +
                '}';
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getBorn() {
        return born;
    }

    public void setBorn(String born) {
        this.born = born;
    }
}

新建构造(builder)类PersonBuilder .java

public class PersonBuilder {

    private Person mPerson;

    public PersonBuilder(){
        mPerson = new Person();
    }
    public PersonBuilder setAge(int age){
        mPerson.age = age;
        return this;
    }

    public PersonBuilder setName(String name){
        mPerson.name = name;
        return this;
    }

    public PersonBuilder setSex(String sex){
        mPerson.sex = sex;
        return this;
    }

    public PersonBuilder setAddress(String address){
        mPerson.address = address;
        return this;
    }

    public PersonBuilder setBorn(String born){
        mPerson.born = born;
        return this;
    }

    public Person create(){
        Log.i("msg", mPerson.toString());
        return mPerson;
    }
}

使用如下:

public void onClick(View view){
        PersonBuilder builder = new PersonBuilder();
        builder.setAge(20)
                .setName("张三")
                .setAddress("北京市")
                .setSex("男")
                .setBorn("厦门")
                .create();
        PersonBuilder builder1 = new PersonBuilder();
        builder1.setAge(22)
                .setName("李四")
                .setAddress("上海市")
                .setSex("女")
                .setBorn("福州")
                .create();
    }

看到这里是不是与构建对话框与OKHTTP3类似呢?

这里写图片描述

构建方式(2)

新建Person.java类

public class Person {
    public int age;
    public String name;
    public String sex;
    public String address;
    public String born;

    @Override
    public String toString() {
        return "Person{" +
                "age=" + age +
                ", name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", address='" + address + '\'' +
                ", born='" + born + '\'' +
                '}';
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getBorn() {
        return born;
    }

    public void setBorn(String born) {
        this.born = born;
    }
}

Ibuilder.java

public interface Ibuilder {
    void setAge(int age);
    void setName(String name);
    void setAddress(String address);
    void setBorn(String born);
    void setSex(String sex);
}

ImplBuilder.java

public class ImplBuilder implements Ibuilder {

    private Person mPerson;

    public ImplBuilder(){
        mPerson = new Person();
    }

    @Override
    public void setAge(int age) {
        mPerson.setAge(age);
    }

    @Override
    public void setName(String name) {
        mPerson.setName(name);
    }

    @Override
    public void setAddress(String address) {
        mPerson.setAddress(address);
    }

    @Override
    public void setBorn(String born) {
        mPerson.setBorn(born);
    }

    @Override
    public void setSex(String sex) {
        mPerson.setSex(sex);
    }

    public Person create(){
        Log.i("msg", mPerson.toString());
        return mPerson;
    }
}

使用如下:

ImplBuilder builder = new ImplBuilder();
builder.setAge(20);
builder.setName("王五");
builder.setAddress("南京");
builder.setBorn("武汉");
builder.setSex("男");
builder.create();

四、适配器模式

特点:

  • 适配器继承或依赖已有的对象,实现想要的目标接口

  • 消除由于接口不匹配所造成的类的兼容性问题

  • 类的适配器模式、对象的适配器模式、接口的适配器模式

  • 提高了类的复用,增加了类的透明度

(1)类的适配器模式

通过实现目标接口,继承原有类,在原有类的基础上增加接口中方法,将一个类转换成满足另一个新接口的类

Original.java

public class Original {
    public void show(){
        Log.i("msg", "This is Original");
    }
}

ExpandInterfacen .java

public interface ExpandInterfacen {
    void show();
    void hide();
}

NewAdapter .java

public class NewAdapter extends Original implements ExpandInterfacen {
    @Override
    public void hide() {
        Log.i("msg", "This is NewAdapter");
    }
}

使用如下

public void onClick(View view){
    NewAdapter adapter = new NewAdapter();
    adapter.hide();
    adapter.show();
}

这里写图片描述
(2)对象的适配器模式

不继承原有类,而是持有该类实例来实现兼容,将一个对象转换成满足另一个新接口的对象

ObjectAdapter.java

public class ObjectAdapter implements ExpandInterfacen {
    
    private Original mOriginal;

    public ObjectAdapter (){
        mOriginal = new Original();
    }

    @Override
    public void show() {
        mOriginal.show();
    }

    @Override
    public void hide() {
        Log.i("msg", "This is ObjectAdapter");
    }
}

使用如下

ObjectAdapter adapter = new ObjectAdapter();
adapter.show();
adapter.hide();

(3)接口的适配器模式

不希望实现一个接口中所有的方法,可选择一个抽象类实现接口,然后继承该抽象类实现想实现的方法即可

ExpandInterfacen.java

public interface ExpandInterfacen {
    void show();
    void hide();
    void close();
    void open();
}

AbstractInterface.java

public abstract class AbstractInterface implements ExpandInterfacen {
    
    @Override
    public void show() {
        
    }

    @Override
    public void hide() {

    }

    @Override
    public void close() {

    }

    @Override
    public void open() {

    }
}

Expand.java

public class Expand extends AbstractInterface {

    @Override
    public void show() {
        super.show();
    }

    @Override
    public void close() {
        super.close();
    }
}

五、装饰器模式

特点:装饰类持有原有类或接口的对象,并调用它的方法

  • 通过一个装饰类对现有类对象动态添加一些功能,同时不改变其结构

  • 动态添加,动态撤销

  • 继承的替代方式,继承只能静态添加

  • 多成装饰产生过多相似对象,复杂且不易排错

这两参考了两种写法

(1)一个装饰类

Person,java

public interface Person {
    void eat();
}

吃饭Petter.java

public class Petter implements Person {
    @Override
    public void eat() {
        Log.i("msg", "petter is eating");
    }
}

装饰类PetterDecorator.java,饭前洗手,饭后睡觉

public class PetterDecorator implements Person {

    Petter mPetter = null;

    public PetterDecorator(){
        mPetter = new Petter();
    }

    @Override
    public void eat() {
        wash();
        mPetter.eat();
        sleep();
    }

    public void sleep(){
        Log.i("msg", "eating after");
    }

    public void wash(){
        Log.i("msg", "eating before");
    }
}

使用如下:

Person decorator = new PetterDecorator();
decorator.eat();

运行结果

eating before
petter is eating
eating after

(2)抽象装饰,多个装饰类

Component抽象构件——Animal.java

public interface Animal {
    void sleep();
}

ConcreteComponent 具体构件——Dog.java

public class Dog implements Animal {
    @Override
    public void sleep() {
        Log.i("msg","dog is sleeping");
    }
}

ConcreteComponent 具体构件——Fish.java

public class Fish implements Animal {
    @Override
    public void sleep() {
        Log.i("msg","fish is sleeping");
    }
}

Decorator装饰角色(一般为抽象类)——AbDecoratorAnimal.java

public abstract class AbDecoratorAnimal implements Animal {

    private Animal mAnimal = null;

    public AbDecoratorAnimal(Animal animal){
        this.mAnimal = animal;
    }

    @Override
    public void sleep() {
        mAnimal.sleep();
    }
}

具体装饰角色——DogDecorator.java

public class DogDecorator extends AbDecoratorAnimal {

    public DogDecorator(Animal animal) {
        super(animal);
    }

    public void eatBone(){
        Log.i("msg","dog eats bone");
    }

    @Override
    public void sleep() {
        super.sleep();
        eatBone();
    }
}

具体装饰角色——DogDecorator2.java

public class DogDecorator2 extends AbDecoratorAnimal {

    public DogDecorator2(Animal animal) {
        super(animal);
    }

    @Override
    public void sleep() {
        super.sleep();
        run();
    }

    private void run() {
        Log.i("msg","dog is running");
    }
}

具体装饰角色——FishDecorator.java

public class FishDecorator extends AbDecoratorAnimal {

    public FishDecorator(Animal animal) {
        super(animal);
    }

    public void swim(){
        Log.i("msg","fish is swimming");
    }

    @Override
    public void sleep() {
        super.sleep();
        swim();
    }
}

使用如下:

Animal dog = new DogDecorator(new DogDecorator2(new Dog()));
dog.sleep();
Animal fish = new FishDecorator(new Fish());
fish.sleep();

运行结果:

dog is sleeping
dog is running
dog eats bone
fish is sleeping
fish is swimming

更多详细内容可参考java的 I / O

我们来看一个实际案例吧!!!更好体验装饰器模式,参考设计模式|菜鸟教程

Hero.java

public interface Hero {
    void learnSkill();
}

BlindMonk.java

public class BlindMonk implements Hero {

    public BlindMonk(String name){
        this.name = name;
    }

    public String getName() {
        return name;
    }

    private String name;

    @Override
    public void learnSkill() {
        Log.i("msg",getName());
    }
}

SkillDecorator.java

public abstract class SkillDecorator implements Hero {

    private Hero mHero = null;

    public SkillDecorator(Hero hero){
        this.mHero = hero;
    }

    @Override
    public void learnSkill() {
        mHero.learnSkill();
    }
}

Qdecoraotr.java

public class Qdecoraotr extends SkillDecorator {

    private String name;

    public Qdecoraotr(Hero hero, String name) {
        super(hero);
        this.name = name;
    }

    private void learn_Q(){
        Log.i("msg","习得技能"+name);
    }

    @Override
    public void learnSkill() {
        super.learnSkill();
        learn_Q();
    }
}

Wdecoraotr.java

public class Wdecoraotr extends SkillDecorator {

    private String name;

    public Wdecoraotr(Hero hero, String name) {
        super(hero);
        this.name = name;
    }

    private void learn_W(){
        Log.i("msg","习得技能"+name);
    }

    @Override
    public void learnSkill() {
        super.learnSkill();
        learn_W();
    }
}

Edecoraotr.java

public class Edecoraotr extends SkillDecorator {

    private String name;

    public Edecoraotr(Hero hero,String name) {
        super(hero);
        this.name = name;
    }

    private void learn_E(){
        Log.i("msg","习得技能"+name);
    }

    @Override
    public void learnSkill() {
        super.learnSkill();
        learn_E();
    }
}

Rdecoraotr.java

public class Rdecoraotr extends SkillDecorator {

    private String name;

    public Rdecoraotr(Hero hero, String name) {
        super(hero);
        this.name = name;
    }

    private void learn_R(){
        Log.i("msg","习得技能"+name);
    }

    @Override
    public void learnSkill() {
        super.learnSkill();
        learn_R();
    }
}

使用如下:

Qdecoraotr q = new Qdecoraotr(new BlindMonk("李青"),"Q");
Wdecoraotr w = new Wdecoraotr(q, "W");
Edecoraotr e = new Edecoraotr(w, "E");
Rdecoraotr r = new Rdecoraotr(e, "R");
r.learnSkill();

运行结果

李青
习得技能Q
习得技能W
习得技能E
习得技能R

六、代理模式

注意事项:
1、和适配器模式的区别:适配器模式主要改变所考虑对象的接口,而代理模式不能改变所代理类的接口。
2、和装饰器模式的区别:装饰器模式为了增强功能,而代理模式是为了加以控制。

解决问题:

  • 对象创建开销很大,或者某些操作需要安全控制,或者需要进程外的访问,直接访问会给使用者或者系统结构带来很多麻烦

  • 租客 —— 中介 —— 房东

ProxyInterface.java

public interface ProxyInterface {
    void buy();
}

Tenant.java

public class Tenant implements ProxyInterface{

    private String name;

    public Tenant(String name){
        this.name = name;
    }

    @Override
    public void buy() {
        Log.i("msg",name + " is buying");
    }
}

AgentProxy.java

public class AgentProxy implements ProxyInterface{

    private Tenant mTenant;
    private String name;

    public AgentProxy(String name){
        this.name = name;
    }

    @Override
    public void buy() {
        if(mTenant == null){
            mTenant = new Tenant(name);
        }
        mTenant.buy();
    }
}

使用如下:

 new AgentProxy("张三").buy();

七、原型模式

注意事项:
用于创建重复的对象,同时又能保证性能
通过对一个类进行实例化来构造新对象不同的是,原型模式是通过拷贝一个现有对象生成新对象的。浅拷贝实现 Cloneable,重写 clone(),深拷贝是通过实现 Serializable 读取二进制流。
浅复制:将一个对象复制后,基本数据类型的变量都会重新创建,而引用类型,指向的还是原对象所指向的。
深复制:将一个对象复制后,不论是基本数据类型还有引用类型,都是重新创建的。

浅复制

public class ShadowClone implements Cloneable {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Object clone() throws CloneNotSupportedException{
        ShadowClone clone = (ShadowClone) super.clone();
        return clone;
    }
}

深复制

public class DeepClone implements Cloneable,Serializable {

    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();
    }
}

八、备忘录模式

特点:

  • 提供了一种可以恢复状态的机制

  • 实现了信息的封装,使得用户不需要关心状态的保存细节

  • 不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态

原始数据类Original.java

public class Original {

    private String value;

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public Memo createMemo(){
        return new Memo(value);
    }

    public void restoreMemo(Memo memo){
        this.value = memo.getValue();
    }
}

备忘录类Memo.java

public class Memo {

    private String value;

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public Memo(String value) {
        this.value = value;
    }
}

保存备忘录类SaveMemo.java

public class SaveMemo {

    private Memo mMemo;

    public SaveMemo(Memo memo) {
        this.mMemo = memo;
    }

    public Memo getMemo() {
        return mMemo;
    }

    public void setMemo(Memo memo) {
        this.mMemo = memo;
    }
}

使用方式如下:

    public void onClick(View view){
        Original original = new Original();
        original.setValue("hello");
        Log.i("msg",original.getValue());
        SaveMemo saveMemo = new SaveMemo(original.createMemo());
        Log.i("msg","修改后的值:");
        original.setValue("good");
        Log.i("msg",original.getValue());
        Log.i("msg","恢复初始值:");
        original.restoreMemo(saveMemo.getMemo());
        Log.i("msg",original.getValue());
    }

运行结果

hello
修改后的值:
good
恢复初始值:
hello

九、观察者模式

特点

  • 类和类之间的关系

  • 对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新

Observer.java

public interface Observer {
    void update();
}

Observerable1.java

public class Observerable1 implements Observer {
    @Override
    public void update() {
        Log.i("msg", "Observerable1 has received");
    }
}

Observerable2.java

public class Observerable2 implements Observer {
    @Override
    public void update() {
        Log.i("msg", "Observerable2 has received");
    }
}

Subject.java

public interface Subject {
    void add(Observer observer);
    void del(Observer observer);
    void notifyAllObservers();
    void opreation();
}

AbstractSubject.java

这里写为抽象主要是为了展示扩展思路

public abstract class AbstractSubject implements Subject{

    private Vector<Observer> mVector = new Vector<>();

    @Override
    public void add(Observer observer) {
        mVector.add(observer);
    }

    @Override
    public void del(Observer observer) {
        mVector.remove(observer);
    }

    @Override
    public void notifyAllObservers() {
        Enumeration<Observer> enumeration = mVector.elements();
        while (enumeration.hasMoreElements()){
            Observer observer = enumeration.nextElement();
            observer.update();
        }
    }

    @Override
    public void opreation() {

    }
}

RealizeSubject.java

public class RealizeSubject extends AbstractSubject {

    @Override
    public void opreation() {
        Log.i("msg", "update");
        notifyAllObservers();
    }
}

使用方式如下:

  public void onClick(View view){
        Subject sub = new RealizeSubject();
        sub.add(new Observerable1());
        sub.add(new Observerable2());
        sub.opreation();
    }

实现结果

update
Observerable1 has received
Observerable2 has received

十、策略模式

特点

  • 多种算法相似的情况下,使用 if…else 所带来的复杂和难以维护

  • 在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为

  • 缺点:策略类会增多,所有策略类都需要对外暴露

Function.java

public interface Function {
    int fun(int a,int b);
}

Addiction.java

public class Addiction implements Function {

    @Override
    public int fun(int a, int b) {
        return a+b;
    }
}

Subtraction.java

public class Subtraction implements Function {
    @Override
    public int fun(int a, int b) {
        return a-b;
    }
}

Division.java

public class Division implements Function {
    @Override
    public int fun(int a, int b) {
        return a/b;
    }
}

Multiplication.java

public class Multiplication implements Function {
    @Override
    public int fun(int a, int b) {
        return a*b;
    }
}

Execute.java

public class Execute {

    private Function mFunction;

    public Execute(Function function){
        this.mFunction = function;
    }

    public int executeFunction(int a,int b){
        return mFunction.fun(a,b);
    }
}

使用如下:

  public void onClick(View view){
        Execute execute = new Execute(new Addiction());
        Log.i("msg",execute.executeFunction(5, 2)+"");
        execute = new Execute(new Division());
        Log.i("msg",execute.executeFunction(5, 2)+"");
        execute = new Execute(new Subtraction());
        Log.i("msg",execute.executeFunction(5, 2)+"");
        execute = new Execute(new Multiplication());
        Log.i("msg",execute.executeFunction(5, 2)+"");
    }

本文只阐述常用的几种设计模式,如有其它需求,见下连接

更多设计模式内容请移步:

http://www.runoob.com/design-pattern/design-pattern-tutorial.html 设计模式|菜鸟教程

https://www.cnblogs.com/geek6/p/3951677.html23种设计模式

菜鸟努力行进…

java设计模式大体上分为三大类: 创建型模式(5):工厂方法模式,抽象工厂模式单例模式,建造者模式,原型模式。 结构型模式(7):适配器模式装饰器模式,代理模式,外观模式,桥接模式,组合模式,享元模式。 行为型模式(11):策略模式、模板方法模式观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式设计模式遵循的原则有6个: 1、开闭原则(Open Close Principle)   对扩展开放,对修改关闭。 2、里氏代换原则(Liskov Substitution Principle)   只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。 3、依赖倒转原则(Dependence Inversion Principle)   这个是开闭原则的基础,对接口编程,依赖于抽象而不依赖于具体。 4、接口隔离原则(Interface Segregation Principle)   使用多个隔离的借口来降低耦合度。 5、迪米特法则(最少知道原则)(Demeter Principle)   一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。 6、合成复用原则(Composite Reuse Principle)   原则是尽量使用合成/聚合的方式,而不是使用继承。继承实际上破坏了类的封装性,超类的方法可能会被子类修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值