在实际开发中我们越来越多的使用到设计模式,使用设计不仅可以提升代码的可读性,解耦,复用,可拓展性还能增强代码的健壮性;现在使用设计模式已经变成了一种常态,那么接下来的一段时间我们一起了解一下Java常用的几种设计模式;
本节主要分析单例模式,工厂模式,观察者模式;
一、单例模式
1、构造方法私有化,阻断一切外部new的入口;
2、防止类多次实例化;
1)懒汉式:声明一个静态变量。并且在用户getInstance 时进行初始化;
例如:
public class Singleton{
private static Singleton instence
private Singleleton(){}//构造函数私有化
public static synchronized Singleton getInstance()//synchronized 同步锁保证在多线程下单例模式的唯一性
{
if(instence==null)
{
instence=new Singleton();
}
return instence;
}
}
懒汉式单例模式的优点:只有在使用的时候才会实例化,很大程度上节约了资源;
缺点:第一次加载的时候需要及时的进行实例化,反应速度慢,每次调用getInstance都会进行同步,很大程度上造成不必要的同步开销;
2)饿汉式:创建的时候就进行实例化
例如:
public class CEO{
private static final CEO ceo=getCEO();
private CEO(){}//构造函数私有化确保单例模式
public static CEO getCEO(){ //共有的静态函数,提供对外的实例化接口
return ceo;
}
}
3)Double Check Lock(DCL 实现单例模式)这是一个双重加锁的方式
优点:既能够在需要的时候初始化,又能保证线程的安全,且单例对象初始化调用getInstence()不进行同步锁;
缺点:第一次加载时反应慢,也会因为Java内存模型问题偶尔失败(虽然概率很小);
例如:
public calss Singleton{
private static final Singleton instence=null;
private Singleton(){}
public static Singleton getInstence(){
if(instence==null)
{
sychronized(Singleton.calss)
{
if(instence==null)
{
instence=new Singleton();
}
}
}
return instence;
}
}
volatile 关键字,用来修饰被不同线程访问和修改的变量;可以保证不同线程对这个变量进行操作的可见性,即一个线程修改了这个变量的值这个新值对其他线程立即可见;
4)静态内部类的单例模式
例如:
public class Singleton{
private Singleton(){}
pirvate static Singleton getInstence()
{
return SingletonHoder.instence;
}
pirvate static class SingletonHoder{
private static final Singleton instence =new Singleton();
}
}
优点:第一次初始化不会实例化instence 只有在我们手动调用getInstence()时才会被初始化,并且第一次加载会导致虚拟机加载SingletonHolder 类这种方式即能保证线程安全,又能保证单例的唯一性,同时也延迟了单例的实例化,这种方式是比较推荐的单例模式加载方式;
二、工厂模式
1、简单工厂模式
简单工厂模式又称为静态工厂方法模式;
工厂顾名思义就是生产产品的地方;简单工厂模式:通过建立一个(函数或者方法)来制造新的对象,(定义一个创建对象的接口或者方法)具体的产品继承父类或者实现接口;
特点:一个工厂,一个车间,一条生产线;
public class EasyFactory {
//工厂类直接生产产品,根据客户的产品类型创建新的产品类,当添加新的车型的时候只需创建不同的产品在此方法中实例化
public static Car getCar(String carName) {
if (carName.equals("audi")) {
return new AuDi();
}else if(carName.equals("fengtian")){
return new FengTian();
}
return null;
}
}
实际调用
//简单工厂模式
Car audi = EasyFactory.getCar("audi");
audi.drive();
2、工厂方法模式
特点:只有一个抽象产品类,一个抽象工厂类,(一个工厂多个车间一条生产线)
一个抽象工厂类,派生出多个具体工厂类;
一个抽象产品类,派生多个具体产品类;
一个具体工厂类,派生出一个具体产品类;
抽象工厂类
public abstract class FactoryM {
public abstract ProductM newProduct();
}
抽象产品类
public abstract class ProductM {
public abstract ProductM show(String productType);
}
具体工厂类
public class BikeFactory extends FactoryM {
@Override
public ProductM newProduct() {
return new BikeProduct();
}
}
具体产品类
public class BikeProduct extends ProductM {
@Override
public BikeProduct show(String productType) {
//根据不同的类型完成不同的功能,如果针对一些具体的产品类需要不同于公共的特性可以直接创建具体的产品类
Log.e("TAG", "这是一个" + productType + "类型的自行车");
if (productType.equals("飞鸽")) {
return new FeiGeBike();
}
return new BikeProduct();
}
}
不同车型的具体产品类
//针对一些特殊的车型,可能有自己的一些特性,那么可以创建不同车型的具体产品类,用于制造自己的特色
public class FeiGeBike extends BikeProduct {
public static FeiGeBike daliang()
{
Log.e("TAG","这是飞鸽特有的大樑自行车");
return new FeiGeBike();
}
}
具体调用
//工厂方法模式
FeiGeBike bikeOfFeiGe = (FeiGeBike) new BikeFactory().newProduct().show("飞鸽");
bikeOfFeiGe.daliang();
3、抽象工厂模式
特点:多个抽象产品类,如果以汽车为例,那么抽象工厂模式好比机械自动化生产车间,程序设置好每个车型的汽车使用哪个发动机,那种空调,那么抽象工厂类就组装该车型,如果新增车型,只需要重现创建发动机空调的型号,在创建此类车型的时候实例化不同的发动机以及空调型号;
一个工厂,多个车间,多条生产线
抽象发动机
public interface Engine {
}
//具体发动机
class EngineA implements Engine{
public EngineA() {
Log.e("TAG","这是320发动机");
}
}
class EngineB implements Engine{
public EngineB() {
Log.e("TAG","这是230发动机");
}
}
抽象空调
public interface Aircondition {
}
//具体空调类
class AirconditionA implements Aircondition{
public AirconditionA() {
Log.e("TAG","空调A");
}
}
class AirconditionB implements Aircondition{
public AirconditionB() {
Log.e("TAG","空调B");
}
}
抽象工厂类
public interface AbstractFactory {
public Engine createEngine();
public Aircondition createAircondition();
}
具体工厂类
public class AudiFactory implements AbstractFactory {
@Override
public Engine createEngine() {
return new EngineB();
}
@Override
public Aircondition createAircondition() {
return new AirconditionB();
}
}
调用
//抽象工厂模式
BMWFactory bmwFactory=new BMWFactory();
bmwFactory.createEngine();
bmwFactory.createAircondition();
AudiFactory audiFactory=new AudiFactory();
audiFactory.createEngine();
audiFactory.createAircondition();
三、观察者模式
定义:
对象间一中一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并自动更新;
简言之:就是一个订阅发布的模式;
观察者模式包括:
1、抽象被观察者:需要把所有的观察者保存在一个集合中,提供一个接口可以增加和删除观察者,以及通知观察者的工作;
2、抽象观察者:为所有的具体观察者定义一个接口,有更新消息时通知自己;
3、具体被观察者;
4、具体观察者;
抽象被观察者
public interface Observerable {
public void registerObserver(Observer observer);
public void removeObserver(Observer observer);
public void notifyObserver();
}
抽象观察者
public interface Observer {
public void update(String message);
}
具体被观察者
public class Boss implements Observerable {
List<Observer> observerList = new ArrayList<>();//存放所有观察者的集合
String message;
@Override
public void registerObserver(Observer observer) {
observerList.add(observer);
}
@Override
public void removeObserver(Observer observer) {
if (observerList.size() >= 1) {
observerList.remove(observer);
}
}
@Override
public void notifyObserver() {
for (Observer observer : observerList) {
observer.update(message);
}
}
public void setMessage(String message)
{
this.message=message;
notifyObserver();
}
}
具体观察者
public class Employee implements Observer {
String message;
@Override
public void update(String message) {
this.message=message;
wireIn(message);
}
private void wireIn(String message) {
Log.e("TAG",""+message);
}
}
调用
public class ObserverActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_observer);
//实例化被观察者
Boss boss=new Boss();
//实例化公司部门员工
Employee qiantai=new Employee();
Employee renshi=new Employee();
Employee kaifa=new Employee();
//注册观察老板的监听
boss.registerObserver(qiantai);
boss.registerObserver(renshi);
boss.registerObserver(kaifa);
//老板要来公司了
boss.setMessage("今天到公司转一圈");
//移除对老板的观察
boss.registerObserver(kaifa);
}
}
结果
由此可见,当老板来的时候,所有的部门员工都接收到了老板来公司转一圈的消息;
同时当remove掉观察者后那么,就将收不到老板来的消息;那么在具体的开发中我们不单是接收单纯的消息,有时会是监听数据的变化,或者监听页面的变化等等,那么具体的业务逻辑就需要根据具体的情况而定;