-
设计模式---创建型模式
2018-01-21 17:54:00创建型模式是创建对象时,不再由我们直接实例化对象,而是根据特定场景,由程序来确定创建对象的方式。一些系统在创建对象时,需要动态地决定怎样创建对象,创建哪些对象,以及如何组合和表示这些对象。创建模式描述...创建型模式是创建对象时,不再由我们直接实例化对象,而是根据特定场景,由程序来确定创建对象的方式。一些系统在创建对象时,需要动态地决定怎样创建对象,创建哪些对象,以及如何组合和表示这些对象。创建模式描述了怎样构造和封装这些动态的决定。包含类的创建模式和对象的创建模式。
创建型模式主要有:单例模式(Singleton)、工厂方法模式(Factory Method)、抽象工厂模式(Abstract Factory)、生成器模式(Builder)和原型模式(Prototype)。单例模式(Singleton)
一个class只允许产生一个实例对象, 通常的做法是定义一个static public的成员函数,以及一个static private的数据成员, 外界通过该static 成员函数获得一个该class的object, 但是, 要确保无论调用多少次, 只能产生一个该class的对象。
clas examClass { public: static public examClass* Instance() { if (NULL == single_obj) { single_obj = new examClass (); } return single_obj; } private: static examClass* single_obj; }
上面的代码示例, 能够实现单线程模式下的单例模式, 但是在多线程环境下, 如果有多个线程同时调用到Instance示例, 并且此时single_obj是NULL,就有可能2个或者多个examClass对象被创建出来。解决的办法, 可以用如下的示例代码来解决:
clas examClass { public: static public examClass* Instance() { if (NULL == single_obj) { mlock.Lock() single_obj = new examClass (); mlock.Unlock() } return single_obj; } private: static examClass* single_obj; static mutex mlock; }
工厂方法模式(Factory Method)
工厂模式, 就是我们在构建对象实例的时候, 不需要直接去调用具体class的构造函数, 而是直接调用一个方法, 就可以根据参数的不同构建需要的class的对象。GoF提供的工厂模式的架构如下:
我们可以采用如下示例代码来实现:
class AbstractClass { public: void run(); } class AClass : public class AbstractClass { public: void run(); } class BClass : public class AbstractClass { public: void run(); } class CClass : public class AbstractClass{ public: void run(); } class Product { public: AbstractClass* Creator(int type); } class ConcreateProduct : public class Product { public: AbstractClass* Creator(int type) { switch (type) { case TYPE_A: return new AClass(); case TYPE_B: return new BClass(); case TYPE_C: return new CClass(); default: break; } return NULL; } }
抽象工厂模式(Abstract Factory)
抽象工厂模式给我的感觉是几个相关的工厂模式的组合, 这些相关的工厂模式用来分别创建不同系列的类似的实例。GoF 给的抽象工厂模式的结构图如下:
举一个比较简单的例子, 假设一家公司生产电脑配件, 并且她生产各种类型的电脑配件, 苹果的, 戴尔的等, 这些公司的电脑的配件都是不一样的。我们可以定义一个AbstractComponentFactory, 它定义AppleComponentFactory, DellComponentFactory, 然后定义AbstractComputor, 以及AppleComputor, DellComputor。
class AbstractComponentFactory { public: virtual Mouse* produceMouse(); virtual Desk* produceDesk(); AbstractComponentFactory* getFactor(int type); private: AbstractComponentFactory* factor; } class AppleComponentFactory: public class AbstractComponentFactory { public: Mouse* produceMouse(); Desk* produceDesk(); } class DellComponentFactory: public class AbstractComponentFactory { public: Mouse* produceMouse(); Desk* produceDesk(); } class AbstractComputor { public: virtual public createMouse(int type); virtual public createDesk(int type); private: AbstractComponentFactory* factory; } class AppleComputor : public class AbstractComputor { public: public Mouse* createMouse() { return factor->getAppleFactory()->produceMouse(); } public Mouse* createDesk() { return factor->getAppleFactory()->produceDesk(); } } class DellComputor : public class AbstractComputor { public: public Mouse* createMouse() { return factor->getDellFactory()->produceMouse(); } public Mouse* createDesk() { return factor->getDellFactory()->produceDesk(); } }
建造模式(Builder)
builder模式:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。Builder模式是一步一步创建一个复杂的对象,它允许用户可以只通过指定复杂对象的类型和内容就可以构建它们,用户不知道内部的具体构建细节。Builder模式是非常类似抽象工厂模式,细微的区别大概只有在反复使用中才能体会到。
原型模式(Prototype)
原型模式:通过给出一个原型对象来指明所要创建的对象的类型,然后用复制这个原型对象的方法创建出更多同类型的对象。原始模型模式允许动态的增加或减少产品类,产品类不需要非得有任何事先确定的等级结构,原始模型模式适用于任何的等级结构。
-
设计模式-创建型模式
2015-11-23 19:37:00创建型模式第一,它们都将系统使用哪些具体类的信息封装起来;第二,它们隐藏了这些类的实例是如何被创建和组织的。 单例模式。 场景。只能有一个实例时的解决方法 抽象工厂模式。 场景。需要创建一系列对象...创建型模式 第一,它们都将系统使用哪些具体类的信息封装起来;第二,它们隐藏了这些类的实例是如何被创建和组织的。单例模式。场景。只能有一个实例时的解决方法抽象工厂模式。场景。需要创建一系列对象的情况,同时,需求改动时,可能需要创建更多对象。如数据库变动,就需要改所有创建包含查询语句的对象。解决方法。提供个接口,这接口可创建一系列相关或相互依赖的对象,客户端不用管是接口的实现类使用哪个数据库。OOP的精华:面向接口编程建造者模式。场景。整体由部分按一定方式构成,部分变化会影响构成整体的原方式。如盖楼的步骤一样,各部分材料不同,材料的变化,不会改变盖楼的步骤。解决方法。把构建整体的方式,与每部分分离开,每部分的变化,不影响构成方式的变化。简单工厂模式,十分常用。场景。一个类的创建代码,如果分散在调用的位置,就会有很多相同的创建代码,修改创建代码,需要改很多处;同时,如果多个相似的子类的创建代码,分散在很多位置,加剧了上述相同;另外,采用子类而不是方法代表不同,方便了扩展,扩展时只需添加子类即可,不用为了加方法而改原类。解决方法。容易变化的用类来实现,代替方法,类的上级可以是普通父类,也可以是接口或抽象类;用工厂类决定创建哪种子类,只需传入参数即可。带来问题是,如果变化太多,用于实现的类会很多,这时,最好使用原型模式,找到各实现类不用的局部点。工厂模式场景。用简单工厂模式时,加功能时,因创建实例的逻辑在工厂类里,需要改工厂类,违背了修改关闭原则。解决办法。把简单工厂的内部逻辑,移到客户端代码,避免改工厂类。定义一个接口,原型模式场景。用简单工厂模式时,新的实现类只改变了一点,但还是要重写一个类,导致了大部分代码相同的实现类很多,改一处,需要改很多实现类。解决办法。用memberwiseclone方法复制对象,并调用系统方法,实现深拷贝。不同处设值。转载于:https://www.cnblogs.com/yinlg/p/4989419.html
-
设计模式(一)创建型模式
2018-07-24 09:54:42创建型模式(Creational Patterns) 这些设计模式提供了一种在创建对象的同时隐藏创建逻辑的方式,而不是使用 new 运算符直接实例化对象。这使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活。 包含以下...创建型模式(Creational Patterns)
这些设计模式提供了一种在创建对象的同时隐藏创建逻辑的方式,而不是使用 new 运算符直接实例化对象。这使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活。包含以下模式:工厂模式(Factory Pattern)、抽象工厂模式(Abstract Factory Pattern)、单例模式(Singleton Pattern)、建造者模式(Builder Pattern)、原型模式(Prototype Pattern)、
工厂模式
工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
介绍
意图:定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。
主要解决:主要解决接口选择的问题。
何时使用:我们明确地计划不同条件下创建不同实例时。
如何解决:让其子类实现工厂接口,返回的也是一个抽象的产品。
关键代码:创建过程在其子类执行。
应用实例: 1、您需要一辆汽车,可以直接从工厂里面提货,而不用去管这辆汽车是怎么做出来的,以及这个汽车里面的具体实现。 2、Hibernate 换数据库只需换方言和驱动就可以。
优点: 1、一个调用者想创建一个对象,只要知道其名称就可以了。 2、扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。 3、屏蔽产品的具体实现,调用者只关心产品的接口。
缺点:每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。
使用场景: 1、日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方。 2、数据库访问,当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化时。 3、设计一个连接服务器的框架,需要三个协议,"POP3"、"IMAP"、"HTTP",可以把这三个作为产品类,共同实现一个接口。
注意事项:作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式。有一点需要注意的地方就是复杂对象适合使用工厂模式,而简单对象,特别是只需要通过 new 就可以完成创建的对象,无需使用工厂模式。如果使用工厂模式,就需要引入一个工厂类,会增加系统的复杂度。
实现
我们将创建一个 Shape 接口和实现 Shape 接口的实体类。下一步是定义工厂类 ShapeFactory。
FactoryPatternDemo,我们的演示类使用 ShapeFactory 来获取 Shape 对象。它将向 ShapeFactory 传递信息(CIRCLE / RECTANGLE / SQUARE),以便获取它所需对象的类型。
步骤 1
创建一个接口:
-
public interface Shape {
-
void draw();
-
}
步骤 2
创建实现接口的实体类。
-
public class Rectangle implements Shape {
-
@Override
-
public void draw() {
-
System.out.println("Inside Rectangle::draw() method.");
-
}
-
}
-
public class Square implements Shape {
-
@Override
-
public void draw() {
-
System.out.println("Inside Square::draw() method.");
-
}
-
}
-
public class Circle implements Shape {
-
@Override
-
public void draw() {
-
System.out.println("Inside Circle::draw() method.");
-
}
-
}
步骤 3
创建一个工厂,生成基于给定信息的实体类的对象。
-
public class ShapeFactory {
-
//使用 getShape 方法获取形状类型的对象
-
public Shape getShape(String shapeType){
-
if(shapeType == null){
-
return null;
-
}
-
if(shapeType.equalsIgnoreCase("CIRCLE")){
-
return new Circle();
-
} else if(shapeType.equalsIgnoreCase("RECTANGLE")){
-
return new Rectangle();
-
} else if(shapeType.equalsIgnoreCase("SQUARE")){
-
return new Square();
-
}
-
return null;
-
}
-
}
步骤 4
使用该工厂,通过传递类型信息来获取实体类的对象。
-
public class FactoryPatternDemo {
-
public static void main(String[] args) {
-
ShapeFactory shapeFactory = new ShapeFactory();
-
//获取 Circle 的对象,并调用它的 draw 方法
-
Shape shape1 = shapeFactory.getShape("CIRCLE");
-
//调用 Circle 的 draw 方法
-
shape1.draw();
-
//获取 Rectangle 的对象,并调用它的 draw 方法
-
Shape shape2 = shapeFactory.getShape("RECTANGLE");
-
//调用 Rectangle 的 draw 方法
-
shape2.draw();
-
//获取 Square 的对象,并调用它的 draw 方法
-
Shape shape3 = shapeFactory.getShape("SQUARE");
-
//调用 Square 的 draw 方法
-
shape3.draw();
-
}
-
}
步骤 5
执行程序,输出结果:
-
Inside Circle::draw() method.
-
Inside Rectangle::draw() method.
-
Inside Square::draw() method.
抽象工厂模式
抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。
介绍
意图:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
主要解决:主要解决接口选择的问题。
何时使用:系统的产品有多于一个的产品族,而系统只消费其中某一族的产品。
如何解决:在一个产品族里面,定义多个产品。
关键代码:在一个工厂里聚合多个同类产品。
应用实例:工作了,为了参加一些聚会,肯定有两套或多套衣服吧,比如说有商务装(成套,一系列具体产品)、时尚装(成套,一系列具体产品),甚至对于一个家庭来说,可能有商务女装、商务男装、时尚女装、时尚男装,这些也都是成套的,即一系列具体产品。假设一种情况(现实中是不存在的,要不然,没法进入共产主义了,但有利于说明抽象工厂模式),在您的家中,某一个衣柜(具体工厂)只能存放某一种这样的衣服(成套,一系列具体产品),每次拿这种成套的衣服时也自然要从这个衣柜中取出了。用 OO 的思想去理解,所有的衣柜(具体工厂)都是衣柜类的(抽象工厂)某一个,而每一件成套的衣服又包括具体的上衣(某一具体产品),裤子(某一具体产品),这些具体的上衣其实也都是上衣(抽象产品),具体的裤子也都是裤子(另一个抽象产品)。
优点:当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
缺点:产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具体的里面加代码。
使用场景: 1、QQ 换皮肤,一整套一起换。 2、生成不同操作系统的程序。
注意事项:产品族难扩展,产品等级易扩展。
实现
我们将创建 Shape 和 Color 接口和实现这些接口的实体类。下一步是创建抽象工厂类 AbstractFactory。接着定义工厂类 ShapeFactory 和 ColorFactory,这两个工厂类都是扩展了 AbstractFactory。然后创建一个工厂创造器/生成器类 FactoryProducer。
AbstractFactoryPatternDemo,我们的演示类使用 FactoryProducer 来获取 AbstractFactory 对象。它将向 AbstractFactory 传递形状信息 Shape(CIRCLE / RECTANGLE / SQUARE),以便获取它所需对象的类型。同时它还向 AbstractFactory 传递颜色信息 Color(RED / GREEN / BLUE),以便获取它所需对象的类型。
步骤 1
为形状创建一个接口。
-
public interface Shape {
-
void draw();
-
}
步骤 2
创建实现接口的实体类。
-
public class Rectangle implements Shape {
-
@Override
-
public void draw() {
-
System.out.println("Inside Rectangle::draw() method.");
-
}
-
}
-
public class Square implements Shape {
-
@Override
-
public void draw() {
-
System.out.println("Inside Square::draw() method.");
-
}
-
}
-
public class Circle implements Shape {
-
@Override
-
public void draw() {
-
System.out.println("Inside Circle::draw() method.");
-
}
-
}
步骤 3
为颜色创建一个接口。
-
public interface Color {
-
void fill();
-
}
步骤4
创建实现接口的实体类。
-
public class Red implements Color {
-
@Override
-
public void fill() {
-
System.out.println("Inside Red::fill() method.");
-
}
-
}
-
public class Green implements Color {
-
@Override
-
public void fill() {
-
System.out.println("Inside Green::fill() method.");
-
}
-
}
-
public class Blue implements Color {
-
@Override
-
public void fill() {
-
System.out.println("Inside Blue::fill() method.");
-
}
-
}
步骤 5
为 Color 和 Shape 对象创建抽象类来获取工厂。
-
public abstract class AbstractFactory {
-
public abstract Color getColor(String color);
-
public abstract Shape getShape(String shape) ;
-
}
步骤 6
创建扩展了 AbstractFactory 的工厂类,基于给定的信息生成实体类的对象。
-
public class ShapeFactory extends AbstractFactory {
-
@Override
-
public Shape getShape(String shapeType){
-
if(shapeType == null){
-
return null;
-
}
-
if(shapeType.equalsIgnoreCase("CIRCLE")){
-
return new Circle();
-
} else if(shapeType.equalsIgnoreCase("RECTANGLE")){
-
return new Rectangle();
-
} else if(shapeType.equalsIgnoreCase("SQUARE")){
-
return new Square();
-
}
-
return null;
-
}
-
@Override
-
public Color getColor(String color) {
-
return null;
-
}
-
}
-
public class ColorFactory extends AbstractFactory {
-
@Override
-
public Shape getShape(String shapeType){
-
return null;
-
}
-
@Override
-
Color getColor(String color) {
-
if(color == null){
-
return null;
-
}
-
if(color.equalsIgnoreCase("RED")){
-
return new Red();
-
} else if(color.equalsIgnoreCase("GREEN")){
-
return new Green();
-
} else if(color.equalsIgnoreCase("BLUE")){
-
return new Blue();
-
}
-
return null;
-
}
-
}
步骤 7
创建一个工厂创造器/生成器类,通过传递形状或颜色信息来获取工厂。
-
public class FactoryProducer {
-
public static AbstractFactory getFactory(String choice){
-
if(choice.equalsIgnoreCase("SHAPE")){
-
return new ShapeFactory();
-
} else if(choice.equalsIgnoreCase("COLOR")){
-
return new ColorFactory();
-
}
-
return null;
-
}
-
}
步骤 8
使用 FactoryProducer 来获取 AbstractFactory,通过传递类型信息来获取实体类的对象。
-
public class AbstractFactoryPatternDemo {
-
public static void main(String[] args) {
-
//获取形状工厂
-
AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE");
-
//获取形状为 Circle 的对象
-
Shape shape1 = shapeFactory.getShape("CIRCLE");
-
//调用 Circle 的 draw 方法
-
shape1.draw();
-
//获取形状为 Rectangle 的对象
-
Shape shape2 = shapeFactory.getShape("RECTANGLE");
-
//调用 Rectangle 的 draw 方法
-
shape2.draw();
-
//获取形状为 Square 的对象
-
Shape shape3 = shapeFactory.getShape("SQUARE");
-
//调用 Square 的 draw 方法
-
shape3.draw();
-
//获取颜色工厂
-
AbstractFactory colorFactory = FactoryProducer.getFactory("COLOR");
-
//获取颜色为 Red 的对象
-
Color color1 = colorFactory.getColor("RED");
-
//调用 Red 的 fill 方法
-
color1.fill();
-
//获取颜色为 Green 的对象
-
Color color2 = colorFactory.getColor("Green");
-
//调用 Green 的 fill 方法
-
color2.fill();
-
//获取颜色为 Blue 的对象
-
Color color3 = colorFactory.getColor("BLUE");
-
//调用 Blue 的 fill 方法
-
color3.fill();
-
}
-
}
步骤 9
执行程序,输出结果:
Inside Circle::draw() method.
Inside Rectangle::draw() method.
Inside Square::draw() method.
Inside Red::fill() method.
Inside Green::fill() method.
Inside Blue::fill() method.
后记
下面例子中鼠标,键盘,耳麦为产品,惠普,戴尔为工厂。
简单工厂模式
简单工厂模式不是 23 种里的一种,简而言之,就是有一个专门生产某个产品的类。
比如下图中的鼠标工厂,专业生产鼠标,给参数 0,生产戴尔鼠标,给参数 1,生产惠普鼠标。
工厂模式
工厂模式也就是鼠标工厂是个父类,有生产鼠标这个接口。
戴尔鼠标工厂,惠普鼠标工厂继承它,可以分别生产戴尔鼠标,惠普鼠标。
生产哪种鼠标不再由参数决定,而是创建鼠标工厂时,由戴尔鼠标工厂创建。
后续直接调用鼠标工厂.生产鼠标()即可
抽象工厂模式
抽象工厂模式也就是不仅生产鼠标,同时生产键盘。
也就是 PC 厂商是个父类,有生产鼠标,生产键盘两个接口。
戴尔工厂,惠普工厂继承它,可以分别生产戴尔鼠标+戴尔键盘,和惠普鼠标+惠普键盘。
创建工厂时,由戴尔工厂创建。
后续工厂.生产鼠标()则生产戴尔鼠标,工厂.生产键盘()则生产戴尔键盘。
在抽象工厂模式中,假设我们需要增加一个工厂
假设我们增加华硕工厂,则我们需要增加华硕工厂,和戴尔工厂一样,继承 PC 厂商。
之后创建华硕鼠标,继承鼠标类。创建华硕键盘,继承键盘类即可。
在抽象工厂模式中,假设我们需要增加一个产品
假设我们增加耳麦这个产品,则首先我们需要增加耳麦这个父类,再加上戴尔耳麦,惠普耳麦这两个子类。
之后在PC厂商这个父类中,增加生产耳麦的接口。最后在戴尔工厂,惠普工厂这两个类中,分别实现生产戴尔耳麦,惠普耳麦的功能。 以上。
单例模式
单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
注意:
- 1、单例类只能有一个实例。
- 2、单例类必须自己创建自己的唯一实例。
- 3、单例类必须给所有其他对象提供这一实例。
介绍
意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
主要解决:一个全局使用的类频繁地创建与销毁。
何时使用:当您想控制实例数目,节省系统资源的时候。
如何解决:判断系统是否已经有这个单例,如果有则返回,如果没有则创建。
关键代码:构造函数是私有的。
应用实例: 1、一个党只能有一个主席。 2、Windows 是多进程多线程的,在操作一个文件的时候,就不可避免地出现多个进程或线程同时操作一个文件的现象,所以所有文件的处理必须通过唯一的实例来进行。 3、一些设备管理器常常设计为单例模式,比如一个电脑有两台打印机,在输出的时候就要处理不能两台打印机打印同一个文件。
优点: 1、在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如管理学院首页页面缓存)。 2、避免对资源的多重占用(比如写文件操作)。
缺点:没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。
使用场景: 1、要求生产唯一序列号。 2、WEB 中的计数器,不用每次刷新都在数据库里加一次,用单例先缓存起来。3、创建的一个对象需要消耗的资源过多,比如 I/O 与数据库的连接等。
注意事项:getInstance() 方法中需要使用同步锁 synchronized (Singleton.class) 防止多线程同时进入造成 instance 被多次实例化。
实现
我们将创建一个 SingleObject 类。SingleObject 类有它的私有构造函数和本身的一个静态实例。
SingleObject 类提供了一个静态方法,供外界获取它的静态实例。SingletonPatternDemo,我们的演示类使用 SingleObject 类来获取 SingleObject 对象。
步骤 1
创建一个 Singleton 类。
-
public class SingleObject {
-
//创建 SingleObject 的一个对象
-
private static SingleObject instance = new SingleObject();
-
//让构造函数为 private,这样该类就不会被实例化
-
private SingleObject(){}
-
//获取唯一可用的对象
-
public static SingleObject getInstance(){
-
return instance;
-
}
-
public void showMessage(){
-
System.out.println("Hello World!");
-
}
-
}
步骤 2
从 singleton 类获取唯一的对象。
-
public class SingletonPatternDemo {
-
public static void main(String[] args) {
-
//不合法的构造函数
-
//编译时错误:构造函数 SingleObject() 是不可见的
-
//SingleObject object = new SingleObject();
-
//获取唯一可用的对象
-
SingleObject object = SingleObject.getInstance();
-
//显示消息
-
object.showMessage();
-
}
-
}
步骤 3
执行程序,输出结果:
Hello World!
单例模式的几种实现方式
单例模式的实现有多种方式,如下所示:
1、懒汉式,线程不安全
是否 Lazy 初始化:是
是否多线程安全:否
实现难度:易
描述:这种方式是最基本的实现方式,这种实现最大的问题就是不支持多线程。因为没有加锁 synchronized,所以严格意义上它并不算单例模式。
这种方式 lazy loading 很明显,不要求线程安全,在多线程不能正常工作。实例
-
public class Singleton {
-
private static Singleton instance;
-
private Singleton (){}
-
public static Singleton getInstance() {
-
if (instance == null) {
-
instance = new Singleton();
-
}
-
return instance;
-
}
-
}
接下来介绍的几种实现方式都支持多线程,但是在性能上有所差异。
2、懒汉式,线程安全
是否 Lazy 初始化:是
是否多线程安全:是
实现难度:易
描述:这种方式具备很好的 lazy loading,能够在多线程中很好的工作,但是,效率很低,99% 情况下不需要同步。
优点:第一次调用才初始化,避免内存浪费。
缺点:必须加锁 synchronized 才能保证单例,但加锁会影响效率。
getInstance() 的性能对应用程序不是很关键(该方法使用不太频繁)。实例
-
public class Singleton {
-
private static Singleton instance;
-
private Singleton (){}
-
public static synchronized Singleton getInstance() {
-
if (instance == null) {
-
instance = new Singleton();
-
}
-
return instance;
-
}
-
}
3、饿汉式
是否 Lazy 初始化:否
是否多线程安全:是
实现难度:易
描述:这种方式比较常用,但容易产生垃圾对象。
优点:没有加锁,执行效率会提高。
缺点:类加载时就初始化,浪费内存。
它基于 classloader 机制避免了多线程的同步问题,不过,instance 在类装载时就实例化,虽然导致类装载的原因有很多种,在单例模式中大多数都是调用 getInstance 方法, 但是也不能确定有其他的方式(或者其他的静态方法)导致类装载,这时候初始化 instance 显然没有达到 lazy loading 的效果。实例
-
public class Singleton {
-
private static Singleton instance = new Singleton();
-
private Singleton (){}
-
public static Singleton getInstance() {
-
return instance;
-
}
-
}
4、双检锁/双重校验锁(DCL,即 double-checked locking)
JDK 版本:JDK1.5 起
是否 Lazy 初始化:是
是否多线程安全:是
实现难度:较复杂
描述:这种方式采用双锁机制,安全且在多线程情况下能保持高性能。
getInstance() 的性能对应用程序很关键。实例
-
public class Singleton {
-
private volatile static Singleton singleton;
-
private Singleton (){}
-
public static Singleton getSingleton() {
-
if (singleton == null) {
-
synchronized (Singleton.class) {
-
if (singleton == null) {
-
singleton = new Singleton();
-
}
-
}
-
}
-
return singleton;
-
}
-
}
5、登记式/静态内部类
是否 Lazy 初始化:是
是否多线程安全:是
实现难度:一般
描述:这种方式能达到双检锁方式一样的功效,但实现更简单。对静态域使用延迟初始化,应使用这种方式而不是双检锁方式。这种方式只适用于静态域的情况,双检锁方式可在实例域需要延迟初始化时使用。
这种方式同样利用了 classloader 机制来保证初始化 instance 时只有一个线程,它跟第 3 种方式不同的是:第 3 种方式只要 Singleton 类被装载了,那么 instance 就会被实例化(没有达到 lazy loading 效果),而这种方式是 Singleton 类被装载了,instance 不一定被初始化。因为 SingletonHolder 类没有被主动使用,只有通过显式调用 getInstance 方法时,才会显式装载 SingletonHolder 类,从而实例化 instance。想象一下,如果实例化 instance 很消耗资源,所以想让它延迟加载,另外一方面,又不希望在 Singleton 类加载时就实例化,因为不能确保 Singleton 类还可能在其他的地方被主动使用从而被加载,那么这个时候实例化 instance 显然是不合适的。这个时候,这种方式相比第 3 种方式就显得很合理。实例
-
public class Singleton {
-
private static class SingletonHolder {
-
private static final Singleton INSTANCE = new Singleton();
-
}
-
private Singleton (){}
-
public static final Singleton getInstance() {
-
return SingletonHolder.INSTANCE;
-
}
-
}
6、枚举
JDK 版本:JDK1.5 起
是否 Lazy 初始化:否
是否多线程安全:是
实现难度:易
描述:这种实现方式还没有被广泛采用,但这是实现单例模式的最佳方法。它更简洁,自动支持序列化机制,绝对防止多次实例化。
这种方式是 Effective Java 作者 Josh Bloch 提倡的方式,它不仅能避免多线程同步问题,而且还自动支持序列化机制,防止反序列化重新创建新的对象,绝对防止多次实例化。不过,由于 JDK1.5 之后才加入 enum 特性,用这种方式写不免让人感觉生疏,在实际工作中,也很少用。
不能通过 reflection attack 来调用私有构造方法。实例
-
public enum Singleton {
-
INSTANCE;
-
public void whateverMethod() {
-
}
-
}
经验之谈:一般情况下,不建议使用第 1 种和第 2 种懒汉方式,建议使用第 3 种饿汉方式。只有在要明确实现 lazy loading 效果时,才会使用第 5 种登记方式。如果涉及到反序列化创建对象时,可以尝试使用第 6 种枚举方式。如果有其他特殊的需求,可以考虑使用第 4 种双检锁方式。
建造者模式
建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
一个 Builder 类会一步一步构造最终的对象。该 Builder 类是独立于其他对象的。
介绍
意图:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。
主要解决:主要解决在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。
何时使用:一些基本部件不会变,而其组合经常变化的时候。
如何解决:将变与不变分离开。
关键代码:建造者:创建和提供实例,导演:管理建造出来的实例的依赖关系。
应用实例: 1、去肯德基,汉堡、可乐、薯条、炸鸡翅等是不变的,而其组合是经常变化的,生成出所谓的"套餐"。 2、JAVA 中的 StringBuilder。
优点: 1、建造者独立,易扩展。 2、便于控制细节风险。
缺点: 1、产品必须有共同点,范围有限制。 2、如内部变化复杂,会有很多的建造类。
使用场景: 1、需要生成的对象具有复杂的内部结构。 2、需要生成的对象内部属性本身相互依赖。
注意事项:与工厂模式的区别是:建造者模式更加关注与零件装配的顺序。
实现
我们假设一个快餐店的商业案例,其中,一个典型的套餐可以是一个汉堡(Burger)和一杯冷饮(Cold drink)。汉堡(Burger)可以是素食汉堡(Veg Burger)或鸡肉汉堡(Chicken Burger),它们是包在纸盒中。冷饮(Cold drink)可以是可口可乐(coke)或百事可乐(pepsi),它们是装在瓶子中。
我们将创建一个表示食物条目(比如汉堡和冷饮)的 Item 接口和实现 Item 接口的实体类,以及一个表示食物包装的 Packing 接口和实现 Packing 接口的实体类,汉堡是包在纸盒中,冷饮是装在瓶子中。
然后我们创建一个 Meal 类,带有 Item 的 ArrayList 和一个通过结合 Item 来创建不同类型的 Meal 对象的 MealBuilder。BuilderPatternDemo,我们的演示类使用 MealBuilder 来创建一个 Meal。
步骤 1
创建一个表示食物条目和食物包装的接口。
-
public interface Item {
-
public String name();
-
public Packing packing();
-
public float price();
-
}
-
public interface Packing {
-
public String pack();
-
}
步骤 2
创建实现 Packing 接口的实体类。
-
public class Wrapper implements Packing {
-
@Override
-
public String pack() {
-
return "Wrapper";
-
}
-
}
-
public class Bottle implements Packing {
-
@Override
-
public String pack() {
-
return "Bottle";
-
}
-
}
步骤 3
创建实现 Item 接口的抽象类,该类提供了默认的功能。
-
public abstract class Burger implements Item {
-
@Override
-
public Packing packing() {
-
return new Wrapper();
-
}
-
@Override
-
public abstract float price();
-
}
-
public abstract class ColdDrink implements Item {
-
@Override
-
public Packing packing() {
-
return new Bottle();
-
}
-
@Override
-
public abstract float price();
-
}
步骤 4
创建扩展了 Burger 和 ColdDrink 的实体类。
-
public class VegBurger extends Burger {
-
@Override
-
public float price() {
-
return 25.0f;
-
}
-
@Override
-
public String name() {
-
return "Veg Burger";
-
}
-
}
-
public class ChickenBurger extends Burger {
-
@Override
-
public float price() {
-
return 50.5f;
-
}
-
@Override
-
public String name() {
-
return "Chicken Burger";
-
}
-
}
-
public class Coke extends ColdDrink {
-
@Override
-
public float price() {
-
return 30.0f;
-
}
-
@Override
-
public String name() {
-
return "Coke";
-
}
-
}
-
public class Pepsi extends ColdDrink {
-
@Override
-
public float price() {
-
return 35.0f;
-
}
-
@Override
-
public String name() {
-
return "Pepsi";
-
}
-
}
步骤 5
创建一个 Meal 类,带有上面定义的 Item 对象。
-
import java.util.ArrayList;
-
import java.util.List;
-
public class Meal {
-
private List<Item> items = new ArrayList<Item>();
-
public void addItem(Item item){
-
items.add(item);
-
}
-
public float getCost(){
-
float cost = 0.0f;
-
for (Item item : items) {
-
cost += item.price();
-
}
-
return cost;
-
}
-
public void showItems(){
-
for (Item item : items) {
-
System.out.print("Item : "+item.name());
-
System.out.print(", Packing : "+item.packing().pack());
-
System.out.println(", Price : "+item.price());
-
}
-
}
-
}
步骤 6
创建一个 MealBuilder 类,实际的 builder 类负责创建 Meal 对象。
-
public class MealBuilder {
-
public Meal prepareVegMeal (){
-
Meal meal = new Meal();
-
meal.addItem(new VegBurger());
-
meal.addItem(new Coke());
-
return meal;
-
}
-
public Meal prepareNonVegMeal (){
-
Meal meal = new Meal();
-
meal.addItem(new ChickenBurger());
-
meal.addItem(new Pepsi());
-
return meal;
-
}
-
}
步骤 7
BuiderPatternDemo 使用 MealBuider 来演示建造者模式(Builder Pattern)。
-
public class BuilderPatternDemo {
-
public static void main(String[] args) {
-
MealBuilder mealBuilder = new MealBuilder();
-
Meal vegMeal = mealBuilder.prepareVegMeal();
-
System.out.println("Veg Meal");
-
vegMeal.showItems();
-
System.out.println("Total Cost: " +vegMeal.getCost());
-
Meal nonVegMeal = mealBuilder.prepareNonVegMeal();
-
System.out.println("\n\nNon-Veg Meal");
-
nonVegMeal.showItems();
-
System.out.println("Total Cost: " +nonVegMeal.getCost());
-
}
-
}
步骤 8
执行程序,输出结果:
-
Veg Meal
-
Item : Veg Burger, Packing : Wrapper, Price : 25.0
-
Item : Coke, Packing : Bottle, Price : 30.0
-
Total Cost: 55.0
-
Non-Veg Meal
-
Item : Chicken Burger, Packing : Wrapper, Price : 50.5
-
Item : Pepsi, Packing : Bottle, Price : 35.0
-
Total Cost: 85.5
原型模式
原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。例如,一个对象需要在一个高代价的数据库操作之后被创建。我们可以缓存该对象,在下一个请求时返回它的克隆,在需要的时候更新数据库,以此来减少数据库调用。
介绍
意图:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
主要解决:在运行期建立和删除原型。
何时使用: 1、当一个系统应该独立于它的产品创建,构成和表示时。 2、当要实例化的类是在运行时刻指定时,例如,通过动态装载。 3、为了避免创建一个与产品类层次平行的工厂类层次时。 4、当一个类的实例只能有几个不同状态组合中的一种时。建立相应数目的原型并克隆它们可能比每次用合适的状态手工实例化该类更方便一些。
如何解决:利用已有的一个原型对象,快速地生成和原型对象一样的实例。
关键代码: 1、实现克隆操作,在 JAVA 继承 Cloneable,重写 clone(),在 .NET 中可以使用 Object 类的 MemberwiseClone() 方法来实现对象的浅拷贝或通过序列化的方式来实现深拷贝。 2、原型模式同样用于隔离类对象的使用者和具体类型(易变类)之间的耦合关系,它同样要求这些"易变类"拥有稳定的接口。
应用实例: 1、细胞分裂。 2、JAVA 中的 Object clone() 方法。
优点: 1、性能提高。 2、逃避构造函数的约束。
缺点: 1、配备克隆方法需要对类的功能进行通盘考虑,这对于全新的类不是很难,但对于已有的类不一定很容易,特别当一个类引用不支持串行化的间接对象,或者引用含有循环结构的时候。 2、必须实现 Cloneable 接口。
使用场景: 1、资源优化场景。 2、类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等。 3、性能和安全要求的场景。 4、通过 new 产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式。 5、一个对象多个修改者的场景。 6、一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用。 7、在实际项目中,原型模式很少单独出现,一般是和工厂方法模式一起出现,通过 clone 的方法创建一个对象,然后由工厂方法提供给调用者。原型模式已经与 Java 融为浑然一体,大家可以随手拿来使用。
注意事项:与通过对一个类进行实例化来构造新对象不同的是,原型模式是通过拷贝一个现有对象生成新对象的。浅拷贝实现 Cloneable,重写,深拷贝是通过实现 Serializable 读取二进制流。
实现
我们将创建一个抽象类 Shape 和扩展了 Shape 类的实体类。下一步是定义类 ShapeCache,该类把 shape 对象存储在一个 Hashtable 中,并在请求的时候返回它们的克隆。
PrototypePatternDemo,我们的演示类使用 ShapeCache 类来获取 Shape 对象。
步骤 1
创建一个实现了 Clonable 接口的抽象类。
-
public abstract class Shape implements Cloneable {
-
private String id;
-
protected String type;
-
abstract void draw();
-
public String getType(){
-
return type;
-
}
-
public String getId() {
-
return id;
-
}
-
public void setId(String id) {
-
this.id = id;
-
}
-
public Object clone() {
-
Object clone = null;
-
try {
-
clone = super.clone();
-
} catch (CloneNotSupportedException e) {
-
e.printStackTrace();
-
}
-
return clone;
-
}
-
}
步骤 2
创建扩展了上面抽象类的实体类。
-
public class Rectangle extends Shape {
-
public Rectangle(){
-
type = "Rectangle";
-
}
-
@Override
-
public void draw() {
-
System.out.println("Inside Rectangle::draw() method.");
-
}
-
}
-
public class Square extends Shape {
-
public Square(){
-
type = "Square";
-
}
-
@Override
-
public void draw() {
-
System.out.println("Inside Square::draw() method.");
-
}
-
}
-
public class Circle extends Shape {
-
public Circle(){
-
type = "Circle";
-
}
-
@Override
-
public void draw() {
-
System.out.println("Inside Circle::draw() method.");
-
}
-
}
步骤 3
创建一个类,从数据库获取实体类,并把它们存储在一个 Hashtable 中。
-
import java.util.Hashtable;
-
public class ShapeCache {
-
private static Hashtable<String, Shape> shapeMap
-
= new Hashtable<String, Shape>();
-
public static Shape getShape(String shapeId) {
-
Shape cachedShape = shapeMap.get(shapeId);
-
return (Shape) cachedShape.clone();
-
}
-
// 对每种形状都运行数据库查询,并创建该形状
-
// shapeMap.put(shapeKey, shape);
-
// 例如,我们要添加三种形状
-
public static void loadCache() {
-
Circle circle = new Circle();
-
circle.setId("1");
-
shapeMap.put(circle.getId(),circle);
-
Square square = new Square();
-
square.setId("2");
-
shapeMap.put(square.getId(),square);
-
Rectangle rectangle = new Rectangle();
-
rectangle.setId("3");
-
shapeMap.put(rectangle.getId(),rectangle);
-
}
-
}
步骤 4
PrototypePatternDemo 使用 ShapeCache 类来获取存储在 Hashtable 中的形状的克隆。
-
public class PrototypePatternDemo {
-
public static void main(String[] args) {
-
ShapeCache.loadCache();
-
Shape clonedShape = (Shape) ShapeCache.getShape("1");
-
System.out.println("Shape : " + clonedShape.getType());
-
Shape clonedShape2 = (Shape) ShapeCache.getShape("2");
-
System.out.println("Shape : " + clonedShape2.getType());
-
Shape clonedShape3 = (Shape) ShapeCache.getShape("3");
-
System.out.println("Shape : " + clonedShape3.getType());
-
}
-
}
步骤 5
执行程序,输出结果:
-
Shape : Circle
-
Shape : Square
-
Shape : Rectangle
-
-
Java jdk中包含哪些设计模式-动力节点
2020-10-23 09:46:57在JDK(Java Development Kit)类库中,开发人员使用了大量设计模式,正因为如此,我们可以在不修改JDK源码的前提下...Java jdk中包含哪些设计模式 创建型模式: (1)抽象工厂模式(Abstract Factory) •java.util.Calenda在JDK(Java Development Kit)类库中,开发人员使用了大量设计模式,正因为如此,我们可以在不修改JDK源码的前提下开发出自己的应用软件,本文列出了部分JDK中的模式应用实例,有兴趣的同学可以深入研究,看看前Sun公司的开发人员是如何在实际框架开发中运用设计模式的,Sunny认为,研究JDK类库中的模式实例也不失为学习如何使用设计模式的一个好方式。
Java jdk中包含哪些设计模式
创建型模式:
(1)抽象工厂模式(Abstract Factory)
•java.util.Calendar#getInstance()
•java.util.Arrays#asList()
•java.util.ResourceBundle#getBundle()
•java.net.URL#openConnection()
•java.sql.DriverManager#getConnection()
•java.sql.Connection#createStatement()
•java.sql.Statement#executeQuery()
•java.text.NumberFormat#getInstance()
•java.lang.management.ManagementFactory(所有getXXX()方法)
•java.nio.charset.Charset#forName()
•javax.xml.parsers.DocumentBuilderFactory#newInstance()
•javax.xml.transform.TransformerFactory#newInstance()
•javax.xml.xpath.XPathFactory#newInstance()
(2)建造者模式(Builder)
•java.lang.StringBuilder#append()
•java.lang.StringBuffer#append()
•java.nio.ByteBuffer#put()(CharBuffer,ShortBuffer,IntBuffer,LongBuffer,FloatBuffer和DoubleBuffer与之类似)
•javax.swing.GroupLayout.Group#addComponent()
•java.sql.PreparedStatement
•java.lang.Appendable的所有实现类
(3)工厂方法模式(Factory Method)
•java.lang.Object#toString()(在其子类中可以覆盖该方法)
•java.lang.Class#newInstance()
•java.lang.Integer#valueOf(String)(Boolean,Byte,Character,Short,Long,Float和Double与之类似)
•java.lang.Class#forName()
•java.lang.reflect.Array#newInstance()
•java.lang.reflect.Constructor#newInstance()
(4)原型模式(Prototype)
•java.lang.Object#clone()(支持浅克隆的类必须实现java.lang.Cloneable接口)
(5)单例模式(Singleton)
•java.lang.Runtime#getRuntime()
•java.awt.Desktop#getDesktop()
结构型模式:
(1)适配器模式(Adapter)
•java.util.Arrays#asList()
•javax.swing.JTable(TableModel)
•java.io.InputStreamReader(InputStream)
•java.io.OutputStreamWriter(OutputStream)
•javax.xml.bind.annotation.adapters.XmlAdapter#marshal()
•javax.xml.bind.annotation.adapters.XmlAdapter#unmarshal()
(2)桥接模式(Bridge)
•AWT(提供了抽象层映射于实际的操作系统)
•JDBC
(3)组合模式(Composite)
•javax.swing.JComponent#add(Component)
•java.awt.Container#add(Component)
•java.util.Map#putAll(Map)
•java.util.List#addAll(Collection)
•java.util.Set#addAll(Collection)
(4)装饰模式(Decorator)
•java.io.BufferedInputStream(InputStream)
•java.io.DataInputStream(InputStream)
•java.io.BufferedOutputStream(OutputStream)
•java.util.zip.ZipOutputStream(OutputStream)
•java.util.Collections#checkedList|Map|Set|SortedSet|SortedMap
(5)外观模式(Facade)
•java.lang.Class
•javax.faces.webapp.FacesServlet
(6)享元模式(Flyweight)
•java.lang.Integer#valueOf(int)
•java.lang.Boolean#valueOf(boolean)
•java.lang.Byte#valueOf(byte)
•java.lang.Character#valueOf(char)
(7)代理模式(Proxy)
•java.lang.reflect.Proxy
•java.rmi.*
行为型模式:
(1)职责链模式(Chain of Responsibility)
•java.util.logging.Logger#log()
•javax.servlet.Filter#doFilter()
(2)命令模式(Command)
•java.lang.Runnable
•javax.swing.Action
(3)解释器模式(Interpreter)
•java.util.Pattern
•java.text.Normalizer
•java.text.Format
•javax.el.ELResolver
(4)迭代器模式(Iterator)
•java.util.Iterator
•java.util.Enumeration
(5)中介者模式(Mediator)
•java.util.Timer(所有scheduleXXX()方法)
•java.util.concurrent.Executor#execute()
•java.util.concurrent.ExecutorService(invokeXXX()和submit()方法)
•java.util.concurrent.ScheduledExecutorService(所有scheduleXXX()方法)
•java.lang.reflect.Method#invoke()
(6)备忘录模式(Memento)
•java.util.Date
•java.io.Serializable
•javax.faces.component.StateHolder
(7)观察者模式(Observer)
•java.util.Observer/java.util.Observable
•java.util.EventListener(所有子类)
•javax.servlet.http.HttpSessionBindingListener
•javax.servlet.http.HttpSessionAttributeListener
•javax.faces.event.PhaseListener
(8)状态模式(State)
•java.util.Iterator
•javax.faces.lifecycle.LifeCycle#execute()
(9)策略模式(Strategy)
•java.util.Comparator#compare()
•javax.servlet.http.HttpServlet
•javax.servlet.Filter#doFilter()
(10)模板方法模式(Template Method)
•java.io.InputStream,java.io.OutputStream,java.io.Reader和java.io.Writer的所有非抽象方法
•java.util.AbstractList,java.util.AbstractSet和java.util.AbstractMap的所有非抽象方法
•javax.servlet.http.HttpServlet#doXXX()
(11)访问者模式(Visitor)
•javax.lang.model.element.AnnotationValue和AnnotationValueVisitor
•javax.lang.model.element.Element和ElementVisitor
•javax.lang.model.type.TypeMirror和TypeVisitor
-
java的JDK中包含哪些设计模式
2013-10-09 15:40:09在JDK(Java Development Kit)类库中,开发人员使用了大量设计模式,正因为如此,我们可以在不修改JDK源码的前提下开发出自己的应用软件,本文列出了部分JDK中的模式应用实例,有兴趣的童鞋可以深入研究,看看前Sun... -
-
23种设计模式包括哪些
2014-06-12 16:38:12一共23种设计模式! 按照目的来分,设计模式可以分为创建型模式、结构型...创建型模式用来处理对象的创建过程,主要包含以下5种设计模式: 工厂方法模式(Factory Method Pattern) 抽象工厂模式... -
设计模式、对应的应用场景以及优缺点有哪些?
2020-09-24 10:18:41设计模式从大的维度来说,可以分为三大类:创建型模式、结构型模式及行为型模式,这三大类下又有很多小分类。 创建型模式是指提供了一种对象创建的功能,并把对象创建的过程进行封装隐藏,让使用者只关注具体的使用... -
设计模式开篇
2020-05-23 23:45:47创建型模式包含:单例模式、工厂模式、抽象工厂模式、建造者模式和原型模式 结构型模式包含:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式和代理模式 行为型模式包含:模板方法模式、命令模式、... -
设计模式常见面试题汇总
2020-10-28 16:07:48答:设计模式总共有 23 种,总体来说可以分为三大类:创建型模式( Creational Patterns )、结构型模式( Structural Patterns )和行为型模式( Behavioral Patterns )。 分类 包含 关注点 创建型模式 ... -
设计模式之初识设计模式
2017-10-11 12:45:48常用的设计模式一共有23中,分为三大类,创建型模式(Creational Patterns)、结构型模式(Structural Patterns)、行为型模式(Behavioral Patterns)。创建型模式提供了一种在创建对象的同时隐藏创建逻辑的方式,... -
设计模式概述
2019-06-26 21:32:08本节将会介绍一下设计模式的分类及各个类别包含哪些设计模式,另外会介绍一下设计模式的六大原则。 设计模式简介 设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计... -
设计模式面试题
2020-11-16 23:21:39答:设计模式总共有 23 种,总体来说可以分为三大类:创建型模式( Creational Patterns )、结构型模式( Structural Patterns )和行为型模式( Behavioral Patterns )。 分类 包含 关注点 创建型模式 工厂模式、... -
-
设计模式(一)建造者模式
2018-05-02 09:46:00GOF论述了23种设计模式,它们有3个分类————创建型模式、结构型模式、行为模式。此篇为创建型模式创建型模式抽象了实例化的过程,它们可以帮助某个系统独立于如何创建、组合以及表示该系统所包含的对象。当系统... -
-
-
设计模式大全
2015-03-18 11:11:33设计模式主要有三大类: 创建模式:对类的实例化过程的抽象。一些系统在创建对象时,需要动态地决定怎样创建对象,创建哪些对象,以及如何组合和表示这些对象。创建模式描述了怎样构造和封装这些动态的决定。包含类... -
设计模式分类
2017-11-04 09:48:00创建型模式(解决对象的创建) 创建型模式抽象了实例化过程.它们帮助一个系统独立于如何创建/组合和表示它的那些对象.一个类创建模式使用继承改变被实例化的类,一个对象创建型模式将实例化委托给另一个对象. 特点:... -
java设计模式(23种设计模式集体打酱油)
2010-08-11 20:59:28另外,近来这一清单又增加了一些类别,例如,并发型模式,线程池模式,javaEE企业技术的多层应用程序上的模式等,下面来看看每一种类型包含哪些设计模式。 I.创建型模式 1.[b]工厂方法模式[/b](Factory Method)[url... -
JAVA设计模式——建造者模式
2018-01-16 17:28:50建造者模式是创建型设计模式。一个产品常由不同的零件构成,我们把这些零件叫做产品的内部表象(internal representation)。不同的产品可以有不同的内部表象,也就是不同的零件。建造模式思想是:把创建对象过程中... -
java设计模式的意图【Z】
2010-09-14 14:27:07另外,近来这一清单又增加了一些类别,例如,并发型模式,线程池模式,javaEE企业技术的多层应用程序上的模式等,下面来看看每一种类型包含哪些设计模式。 I.创建型模式 1.工厂方法模式 (Factory Method)... -
设计模式提升与加强一
2011-10-28 09:38:00“设计模式”一书包含的23种模式都有若干个著名的应用,这些应用具有一定的通用性,可以方便地应用于不同应用领域,并且包含多种对象。有关作者将这些模式分成三类: 1、创建型模式(Creational pattern):为... -
设计模式之(十八)备忘录模式
2020-07-24 11:20:38在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态,是一种对象行为型模式,其别名为Token 结构图 (1)Originator(原发器)是一个普通的... -
设计模式实战 - 责任链模式
2019-01-19 14:29:48每一个处理对象决定它能处理哪些命令对象,它也知道如何将它不能处理的命令对象传递给该链中的下一个处理对象. 该模式还描述了往该处理链的末尾添加新的处理对象的方法. 精简定义 为请求创建一个接收此次请求对象的链... -
常用设计模式及 Java程序设计(含java源码)
2010-01-15 11:33:38常用设计模式及 Java程序设计 第一章设计模式基础 一:什么是设计模式 在面向对象的软件设计中,总是希望避免重复设计或尽可能少做重复设计。有经验的面向对象 设计者的确能做出良好的设计,而新手则面对众多选择... -
-
用Go语言来写区块链(一)
-
安装MySQL无法下一步问题解决了!
-
MySQL 管理利器 mysql-utilities
-
狂神的SpringSecurity素材.rar
-
Unity RUST 逆向安全开发
-
【Python-随到随学】FLask第二周
-
基于python的dango框架购物商城毕业设计毕设源代码使用教程
-
PowerBI重要外部工具详解
-
自动化测试Python3+Selenium3+Unittest
-
牛牛量化策略交易
-
惠普HP OfficeJet Pro 9018 打印机驱动
-
MySQL 触发器
-
10.易课寄在线购课系统部署-CentOS6环境安装Redis
-
MySQL 备份与恢复详解(高低版本 迁移;不同字符集 相互转换;表
-
应广105G雾化片驱动.rar
-
python文件上传接口实例
-
IntelliJ IDEA 2019 下载安装教程
-
libFuzzer视频教程
-
pcmcia转串口驱动
-
07.易课寄在线购课系统部署-CentOS6环境安装ZooKeeper