1.单例模式
就是在整个应用中保证只有一个类的实例存在。单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
单例模式分为懒汉式单例和恶汉式单例。
//懒汉式
public class SingleInstance {
public double d = Math.random();
private static SingleInstance single = null;
//私有化构造器:其他类不能创建此类的对象
private SingleInstance() {
}
//静态工厂,用来生产对象的
public static SingleInstance getInstance() {
if (single == null) {
single = new SingleInstance();
}
return single;
}
}
class Test {
public static void main(String[] args) {
SingleInstance s1 = SingleInstance.getInstance();
SingleInstance s2 = SingleInstance.getInstance();
System.out.println(s1.d);
System.out.println(s2.d);
}
}
//饿汉式
public class SingleInstance {
public double d = Math.random();
private static SingleInstance single = new SingleInstance();
//私有化构造器:其他类不能创建此类的对象
private SingleInstance() {
}
//静态工厂,用来生产对象的
public static SingleInstance getInstance() {
return single;
}
}
2.工厂模式
一抽象产品类派生出多个具体产品类;一抽象工厂类派生出多个具体工厂类;每个具体工厂类只能创建一个具体产品类的实例。
一个工厂类处于对产品类实例化调用的中心位置上,它决定哪一个产品应当被实例化,也就是说由工厂类来决定实例化哪一个具体产品类的对象
工厂模式是根据不同的参数得到不同的对象,用工厂方法代替new操作的一种模式,可带来更大的扩展性和尽量少的修改量。
//抽象产品类
public abstract class Car {
public abstract void drive();
}
//具体产品类:大众车
class DazhongCar extends Car{
@Override
public void drive() {
System.out.println("DazhongCar");
}
}
//具体产品类:BMW
class BMW extends Car {
@Override
public void drive() {
System.out.println("BMW");
}
}
//具体产品类:QQCar
class QQCar extends Car {
@Override
public void drive() {
System.out.println("QQCar");
}
}
//工厂:根据用户的需求具体生产某一个产品
public class Factory {
public static Car getCar(String s) {
Car car = null;
if (s.equals("dazhong")) {
car = new DazhongCar();//生产大众车的
} else if(s.equals("bmw")) {
car = new BMW();//生产宝马车的
} else if(s.equals("QQ")) {
car = new QQCar();//生产QQ车
}
return car;//返回一个具体的车
}
}
//测试类
public class Test {
public static void main(String[] args) {
Car car = Factory.getCar("QQ");//通过名称从工厂中得到车对象
car.drive();
Car car2 = Factory.getCar("bmw");
car2.drive();
}
}
3.代理模式
为其他对象提供一种代理以控制对这个对象的访问
在某些情况下,一个对象不想或不能直接引用一个对象,而代理对象可以在客户端与目标对象之间起到中介的作用。
代理是触发真正做事情的入口,通过被代理(目标对象)的业务逻辑方法来实现抽象方法,并可以附加自己的操作。
//抽象角色
public abstract class SaleTickets {
public abstract void sale();
}
//真实角色:也就是真正的卖票点
class TrainStation extends SaleTickets {
@Override
public void sale() {
System.out.println("卖票");
}
}
//代理角色:票务中心
public class Helper extends SaleTickets {
TrainStation ts = new TrainStation();
@Override
public void sale() {
ts.sale();
}
}
//使用者对象
public class User {
public static void main(String[] args) {
Helper help = new Helper();//通过代理来买票
help.sale();
}
}
4.观察者模式
当一个抽象模型有两个方面,其中一个方面依赖于另一方面。将这两者封装在独立的对象中以使它们可以各自独立的改变和复用。
当对一个对象的改变需要同时改变其他对象,而不知道具体有多少对象有待改变。
当一个对象必须通知其他对象,而它又不能假定其他对象是谁。换言之,你不希望这些对象是紧密耦合的。
//抽象观察者角色
public abstract class Watcher {
public abstract void update();
}
//具体的观察者角色:警察
class Police extends Watcher {
@Override
public void update() {
System.out.println("运输车有情况,警察保驾护航");
}
}
//具体的观察者角色:保镖
class Protector extends Watcher {
@Override
public void update() {
System.out.println("运输车有情况,保镖贴身保护");
}
}
//具体的观察者角色:劫匪
class Thief extends Watcher {
@Override
public void update() {
System.out.println("运输车有情况,劫匪准备动手");
}
}
//抽象主题角色:提供抽象的方法用来添加、删除以及通知所有的观察者对象
public abstract class Transfer {
//添加观察者对象
public abstract void addWatcher(Watcher w);
//删除观察者对象
public abstract void deleteWatcher(Watcher w);
//通知所有的观察者对象
public abstract void notifyWatcher();
}
//具体主题角色
class CreateTransfer extends Transfer {
List<Watcher> list = new ArrayList<Watcher>();
//添加观察者对象
@Override
public void addWatcher(Watcher w) {
list.add(w);
}
//删除观察者对象
@Override
public void deleteWatcher(Watcher w) {
list.remove(w);//根据元素名称删除一个数据
}
//通知所有的观察者对象:调用观察者中的更新状态的方法
@Override
public void notifyWatcher() {
for (Watcher w : list) {
w.update();
}
}
}
//测试类
public class Test {
public static void main(String[] args) {
//创建观察者对象
Police police = new Police();
Protector protect = new Protector();
Thief thief = new Thief();
//创建具体主题角色对象,然后往里面添加观察者对象
CreateTransfer ct = new CreateTransfer();
ct.addWatcher(police);
ct.addWatcher(protect);
ct.addWatcher(thief);
//通知所有的观察者对象
ct.notifyWatcher();
}
}
5.适配器模式
这个模式后面在安卓中,我还会详细介绍~~(比较重要)
想要使用一个已经存在的类,但如果它的方法不满足需求时。
两个类的职责相同或相似,但是具有不同的接口
应该在双方都不太容易修改的时候再使用适配器模式适配,而不是一有不同就使用。
接口要尽量简单,可以实现多个接口来实现多个功能。使用适配器来实现多个接口,并重写接口中所有的抽象方法,再写一个子类来继承这个适配器,就可以实现想要的方法,而不是在子类中重写所有的抽象方法。使用适配器扩展性较好,若接口中需要添加新的抽象方法,就可以只在适配器中重写该方法,对子类不会造成影响。
//目标类
public class Target {
public int get110v(){
System.out.println("220v");
return 220;
}
}
//需要适配的类
interface Adaptee {
public int get380v();
public int get110v();
}
//公用方法接口
public interface Inf1 {
public void work();
}
class Target {
public void work() {
System.out.println("target work");
}
}
//重写目标方法
class Adapter extends Target {
class Inner implements Inf1 {
@Override
public void work() {
System.out.println("inf work");
}
}
}
//适配器:Adapter
public class Adapter extends Target implements Adaptee {
@Override
public int get380v() {
return 220;
}
}
class Test {//把110V和380V电压都适配到220V使用
public static void main(String[] args) {
Adapter a = new Adapter();
System.out.println(a.get110v());
System.out.println(a.get380v());
}
}