Java设计模式

写在前面:
本文参考:http://c.biancheng.net/design_pattern/
本文用于交流学习。

简介

类间关系

依赖

耦合度最弱。
使用类调用依赖类的对象。
如:使用类A(人)------>被依赖的类B(手机)

关联

  • 一般关联关系
    关联可以是双向的,也可以是单向的。
    使用类将被关联类的对象做为成员变量。
    ——或使用类——>被关联的类
    如老师和学生。
  • 聚合关系
    强关联关系。整体和部分的关系。has-a。
    整体类将部分类的对象做为成员变量。成员变量可以独立存在。
    如学校和老师。
    整体◊——部分
  • 组合关系
    更强烈的聚合关系。contains-a。
    整体对象可以控制部分对象的生命周期,一旦整体对象不存在,部分对象也将不存在,部分对象不能脱离整体对象而存在。
    如人和眼睛。
    整体◆——部分

泛化(继承)

is-a。
父类◁——子类。

实现(接口)

接口◁------实现类

面向对象设计原则

开闭原则(open closed principle,OCP)

对扩展开放,对修改关闭。
对象:软件实体----项目中的模块、类与接口、方法。

里氏替换原则(Liskov substitution principle,LSP)

继承必须确保超类(父类)所有性质在子类中仍然成立。
作用:继承的一个标准。实现开闭原则的一种方式。

依赖倒置原则(dependence inversion principle,DIP)

高层模块不应依赖于低层模块,两者都应该依赖抽象;抽象不应该依赖于细节,细节应该依赖于抽象。
核心思想:面向接口编程,不要面向实现编程。
作用:降低类间耦合。实现开闭原则的一种重要方式。

单一职责原则(single responsibility principle,SRP)

一个类应该有且仅有一个引起它变化的原因,否则类应被拆分。

接口隔离原则(interface segregation principle,ISP)

一个类对另一个类的依赖应该建立在最小的接口上,客户端不应该被迫依赖它不使用的方法。

迪米特法则/最少知识原则(law of Demeter,LoD/least knowledge principle,LKP)

只与你的直接朋友交谈,不跟陌生人说话。
直接朋友:当前对象本身,当前对象的成员对象,当前对象所创建的对象,当前对象的方法参数等。

合成复用原则(composite reuse principle,CRP)

软件复用时,尽量先使用组合或聚合等关联关系实现,其次才考虑继承关系来实现。

设计模式

在这里插入图片描述

1.单例模式(Singleton)

一个类只有一个实例,由类自行创建。

懒汉式:只在第一次使用时创建实例对象,需要使用volatile,synchronized保证线程安全(每次访问要同步),会消耗更多资源。

public class Singleton {
    private static volatile Singleton instance = null;
    private LazySingleton() {}
    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

饿汉式:提前创建好实例对象,线程安全。

public class Singleton {
    private static final Singleton instance = new HungrySingleton();
    private Singleton() {}
    public static Singleton getInstance() {
        return instance;
    }
}

2.原型模式(Prototype)

用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象。原型实例指定了要创建的对象的种类。

抽象原型类:规定了具体原型对象必须实现的接口。
具体原型类:实现抽象原型类的 clone() 方法,它是可被复制的对象。
访问类:使用具体原型类中的 clone() 方法来复制新的对象。

浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址。

//Java 的 Object 类 clone() 方法
//具体原型类只要实现 Cloneable 接口就可实现对象的浅克隆
class Prototype implements Cloneable {
	String proporty="";
    Prototype() {
        System.out.println("Prototype");
    }
    public Object clone() throws CloneNotSupportedException {
        System.out.println("Prototype copy");
        return (Prototype) super.clone();
    }
}

public class PrototypeTest {
    public static void main(String[] args) throws CloneNotSupportedException {
        Prototype obj1 = new Prototype ();
        Prototype obj2 = (Prototype) obj1.clone();
        System.out.println(bj1 == obj2);  //false
        System.out.println(obj1.proporty == obj2.proporty);  //true
    }
}

深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。

3.工厂模式

定义一个创建产品对象的工厂接口,将产品对象的实际创建工作交给具体工厂类。

如客户想要吃早餐。

  • 对于简单工厂,早餐店售卖的早餐类型有限,客户在早餐店挑选一种早餐,早餐店创建一个早餐给客户。当客户想要新的早餐,早餐点就需要在售卖类型里添加新的类型。
  • 对于工厂方法模式,售卖的早餐类型有限,客户在早餐店挑选一种早餐,由早餐店下面对应的部门生产。当客户想要吃新的早餐,就增加一个新的部门。这个部门只生产这种早餐(如牛奶由牛奶部门生产)。
  • 对于抽象工厂模式,售卖的早餐类型有限,客户在早餐店挑选一种早餐,由早餐店下面该早餐类型所属的部门生产。当客户想要吃新的早餐类型,就增加一个新的部门。这个部门生产一类早餐(如牛奶由饮品部门生产,饮品部门还生产果汁等)。

简单工厂模式(Simple Factory Pattern)

创建实例的方法通常为静态方法,因此简单工厂模式又叫作静态工厂方法模式(Static Factory Method Pattern)。

角色:简单工厂,抽象产品,具体产品。

public interface Breakfast {
	void sale();
}

public class Breakfast1 implements Breakfast {
	public static final int id=1;
	@Override
	public void sale() {
		// TODO Auto-generated method stub
		System.out.println("Breakfast1");		
	}
}

public class Breakfast2 implements Breakfast {
	public static final int id=2;
	@Override
	public void sale() {
		// TODO Auto-generated method stub
		System.out.println("Breakfast2");
	}
}

public class SimpleFactory {  //早餐店
	public static Breakfast makeBreakfast(int id) {
		switch(id) {
		case 1: return new Breakfast1(); 
		case 2: return new Breakfast2(); 
		} 
		return null;
	}
}

public class Client {  //客户
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Breakfast bf1=SimpleFactory.makeBreakfast(Breakfast1.id);
		Breakfast bf2=SimpleFactory.makeBreakfast(Breakfast2.id);
		bf1.sale();
		bf2.sale();
	}
}

