单例模式
特点:
1、单例类只能有一个实例。
2、单例类必须自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。
主要:
懒汉模式:存在线程安全问题
//懒汉式单例类.在第一次调用的时候实例化自己
public class Singleton {
private Singleton() {}
private static Singleton single=null;
//静态工厂方法
public static Singleton getInstance() {
if (single == null) {
single = new Singleton();
}
return single;
}
}
饿汉模式:建议使用
//饿汉式单例类.在类初始化时,已经自行实例化
public class Singleton1 {
private Singleton1() {}
private static final Singleton1 single = new Singleton1();
//静态工厂方法
public static Singleton1 getInstance() {
return single;
}
}
builder模式(建造者模式)
定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
public class penguin {
private String name;
private Integer age;
private String sex;
private Integer heignt;
public void print() {
String str = "name:" + name;
str += (age == null) ? "" : ",age:" + age;
str += (sex == null) ? "" : ",sex:" + sex;
str += (heignt == null) ? "" : ",age:" + heignt;
System.out.println(str);
}
public penguin(penguinBuilder builder) {
this.age = builder.age;
this.name = builder.name;
this.sex = builder.sex;
this.heignt = builder.heignt;
}
public static class penguinBuilder {
private String name;
private Integer age;
private String sex;
private Integer heignt;
public penguinBuilder setName(String name) {
this.name = name;
return this;
}
public penguinBuilder setAge(Integer age) {
this.age = age;
return this;
}
public penguinBuilder setSex(String sex) {
this.sex = sex;
return this;
}
public penguinBuilder setHeignt(Integer heignt) {
this.heignt = heignt;
return this;
}
public penguin bulid() {
return new penguin(this);
}
}
}
总结一下build模式的要点:
定义一个静态内部类Builder,内部的成员变量和外部类一样;
Builder类通过一系列的方法用于成员变量的赋值,并返回当前对象本身(this);
Builder类提供一个外部类的创建方法(build、create……),该方法内部调用了外部类的一个私有构造函数,入参就是内部类Builder;
外部类提供一个私有构造函数供内部类调用,在该构造函数中完成成员变量的赋值,取值为Builder对象中对应的成变量的值。
工厂方法模式
工厂方法模式将工厂抽象化,并定义一个创建对象的接口。每增加新产品,只需增加该产品以及对应的具体实现工厂类,由具体工厂类决定要实例化的产品是哪个,将对象的创建与实例化延迟到子类,这样工厂的设计就符合“开闭原则”了,扩展时不必去修改原来的代码。
abstract class BMW {
public BMW(){}
}
public class BMW320 extends BMW {
public BMW320() {
System.out.println("制造-->BMW320");
}
}
public class BMW523 extends BMW{
public BMW523(){
System.out.println("制造-->BMW523");
}
}
interface FactoryBMW {
BMW createBMW();
}
public class FactoryBMW320 implements FactoryBMW{
@Override
public BMW320 createBMW() {
return new BMW320();
}
}
public class FactoryBMW523 implements FactoryBMW {
@Override
public BMW523 createBMW() {
return new BMW523();
}
}
工厂模式小结:
1、工厂方法模式与抽象工厂模式的区别在于:
(1)工厂方法只有一个抽象产品类和一个抽象工厂类,但可以派生出多个具体产品类和具体工厂类,每个具体工厂类只能创建一个具体产品类的实例。
(2)抽象工厂模式拥有多个抽象产品类(产品族)和一个抽象工厂类,每个抽象产品类可以派生出多个具体产品类;抽象工厂类也可以派生出多个具体工厂类,同时每个具体工厂类可以创建多个具体产品类的实例
代理模式
代理模式的设计动机是通过代理对象来访问真实对象,通过建立一个对象代理类,由代理对象控制原对象的引用,从而实现对真实对象的操作。在代理模式中,代理对象主要起到一个中介的作用,用于协调与连接调用者(即客户端)和被调用者(即目标对象),在一定程度上降低了系统的耦合度,同时也保护了目标对象。但缺点是在调用者与被调用者之间增加了代理对象,可能会造成请求的处理速度变慢,
public class HerChum implements GiveGift{
You you;
public HerChum(BeautifulGirl mm){
you = new You(mm);
}
public void giveBook() {
you.giveBook();
}
public void giveChocolate() {
you.giveChocolate();
}
public void giveFlowers() {
you.giveFlowers();
}
}
装饰器模式执行主体是原类;代理模式是代理原类进行操作,执行主体是代理类。
观察者模式
观察者模式又称为 发布-订阅模式,定义了对象之间一对多依赖关系,当目标对象(被观察者)的状态发生改变时,它的所有依赖者(观察者)都会收到通知。
观察者模式的两种模式:
(1)拉取模式:目标角色在发生变化后,仅仅告诉观察者角色“我变化了”,观察者角色如果想要知道具体的变化细节,则就要自己从目标角色的接口中得到,这种模式称为拉取模式,就是说变化的信息是观察者角色主动从目标角中“拉”出来的。
(2)推送模式:目标角色发生变化时,通知观察者的同时,通过参数将变化的细节传递到观察者角色中去。
这两种模式的使用取决于系统设计,如果目标角色比较复杂,并且观察者角色进行更新时必须得到一些具体变化的信息,则“推模式”比较合适,如果目标角色比较简单,则“拉模式”就很合适啦。
public interface Subject {
/**
* 注册观察者
* @param observer
*/
public void registerObserver(Observer observer);
/**
* 删除观察者
* @param observer
*/
public void removeOberver(Observer observer);
/**
* 当主题状态发生改变时,这个方法需要被调用,以通知所有观察者
*/
public void notifyObserver();
}
public interface Observer {
public void update(float temp,float humidity,float pressure);
}
public interface DisplayElement {
public void display();
}
public class WeatherData implements Subject{
private List<Observer> observers;
private float tempterature;
private float pressure;
private float humidity;
public WeatherData(){
observers = new ArrayList<Observer>();
}
@Override
public void notifyObserver() {
for(int i = 0; i < observers.size();i++){
Observer observer = observers.get(i);
observer.update(tempterature, humidity, pressure);
}
}
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}
@Override
public void removeOberver(Observer observer) {
int i = observers.indexOf(observer);
if(i >= 0){
observers.remove(i);
}
}
/**
* 气象站得到更新的观测数据时,通知观察者
*/
public void measurementChanged(){
notifyObserver();
}
public void setMeasurements(float temperature,float humidity,float pressure){
this.tempterature = temperature;
this.humidity = humidity;
this.pressure = pressure;
measurementChanged();
}
}
public class CurrentConditionsDisplay implements Observer,DisplayElement{
private float temperature;
private float humidity;
private Subject weatherData;
public CurrentConditionsDisplay(Subject weatherData){
this.weatherData = weatherData;
weatherData.registerObserver(this); //注册观察者
}
public void update(float temp, float humidity, float pressure) {
this.temperature = temp;
this.humidity = humidity;
display();
}
@Override
public void display() {
System.out.println("Current conditions:"+temperature+"F degrees and "+humidity+"% humidity");
}
}
public class WeatherStation {
public static void main(String[] args) {
WeatherData weatherData = new WeatherData();
CurrentConditionsDisplay conditionsDisplay = new CurrentConditionsDisplay(weatherData);
weatherData.setMeasurements(80, 65, 30.4f);
weatherData.setMeasurements(82, 70, 29.2f);
weatherData.setMeasurements(78, 78, 40.4f);
}
}