设计模式总概念之创建型设计模式详解
设计模式分类:
创建型设计模式:对象怎么来的,主要用于创建对象。
结构型设计模式:对象和谁有关系,主要用于描述对象之间的关系。
行为型设计模式:对象和对象在干嘛,主要用于描述对象的动作。
J2EE型设计模式:对象联合起来要干嘛,主要用于描述对象联合的目的。
设计模式的六大原则:
开闭原则:对扩展开放,对修改关闭。
里氏代换原则:任何基类可以出现的地方,子类一定可以出现
依赖倒转原则:针对接口编程,依赖于抽象而不依赖于具体类
接口隔离原则:使用多个隔离的接口好过于使用一个接口,降低类之间的耦合性
迪米特法则:实体之间尽少相互作用,系统功能模块尽量独立;
合成复用原则:尽量使用聚合和组合,而不是继承;
创建型设计模式:
工厂模式 ; 抽象工厂模式 ; 单例模式 ; 建造者模式 ; 原型模式
工厂模式:
创建一个接口,创建多个实现接口的实体类
创建一个工厂类,通过工厂创建对象。
定义Animal接口: Animal.java
public interface Animal
{
void eat();
}
定义接口实现类1 Dog.java
public class Dog implements Animal
{
@Override
public void eat()
{
System.out.println("eat meat ~");
}
}
定义接口实现类2 Cat.java
public class Cat implements Animal { @Override public void eat() { System.out.println("eat fish ~"); } }
定义工厂类 AnimalFactory.java
public class AnimalFactory { public AnimalFactory getAnimalFactory(String animalName)
{
if(animalName.equalsIgnoreCase("DOG"))
{
return new Dog();
}
else if(animalName.equalsIgnoreCase("Cat"))
{
return new Cat();
}
else
{
return null;
}
}
}
通过工厂类创建对象类 AnimalFactoryTest.java
public class AnimalFactoryTest { public static void main(String[] args) {
//创建工厂对象 AnimalFactory animalFactory = new AnimalFactory();
//通过工厂对象创建对应的接口实现类对象,而后调用类实现的方法
Dog dog = animalFactory.getAnimalFactory("dog");
dog.eat();
Cat cat= animalFactory.getAnimalFactory("cat");
cat.eat();
} }
输出结果为:
eat meat ~
eat fish ~
抽象工厂模式:
创建多个接口,创建对应每个接口的多个实现类
创建一个抽象工厂类 里面包含得到每个接口类型变量的抽象方法
创建多个工厂继承抽象工厂,实现对应的方法,不对应的采用空实现
与工厂模式的不同之处: 接口对应的工厂类继承抽象工厂,工厂生成器生成工厂,再通过工厂创建对象
定义Shape接口: Shape.java
public interface Shape { void draw(); }
定义Circle实现SHape接口类: Circle.java
public class Circle implements Shape { public void draw()
{ System.out.println("draw--circle"); } }
定义Square实现SHape接口类: Square.java
public class Square implements Shape
{
public void draw()
{ System.out.println("draw--square"); } }
定义Color接口: Color.java
public interface Color
{
void fill();
}
定义Red实现Color接口类: Red.java
public class Red implements Color
{
public void fill()
{ System.out.println("fill--Red"); } }
定义Green实现Color接口类: Green.java
public class Green implements Color
{
public void fill()
{ System.out.println("fill--green"); } }
创建获取接口的抽象工厂: AbstractFactory.java
public abstract class AbstractFactory { abstract Shape getShape(String shape); abstract Color getColor(String color); }
创建Shape接口对应的工厂,并且继承抽象工厂: ShapeFactory.java
public class ShapeFactory extends AbstractFactory { @Override public Shape getShape(String shape) { if(shape.equals("Circle"){ return new Circle(); }else if(shape.equals("Square")){ return new Square(); }else{ return null; } }
@Override
public Color getColor(String color) {
return null;
}
}
创建Color接口对应的工厂,并且继承抽象工厂:ColorFactory.java
public class ColorFactory extends AbstractFactory
{
@Override
public Color getColor(String color) { if(color.equals("red"){ return new Red(); }else if(color.equals("green")){ return new Green(); }else{ return null; } }
@Override
public Shape getShape(String shape) { return null; }
}
创建工厂生成器类用来得到相应的接口对应的工厂: BuilderFactory.java
public class BuilderFactory { public static AbstractFactory getFactory(String factory) { if(factory.equals("ShapeFactory")){ return new ShapeFactory(); }else if(factory.equals("ColorFactory")){ return new ColorFactory(); }else{ return null; } } }
测试类:AbstractFactoryTest.java
public class AbstractFactoryTest {
public static void main(String[] args){
//得到Shape接口对应的工厂
AbstractFactory shapeFactory = BuilderFactory.getFactory("ShapeFactory");
//通过工厂创建Circle对象
Circle circle = shapeFactory.getShape("Circle");
circle.draw();
//通过工厂创建Square对象
Square square= shapeFactory.getShape("Square");
square.draw();
//得到Color接口对应的工厂
AbstractFactory colorFactory = BuilderFactory.getFactory("ColorFactory");
//通过工厂创建Red对象
Red red= colorFactory .getColor("red");
red.fill();
//通过工厂创建Green对象
Green green= colorFactory .getColor("green");
green.fill();
}
}
输出结果为:
draw--circle
draw--square
fill--red
fill--green
单例模式:
保证只有一个对象的存在
构造方法私有化
饱汉式单例与饿汉式单例
包汉式单例 Singleton.java
特点:
创建静态全局变量
定义私有构造方法
创建静态方法获取对象,先判断对象是否存在,存在直接返回对象,不存在通过new创建对象再返回。
public class Singleton { private static Singleton instance; private Singleton (){}
//synchronized存在的时候表示这是线程安全的,不存在的时候表示线程不安全 public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; }
public void showMessage(){ System.out.println("Hello World!"); }
}
饿汉式单例:Singleton.java
特点:
定义私有的构造方法
直接定义静态全局变量并且创建对象为其赋值,
创建静态方法获取时直接返回对象。
public class Singleton { private static Singleton instance = new Singleton(); private Singleton (){} public static Singleton getInstance() { return instance; }
public void showMessage(){ System.out.println("Hello World!"); }
}
测试类: SingletonTest.java
public class SingletonTest{ public static void main(String[] args) { //不合法的构造函数 //编译时错误:构造函数 Singleton () 是不可见的 //Singleton object = new Singleton (); //获取唯一可用的对象 Singleton object = Singleton .getInstance(); //显示消息 object.showMessage(); } }
输出结果:
Hello world!
知识点:抽象类实现接口可以不实现的接口的所有方法,未实现的接口方法可以交给抽象类的子类去实现。
建造者模式:
使用多个简单的对象一步一步构建成一个复杂的对象。
一个 Builder 类会一步一步构造最终的对象。该 Builder 类是独立于其他对象的。
步骤 1
创建一个表示食物条目和食物包装的接口。
Item.java
public interface Item { public String name(); public Packing packing(); public float price(); }
Packing.java
public interface Packing { public String pack(); }
步骤 2
创建实现 Packing 接口的实体类。
Wrapper.java
public class Wrapper implements Packing { @Override public String pack() { return "Wrapper"; } }
Bottle.java
public class Bottle implements Packing { @Override public String pack() { return "Bottle"; } }
步骤 3
创建实现 Item 接口的抽象类,该类提供了默认的功能。(这里只实现一个方法,其余两个交给子类去实现)
Burger.java
public abstract class Burger implements Item { @Override public Packing packing() { return new Wrapper(); } @Override public abstract float price(); }
ColdDrink.java
public abstract class ColdDrink implements Item { @Override public Packing packing() { return new Bottle(); } @Override public abstract float price(); }
步骤 4
创建扩展了 Burger 和 ColdDrink 的实体类。
VegBurger.java
public class VegBurger extends Burger { @Override public float price() { return 25.0f; } @Override public String name() { return "Veg Burger"; } }
ChickenBurger.java
public class ChickenBurger extends Burger { @Override public float price() { return 50.5f; } @Override public String name() { return "Chicken Burger"; } }
Coke.java
public class Coke extends ColdDrink { @Override public float price() { return 30.0f; } @Override public String name() { return "Coke"; } }
Pepsi.java
public class Pepsi extends ColdDrink { @Override public float price() { return 35.0f; } @Override public String name() { return "Pepsi"; } }
步骤 5
创建一个 Meal 类,带有上面定义的 Item 对象。
Meal.java
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 对象。
MealBuilder.java
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)。
BuilderPatternDemo.java
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