PHP网站开发与管理设计心得,资阳做网站,中国有多少网站有多少域名,北京西站电话文章目录 参考简介工厂模式简单工厂模式工厂方法模式抽象工厂模式总结 单例模式预加载懒加载线程安全问题 策略模式 参考
知乎
简介
总体来说设计模式分为三类共23种。
创建型模式#xff0c;共五种#xff1a;工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模… 文章目录 参考简介工厂模式简单工厂模式工厂方法模式抽象工厂模式总结 单例模式预加载懒加载线程安全问题 策略模式 参考
知乎
简介
总体来说设计模式分为三类共23种。
创建型模式共五种工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
结构型模式共七种适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式共十一种策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
工厂模式
简单工厂模式
定义了一个创建对象的类由这个类来封装实例化对象的行为。 如下Pizza工厂生产chesse pepper greek三种类型的pizza所有创建pizza对象的行为都要通过SimplePizzaFactory这个类完成。
public class SimplePizzaFactory {public Pizza CreatePizza(String ordertype) {Pizza pizza null;if (ordertype.equals(cheese)) {pizza new CheesePizza();} else if (ordertype.equals(greek)) {pizza new GreekPizza();} else if (ordertype.equals(pepper)) {pizza new PepperPizza();}return pizza;}
}工厂方法模式
简单工厂模式有一个问题是对象的创建依赖工厂类本身如果要拓展程序必须对工厂类进行修改。 可以定义一个创建对象的抽象方法并创建多个不同的工厂类实现该抽象方法这样需要增加新功能时直接增加新的工厂类即可如下。
// OrderPizza中的抽象方法
abstract Pizza createPizza();// 伦敦和纽约两个工厂实现抽象方法
public class LDOrderPizza extends OrderPizza {Pizza createPizza(String ordertype) {Pizza pizza null;if (ordertype.equals(cheese)) {pizza new LDCheesePizza();} else if (ordertype.equals(pepper)) {pizza new LDPepperPizza();}return pizza;}
}
public class NYOrderPizza extends OrderPizza {Pizza createPizza(String ordertype) {Pizza pizza null;if (ordertype.equals(cheese)) {pizza new NYCheesePizza();} else if (ordertype.equals(pepper)) {pizza new NYPepperPizza();}return pizza;}}这个模式的好处是如果想增加功能只需新增实现类即可。
抽象工厂模式
上述模式抽象程度仍不足如客户想吃伦敦工厂的pizza还需亲自调用伦敦工厂的createPizza方法。可以进一步优化使用户只需传入自己的需求作为参数即可不用亲自寻找不同的工厂。
点单方法如下只需向固定的对象传入不同参数即可。
public class PizzaStroe {public static void main(String[] args) {OrderPizza mOrderPizza;mOrderPizza new OrderPizza(London);}
}抽象工厂的接口如下
public interface AbsFactory {Pizza CreatePizza(String ordertype) ;
}工厂实现如下
public class LDFactory implements AbsFactory {Overridepublic Pizza CreatePizza(String ordertype) {Pizza pizza null;if (cheese.equals(ordertype)) {pizza new LDCheesePizza();} else if (pepper.equals(ordertype)) {pizza new LDPepperPizza();}return pizza;}
}总结
简单工厂模式就是建立一个实例化对象的类在该类中对多个对象实例化。工厂方法模式是定义了一个创建对象的抽象方法由子类决定要实例化的类。这样做的好处是再有新的类型的对象需要实例化只要增加子类即可。抽象工厂模式定义了一个接口用于创建对象族而无需明确指定具体类。抽象工厂也是把对象的实例化交给了子类即支持拓展。同时提供给客户端接口避免了用户直接操作子类工厂。
单例模式
确保一个类最多只有一个实例并提供一个全局访问点。可以分为预加载和懒加载两种。
预加载
在使用单例对象之前先加载其到内存
public class PreloadSingleton {public static PreloadSingleton instance new PreloadSingleton();//其他的类无法实例化单例类的对象private PreloadSingleton() {};public static PreloadSingleton getInstance() {return instance;}
}懒加载
为了避免内存浪费可以等用到该单例对象的时候再创建。
public class Singleton {private static Singleton instancenull;private Singleton(){};public static Singleton getInstance(){if(instancenull){instancenew Singleton();}return instance;}
}线程安全问题
预加载可以保证线程安全懒加载无法保证线程安全因为if判断后执行代码是非原子性的而且new操作内部也无法保证顺序性因为创建一个对象分三步
memoryallocate();//1:初始化内存空间ctorInstance(memory);//2:初始化对象instancememory();//3:设置instance指向刚分配的内存地址jvm为了提高程序执行性能会对没有依赖关系的代码进行重排序上面2和3行代码可能被重新排序。我们用两个线程来说明线程是不安全的。线程A和线程B都创建对象。其中A2和A3的重排序将导致线程B在B1处判断出instance不为空线程B接下来将访问instance引用的对象。此时线程B将会访问到一个还未初始化的对象线程不安全。 可以使用synchronized关键字保证线程安全如果在getInstance函数上加此关键字那么无论有没有初始化实例都会影响其他线程的执行出于性能考虑把关键字加到if判空的语句块内保证instance没有实例化时才加锁。然后还需使用volatile关键字保证对象实例化过程的顺序性。
public class Singleton {private static volatile Singleton instance null;private Singleton() {};public static synchronized Singleton getInstance() {if (instance null) {synchronized (instance) {if (instance null) {instance new Singleton();}}}return instance;}
}策略模式
策略模式定义了一系列算法并将每个算法封装起来使得他们可以相互替换且算法的变化不会影响到客户。 例实现一个加减的功能类图如下 抽象策略角色定义如下
public interface Strategy {public int calc(int num1,int num2);
}具体策略角色继承于抽象策略角色分别实现了加减法。
public class AddStrategy implements Strategy {Overridepublic int calc(int num1, int num2) {// TODO Auto-generated method stubreturn num1 num2;}}
public class SubstractStrategy implements Strategy {Overridepublic int calc(int num1, int num2) {// TODO Auto-generated method stubreturn num1 - num2;}
环境角色引用抽象角色给客户端调用
public class Environment {private Strategy strategy;public Environment(Strategy strategy) {this.strategy strategy;}public int calculate(int a, int b) {return strategy.calc(a, b);}}客户端调用环境角色完成计算
public class MainTest {public static void main(String[] args) {Environment environmentnew Environment(new AddStrategy());int resultenvironment.calculate(20, 5);System.out.println(result);Environment environment1new Environment(new SubstractStrategy());int result1environment1.calculate(20, 5);System.out.println(result1);}}