工厂方法模式

角色:抽象工厂,具体工厂,抽象产品(1个),具体产品。

// Breakfast接口及其实现类同上

public interface AbstractFactory {
	Breakfast makeBreakfast();
}

public class Breakfast1Factory implements AbstractFactory {
	@Override
	public Breakfast makeBreakfast() {
		// TODO Auto-generated method stub
		return new Breakfast1();
	}
}

public class Breakfast2Factory implements AbstractFactory {
	@Override
	public Breakfast makeBreakfast() {
		// TODO Auto-generated method stub
		return new Breakfast2();
	}
}

public class Client {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Breakfast bf1=new Breakfast1Factory().makeBreakfast();
		Breakfast bf2=new Breakfast2Factory().makeBreakfast();
		bf1.sale();
		bf2.sale();
	}
}

抽象工厂模式

角色:抽象工厂,具体工厂,抽象产品(多个),具体产品。

public interface Drink{
	void sale();
}

public interface Bread {
	void sale();
}

public class Milk implements Drink {
	@Override
	public void sale() {
		// TODO Auto-generated method stub
		System.out.println("Milk ");
	}
}

public class SweetBread implements Bread {
	@Override
	public void sale() {
		// TODO Auto-generated method stub
		System.out.println("SweetBread ");
	}
}

public interface AbstractFactory {
	Drink makeBreakfast();
	Bread makeBreakfast();
}

public class BreakfastFactory implements AbstractFactory {
	@Override
	public Drink makeDrink() {
		// TODO Auto-generated method stub
		return new Milk();
	}
	@Override
	public Bread makeBread() {
		// TODO Auto-generated method stub
		return new SweetBread();
	}
}

public class Client {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Drink milk=new BreakfastFactory().makeDrink();
		Bread sweetBread=new BreakfastFactory().makeBread();
		milk.sale();
		sweetBread.sale();
	}
}

4.代理模式

访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。
角色:代理,抽象对象,具体对象。

public interface Buy {
	void buy();
}

public class BuyTicket implements Buy {
	@Override
	public void buy() {
		// TODO Auto-generated method stub
		System.out.println("buy ticket");
	}
}

public class Proxy implements Buy {
	private BuyTicket buyTicket = new BuyTicket();
	@Override
	public void buy() {
		// TODO Auto-generated method stub
		System.out.println("proxy buy ticket");
		buyTicket.buy();
		System.out.println("proxy finish buying ticket");
	}
}

public class Client {
	public static void main(String[] args) {
		Proxy proxy=new Proxy();
		proxy.buy();
	}
}

5.适配器模式

将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作。类似于现实生活中的数据线转化接口。

可以通过接口的多继承来实现。

6.装饰者模式

在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式。
使用组合关系来创建一个包装对象(即装饰对象)来包裹真实对象。

角色:抽象构件,具体构件,抽象装饰,具体装饰。

public interface Component {
    public void operation();
}

public class ConcreteComponent implements Component {
	@Override
    public void operation() {
        System.out.println("ConcreteComponent ");
    }
}

public class Decorator implements Component {
    private Component component;
    public Decorator(Component component) {
        this.component = component;
    }
    @Override
    public void operation() {
        component.operation();
    }
}

class ConcreteDecorator extends Decorator {
    public ConcreteDecorator(Component component) {
        super(component);
    }
    public void operation() {
        super.operation();
        addOperation();
    }
    public void addOperation() {
        System.out.println("add operation");
    }
}

7.观察者模式

指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。如微信公众号的推文。

角色:抽象对象,具体对象,抽象观察者,具体观察者。

public interface Observer {
	void recieve(String article);
}

public class User1 implements Observer {
	@Override
	public void recieve(String article) {
		// TODO Auto-generated method stub
		System.out.println("user1 get "+article);
	}
}

public class User2 implements Observer {
	@Override
	public void recieve(String article) {
		// TODO Auto-generated method stub
		System.out.println("user2 get "+article);
	}
}

//公众号
import java.util.ArrayList;
import java.util.List;

public abstract class OfficialAccount {
	public List<Observer> observers = new ArrayList<Observer>();
	public void add(Observer observer) {
        observers.add(observer);
    }	
	public void remove(Observer observer) {
        observers.remove(observer);
    }	
	public abstract void sendArticle();
}

//腾讯的公众号
public class Tencent extends OfficialAccount {
	@Override
	public void sendArticle() {
		// TODO Auto-generated method stub
		String article="this is tencent";
		for(Observer user:observers) {
			user.recieve(article);
		}
	}
}

public class Wechat {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Tencent tencent=new Tencent();
		User1 u1=new User1();
		User2 u2=new User2();
		tencent.add(u1);
		tencent.add(u2);
		tencent.sendArticle();
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值