1.工厂方法模式(创建型)
在这之中有简单工厂模式 和工厂方法模式
简单工厂模式
概述:又叫静态工厂模式,它定义一个具体的工厂类负责创建一些类的实例
优点:客户端不需要再负责对象的创建。
缺点:如果有新的对象增加,或者某些对象的创建方式不同,就需要不断修改工厂类
不利于后期的维护。
代码:
每个代码
1.定义接口,定义一个具体的动作
//每个具体类的父类
public interface Flower {
void bloom();
}
提供一个工厂类,用静态方法间接创建对象
//对象创建的工厂类
public class FlowerFactory {
//需要私有化构造方法,外界不能创建该类对象
private FlowerFactory(){};
public static WhiteHe createWhiteHe(){
return new WhiteHe();
}
public static Shy createShy(){
return new Shy();
}
}
工厂类改进
public class FlowerFactory2 {
//私有化构造
private FlowerFactory2(){};
public static Flower createFlower(String type){
if("shy".equals(type)){
return new Shy();
}
else if("WhiteHe".equals(type)){
return new WhiteHe();
}
return null;
}
}
public class Shy implements Flower {
public void bloom() {
System.out.println("含羞草自闭了");
}
}
public class WhiteHe implements Flower {
public void bloom() {
System.out.println("百合开花了");
}
}
测试类:
public class Test {
public static void main(String[] args) {
Shy s = FlowerFactory.createShy();
s.bloom();
}
}
工厂方法模式(创建型)
概述:
工厂方法模式去掉了简单工厂模式中方法的静态属性,使得子类可以继承,这样在简单工厂模式里集中在工厂方法上的压力可以由工厂方法模式里面的不同子工厂来分担
工厂中抽象工厂类负责定义创建对象的接口,具体的创建工作由继承抽象工厂的具体类去实现.
优点:
客户端不需要负责对象的创建,从而明确了各个类的职责,如果有新的类增加,只需要增加一个具体的类和具体的工厂类即可,不影响已有代码,后期维护容易,增加了系统的扩展性.
缺点:需要增加额外的代码,增加了工作量.
代码
//定义一个接口动作
//定义一个接口动作
public interface Flower {
void bloom();
}
//定义一个对象创建接口的工厂
public interface Factory {
Flower create();
}
//定义一个具体类
//定义一个具体类
public class Baihe implements Flower{
public void bloom() {
System.out.println("百合花开");
}
}
//定义一个百合花的创建工厂
//定义一个百合花的创建工厂
public class BaiHeFactory implements Factory {
public Flower create() {
return new Baihe();
}
}
//定义一个测试类
//定义一个测试类
public class Demo {
public static void main(String[] args) {
Factory f = new BaiHeFactory();
Flower ff = f.create();
ff.bloom();
}
}
2.抽象工厂模式:
提供一个创建一系列或相互依赖对象的接口,而无需指定它们具体的类.
何时使用:生产的产品不可能只有一类,可能是花就可能是鸟,必须要对上述例子进行扩展
//定义抽象产品
//定义抽象产品
public interface Bird {
void play();
}
//定义抽象产品
//定义抽象产品
public interface Flower {
void bloom();
}
//抽象工厂
public interface Factory {
Bird createBird();
Flower createFlower();
}
//定义鸟类猫头鹰
//定义鸟类猫头鹰
public class Maotouying implements Bird {
public void play() {
System.out.println("猫头鹰在摇头");
}
}
//定义花类含羞草
//定义花类含羞草
public class Shy implements Flower {
public void bloom() {
System.out.println("含羞草自闭了");
}
}
//定义具体工厂类,可以生产多种产品
public class BigFactory implements Factory {
public Bird createBird() {
return new Maotouying();
}
//定义测试类
//定义测试类
public class Demo {
public static void main(String[] args) {
//创建工厂类对象
Factory f = new BigFactory();
f.createBird().play();
f.createFlower().bloom();
}
}
3.单例模式(面试一定会问到!)
Servlet程序(优化服务器开发的) 单例的(创建型)
单例设计模式概述:单例模式就是确保类在内存中只有一个对象,该实例必须自动创建,并且对外
提供.
优点:在系统内存中只存在一个对象,因此可以节约系统资源,对于一些需要频繁创建和销毁的对象,单例模式无疑可以提高系统性能.
缺点:
没有抽象层,因此扩展很难
职责过重,在一定程度上违背了单一职责.
单例模式的三个写法特征:
1.私有化构造
2.私有化类变量(表示该类的对象)
3.提供静态方法获得该对象
单例模式又分为两种:饿汉式和懒汉式
两者区别是:饿汉一旦加载,单例初始化完成了,保证getInstance的时候,单例就是已经存在的,
而懒汉比较懒,只有在调用getInstance的时候,才回去初始化这个值
饿汉式:
public class Ehan {
//2.创建该对象变量并且私有化,
private static Ehan instance;//饿汉式,在实例化该对象的时候已经存在单例对象了
//1.私有化构造
private Ehan(){
}
//提供静态成员变量(返回值是该类对象)
public static Ehan getInstance(){
return instance;
}
懒汉式:
public class Lanhan {
private static Lanhan instance;
private Lanhan(){
}
public static Lanhan getInstance(){
if(instance==null){
instance = new Lanhan();
}
return instance;
}
}
懒汉式会存在线程安全问题:一旦if(instance==null)判断结束之后,转到另一个线程,其他线程创建了一个对象,而继续一开始的线程,该线程由于判断过了,会接着创建对象,这时候系统中会存在多个对象.
4.原型模式:(Prototype Pattern)
概述:用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象。
在应用程序中,有些对象比较复杂,其创建过程过于复杂,而且我们又需要频繁的利用该对象,如果这个时候我们按照常规思维new该对象,那么务必会带来非常多的麻烦,这个时候我们就希望可以利用一个已有的对象来不断对他进行复制就好了,这就是编程中的“克隆”。这里原型模式就可以满足我们的“克隆”,在原型模式中我们可以利用过一个原型对象来指明我们所要创建对象的类型,然后通过复制这个对象的方法来获得与该对象一模一样的对象实例。这就是原型模式的设计目的。
使用场景:
1。如果新建对象成本较大,我们可以利用已有的对象复制来获得
2。如果系统要保存对象的状态,而对象的状态变化很小,或者对象本身占内存不大的时候,也可以使用原型模式配合备忘录模式来应用。相反,如果对象状态变化很大,或者占用内存过多,那么采用状态模式会比原型模式更好
3.需要避免使用分层次的工厂类来创建分层次的对象,并且类的实例对象只有一个或很少的几个组合状态,通过复制原型对象得到新实例可能比使用构造函数创建新实例更加方便。
优点:
1.如果创建新的对象比较复杂时,可以利用原型模式简化对象的创建过程,同事也能够提高效率
2.可以动态的保存当前对象的状态。在运行时,可以随时使用对象流保存当前对象的一个复制品。
3.可以在运行时创建新的对象,而无需创建一些列类和集成结构
4.可以动态的添加、删除原型的复制品。
缺点:
需要为每一个类配备一个克隆方法,而且这个克隆方法需要对类的功能进行通盘考虑,者对全新的类来说不是很难,但是对已有的类进行改造的时候,克隆方法在类的内部,不一定是件容易的事,违反了开闭原则。
//原型接口
public interface Prototype {
Object cloneSelf(); //克隆自身的方法
}
//具体原型
public class SimplePrototype implements Prototype,Cloneable {
int value;
//clone()实现
public Object cloneSelf() {
SimplePrototype self = new SimplePrototype();
self.value = value;
return self;
}
//使用
public static void main(String args[]){
SimplePrototype simplePrototype = new SimplePrototype();
simplePrototype.value = 500;
SimplePrototype simplePrototypeClone = (SimplePrototype) simplePrototype.cloneSelf();
System.out.println(simplePrototypeClone.value);
}
}
//客户端使用
public class Client {
SimplePrototype prototype;
public Client(SimplePrototype prototype){
this.prototype = prototype;
}
public Object getPrototype(){
return prototype.cloneSelf();
}
}