单例模式
现实生活中常出现唯一的现象,比如地球只有一个
为了保证一个类只有一个实例,核心办法就是把构造方法设置为私有的,也就是只有自己才能实例化自己
public class ClassMaster {
private String id;
// 班主任名称
private String name;
private String gender;
// 唯一实例
private static ClassMaster instance = new ClassMaster();
private ClassMaster() {
}
}
这种保证只有一个实例对象的方式就是单例设计模式
为了给其他得类使用还需要增加一个方法,允许其他类访问这个单利的实例
public class ClassMaster {
private String id;
// 班主任名称
private String name;
private String gender;
// 唯一实例
private static ClassMaster instance = new ClassMaster();
private ClassMaster() {
}
// 外部类可以通过这个方法访问唯一的实例
public static ClassMaster getInstance() {
return instance;
}
}
UML图
spring中的单例
任何自动注入实例对象,默认只有一个实例对象
简单工厂模式
程序中的工厂是生产实例对象的地方
为了实现不同条件创建不同对象的需求,核心问题是:
- 减少代码重复,减少相同逻辑代码
- 降低耦合紧密,减少代码之间的相互影响
实现简单工厂:
- 从具体的产品类抽象出接口,java面向接口编程,所以工厂应该生产一种产品而不是一个产品
- 把生产实例对象的过程收敛到工厂类中实现
UML图
public class FruitFactory {
public static Fruit getFruit(Customer customer) {
Fruit fruit = null;
if ("sweet".equals(customer.getFlavor())) {
fruit = new Watermelon();
} else if ("acid".equals(customer.getFlavor())) {
fruit = new Lemon();
} else if ("smelly".equals(customer.getFlavor())) {
fruit = new Durian();
}
return fruit;
}
}
工厂主要的优点在于职责明确,餐馆和甜品店只需要告诉工厂口味,就可以获得工厂的水果,但又不需要知道具体是什么水果
一般工厂命名为XXXFactory
,这样的辨识度较高易于理解
重点在于明确什么条件下创建什么实例对象
抽象工厂模式
对于一批,多种类型的对象需要创建时,使用抽象工厂模式
简单工厂主要是把多个产品抽象,使用一个工厂统一创建,抽象工厂则是把多个工厂进一步抽象
UML图
就是进一步抽象工厂接口(SnackFactory)多出一个SnacksFactoryBuilder
工厂接口
规定工厂应该提供什么样的产品,包含了所有工厂的方法
public interface SnacksFactory {
// 取得水果
public Fruit getFruit(Customer customer);
// 取得饮料
public Drink getDrink(Customer customer);
}
public class FruitFactory implements SnacksFactory {
public Fruit getFruit(Customer customer) {
Fruit fruit = null;
if ("sweet".equals(customer.getFlavor())) {
fruit = new Watermelon();
} else if ("acid".equals(customer.getFlavor())) {
fruit = new Lemon();
} else if ("smelly".equals(customer.getFlavor())) {
fruit = new Durian();
}
return fruit;
}
//水果工厂不提供饮料
public Drink getDrink(Customer customer) {
return null;
}
}
工厂的工厂
工厂用来生成产品实例,生产工厂的工厂用于生成工厂实例
public class SnacksFactoryBuilder {
public SnacksFactory buildFactory(String choice) {
if (choice.equalsIgnoreCase("fruit")) {
return new FruitFactory();
} else if (choice.equalsIgnoreCase("drink")) {
return new DrinkFactory();
}
return null;
}
}
SnacksFactoryBuilder
的buildFactory()
方法并不是static
的,在复杂场景下尽量不要使用static方法
工厂模式结合Spring工程
在工厂中减少定义static
方法是为了在使用Spring框架时,可以为FactoryBuilder
加上@Component
注解让框架管理实例
@Component
public class FactoryBuilder {
public Factory buildFactory(String choice) {
}
}
同样任何需要使用工厂的地方只需要使用@Autowired
注解让框架自动注入实例即可,这样可以让工厂模式的代码与Spring互为一体,扩展性更好,易于维护
观察者模式
订阅和通知这种场景比较适合观察者模式
把需要观察的对象类也就是会改变的类继承Observable
类,继承了就表示是核心的,需要观察的类
和以往的模型设计不一样,需要观察的类要去掉全部属性的setter
方法
Observable提供的setChanged()
方法就是标记被观察者对象发送了变化,notifyObservers()
就是发出通知.
接受通知的类就叫做观察者,观察者需要实现Observer
接口,表示为观察者
@Override
public void update(Observable o, Object arg) {
}
- 第一个参数就是被观察者对象
- 第二个参数就是额外的信息,具体就是调用
super.notifyObservers()
是传入的参数对象,传入什么对象,arg的值就是什么对象
update()方法的作用就是接受通知,系统在super.notifyObservers()发出通知后,及调用了所有的观察者的update()方法
观察者可以有多个,无论观察者还是被观察者对象谁先new出来都可以,但必须先调用addObserver()
方法把观察者对象实例添加到被观察者实例中,然后再调用自定义的changeTemp()
方法改变天气,才能触发通知