设计模式学习-基于Java
对http://www.runoob.com/design-pattern/design-pattern-tutorial.html的学习总结,没那么啰嗦,直接上代码。
代码位于Github:https://github.com/425776024/DesignPattern
目录
1.工厂模式
优点: 1、一个调用者想创建一个对象,只要知道其名称就可以了。 2、扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。 3、屏蔽产品的具体实现,调用者只关心产品的接口。
缺点:每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。
1.1创建抽象
package 设计模式.工厂模式;
public interface Shape {
void draw();
}
1.2具体实现了Rectangle和Square
package 设计模式.工厂模式;
public class Square implements Shape {
@Override
public void draw() {
System.out.println("Square.draw()");
}
}
package 设计模式.工厂模式;
public class Rectangle implements Shape {
// Rectangle具体实现shape的抽象
@Override
public void draw() {
// 具体实现
System.out.println("Rectangle.drwa()");
}
}
1.3创建实例工厂
package 设计模式.工厂模式;
public class ShapeFactory {
// shape抽象类的生成工厂,给定信息,生成对应的具体类
public Shape getShape(String shape_type) {
// 根据shape_type,生成具体的类
if (shape_type == null) {
return null;
}
if (shape_type.equalsIgnoreCase("RECTANGLE")) {
return new Rectangle();
}
if (shape_type.equalsIgnoreCase("SQUARE")) {
return new Square();
}
return null;
}
}
1.4main
package 设计模式.工厂模式;
public class FactoryPatterDemo {
public static void main(String[] args) {
ShapeFactory shapeFactory = new ShapeFactory();
// 获取一个长方形类
Shape shape1 = shapeFactory.getShape("RECTANGLE");
shape1.draw();
// 正方形类
Shape shape2 = shapeFactory.getShape("SQUARE");
shape2.draw();
}
}
//
Rectangle.drwa()
Square.draw()
2.抽象工厂模式
创建抽象类型的工厂类,然后再用抽象类的工厂类创建具体实例
1.如上,shape抽象类及相关Rectangle、Square实例:
package 设计模式.抽象工厂模式;
public interface Shape {
void draw();
}
package 设计模式.抽象工厂模式;
public class Rectangle implements Shape {
// Rectangle具体实现shape的抽象
@Override
public void draw() {
// 具体实现
System.out.println("Rectangle.drwa()");
}
}
package 设计模式.抽象工厂模式;
public class Square implements Shape {
@Override
public void draw() {
System.out.println("Square.draw()");
}
}
2.新的颜色抽象类,及具体实现类
package 设计模式.抽象工厂模式;
public interface Color {
void fill();
}
package 设计模式.抽象工厂模式;
public class Blue implements Color {
@Override
public void fill() {
System.out.println("Inside Blue::fill() method.");
}
}
package 设计模式.抽象工厂模式;
public class Green implements Color {
@Override
public void fill() {
System.out.println("Inside Green::fill() method.");
}
}
3.创建抽象工厂的获取抽象类
package 设计模式.抽象工厂模式;
public abstract class AbstractFactory {
public abstract Color getColor(String color);
public abstract Shape getShape(String shape);
}
4.创建shape工厂,及color工厂
package 设计模式.抽象工厂模式;
public class ShapeFactory extends AbstractFactory {
@Override
public Color getColor(String color) {
return null;
}
@Override
public Shape getShape(String shapeType) {
if(shapeType == null){
return null;
}
if(shapeType.equalsIgnoreCase("RECTANGLE")){
return new Rectangle();
} else if(shapeType.equalsIgnoreCase("SQUARE")){
return new Square();
}
return null;
}
}
package 设计模式.抽象工厂模式;
public class ColorFactory extends AbstractFactory {
@Override
public Color getColor(String color) {
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;
}
@Override
public Shape getShape(String shape) {
return null;
}
}
5.创建抽象工厂的生成器,给定文字返回对应的抽象工厂
package 设计模式.抽象工厂模式;
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;
}
}
6.main
package 设计模式.抽象工厂模式;
public class AbstractFactoryPatternDemo {
public static void main(String[] args) {
// 抽象工厂类获取抽象工厂实例
AbstractFactory shape_fa = FactoryProducer.getFactory("shape");
// shape抽象类创建RECTANGLE类实例
Shape shape = shape_fa.getShape("RECTANGLE");
// 得到RECTANGLE实例,进行使用
shape.draw();
// 创建color工厂
AbstractFactory colorFactory = FactoryProducer.getFactory("COLOR");
// color工厂创建具体颜色类
Color color1 = colorFactory.getColor("RED");
color1.fill();
}
}
3.单例模式
1.对象
单例模式的实现有多种方式
1)懒汉式,线程不安全
public class Singleton {
private static Singleton instance;
private Singleton (){}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
2)懒汉式,线程安全
public class Singleton {
private static Singleton instance;
private Singleton (){}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
3)双检锁/双重校验锁(DCL,即 double-checked locking)
采用双锁机制,安全且在多线程情况下能保持高性能
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;
}
}
4)登记式/静态内部类
这种方式能达到双检锁方式一样的功效,但实现更简单。
public class Singleton {
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton (){}
public static final Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
一般情况下,不建议使用第 1 种和第 2 种懒汉方式,建议使用第 3 种饿汉方式。只有在要明确实现 lazy loading 效果时,才会使用登记方式
2.main
package 设计模式.单例模式;
public class SingletonPatternDemo {
public static void main(String[] args) {
//不合法的构造函数
//编译时错误:构造函数 SingleObject() 是不可见的
//SingleObject object = new SingleObject();
//获取唯一可用的对象
// 不安全
SingleObject object = SingleObject.getInstance();
// 安全
Singleton object1 = Singleton.getInstance();
//显示消息
object.showMessage();
object1.showMessage();
}
}
4.建造者模式
1.创建一个表示食物条目和食物包装的接口。
package 设计模式.建造者模式;
public interface Item {
public String name();
public Packing packing();
public float price();
}
package 设计模式.建造者模式;
public interface Packing {
public String pack();
}
2.实现 Packing 接口的实体,包装纸、瓶子打包
package 设计模式.建造者模式;
public class Wrapper implements Packing {
@Override
public String pack() {
return "Wrapper";
}
}
package 设计模式.建造者模式;
public class Bottle implements Packing {
@Override
public String pack() {
return "Bottle";
}
}
3.创建汉堡、可乐饮料类型的抽象物品
package 设计模式.建造者模式;
public abstract class Burger implements Item {
@Override
public Packing packing() {
return new Wrapper();
}
@Override
public abstract float price();
}
package 设计模式.建造者模式;
public abstract class ColdDrink implements Item {
@Override
public Packing packing() {
return new Bottle();
}
@Override
public abstract float price();
}
4.创建汉堡实体,素食、鸡肉汉堡
package 设计模式.建造者模式;
public class VegBurger extends Burger {
@Override
public float price() {
return 25.0f;
}
@Override
public String name() {
return "Veg Burger";
}
}
package 设计模式.建造者模式;
public class ChickenBurger extends Burger {
@Override
public float price() {
return 50.5f;
}
@Override
public String name() {
return "Chicken Burger";
}
}
5.创建可乐饮料类型实体,可口可乐、百事可乐
package 设计模式.建造者模式;
public class Coke extends ColdDrink {
@Override
public float price() {
return 30.0f;
}
@Override
public String name() {
return "Coke";
}
}
package 设计模式.建造者模式;
public class Pepsi extends ColdDrink {
@Override
public float price() {
return 35.0f;
}
@Override
public String name() {
return "Pepsi";
}
}
6.定义套餐类
package 设计模式.建造者模式;
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());
}
}
}
7.定义套餐创建类builder,创建了两个不同套餐
package 设计模式.建造者模式;
public class MealBuilder {
// 套餐1
public Meal prepareVegMeal() {
Meal meal = new Meal();
meal.addItem(new VegBurger());
meal.addItem(new Coke());
return meal;
}
//套餐2
public Meal prepareNonVegMeal() {
Meal meal = new Meal();
meal.addItem(new ChickenBurger());
meal.addItem(new Pepsi());
return meal;
}
}
8.main
package 设计模式.建造者模式;
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());
}
}
//
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
5.原型模式
通过继承Cloneable,实现clone功能,可以对对象进行浅拷贝。
package 原型模式;
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;
}
}
6.适配器模式
将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。