当前:原型模式(使用价值方面说明)
需求:坦克大战
创建两种坦克
坦克类型 | 射程 | 速度 |
b70 | 70米 | 时/70公里 |
b50 | 50米 | 时/70公里 |
类图
需求设计
我们假设坦克有两种,
一种数速度型坦克
一种是构造型坦克
速度型坦克的改变,无非就是改变数据,70,50,60
而发射行坦克无非改变的就是设计的距离 50 100 105
该实例通过,通过改变参数创建不同类型的坦克。
而不是通过类,如果分类的对象过多了,可以考虑通过该方式来消减类。
这里面其实用了桥接的思想。
这里改变的规格就相当于桥接对象。
类本身承担一个维度的变化,而这个规格的改变又承担了一个规格的变化。
坦克类型决定了坦克的基本功能,而规格的变化决定了他的性能。
模式价值:就是把类型迁移到参数里。
本来是需要分类的,但是用一个成员变量承载了这个变化,通过给一类对象设计不同的参数产生实际类别的对象。
优点:避免类型数量的增加。
适用情况:一个类对外接口稳定,但是在实际应用中,需要衍生很多多的子类。
子类的数量多到我们不愿意去接受,比如20个50个等等。
这时候我们怎么办,我们要降低类的数量。
什么降低呢,当然从问题入手。
看什么因素导致了这么多的类,这个因素一定是一个或几个成员变量。
那么我们把这些成员拿出来,把这些成员提供接口。
用设置这些成员的方法来来转换类的衍生数量。
这就是原型模式的基本创建过程。
这里有一个问题需要解释一下,什么叫稳定的接口呢。
举例例子吧
A{
int mA;
B mB;
public:
fun(int a)
fun2(int b)
private fun3();
}
mA的名称变化了,接口是否稳定。当然稳定。
mB的fun3变化了,接口是否稳定。当然稳定。
fun的名称变化了,接口不稳定了。
fun2 的参数编程两个了,接口不稳定了。
这样,你应该明白什么叫接口稳定了吧。
说白了,就是对外提供的函数没有变化。
代码
interface ITank{
void setmName(String mName);
ITank clones();
void exe();
void setmSpecification(int mSpecification);
}
abstract class Tank implements ITank{
int mSpecification;
String mName;
String mType;
protected void setmType(String mType) {
this.mType = mType;
}
public void setmName(String mName) {
this.mName = mName;
}
public void setmSpecification(int mSpecification) {
this.mSpecification = mSpecification;
}
}
class ShotTank extends Tank{
public ShotTank() {
mType = "射击";
}
public ITank clones() {
Tank t = new ShotTank();
t.setmType(mType);
return t;
}
public void exe() {
System.out.println("型坦克型号:"+mType+mName);
System.out.println("射击距离:"+mSpecification+"米");
}
}
class RunTank extends Tank{
public RunTank() {
mType = "奔跑";
}
public ITank clones() {
Tank t = new ShotTank();
t.setmType(mType);
return t;
}
public void exe() {
System.out.println("坦克型号:"+mType+mName);
System.out.println("速度:"+mSpecification+"公里");
}
}
class ShotFactory{
public ITank createS70(ITank shotPrototype) {
ITank shot = shotPrototype.clones();
shot.setmName("S70");
shot.setmSpecification(70);
return shot;
}
public ITank createS50(ITank shotPrototype) {
ITank shot = shotPrototype.clones();
shot.setmName("S51");
shot.setmSpecification(50);
return shot;
}
public ITank createS43(ITank shotPrototype) {
ITank shot = shotPrototype.clones();
shot.setmName("S43");
shot.setmSpecification(40);
return shot;
}
}
class RunFactory{
public ITank createR80(ITank runPrototype) {
ITank run = runPrototype.clones();
run.setmName("R80");
run.setmSpecification(70);
return run;
}
public ITank createR999(ITank runPrototype) {
ITank run = runPrototype.clones();
run.setmName("R999");
run.setmSpecification(999);
return run;
}
public ITank createR47(ITank runPrototype) {
ITank run = runPrototype.clones();
run.setmName("R47");
run.setmSpecification(440);
return run;
}
}
public class Client {
public static void main(String[] args) {
System.out.println("Prototype 演示\n");
ITank shotPrototype = new ShotTank();
ITank runPrototype = new RunTank();
ShotFactory sf = new ShotFactory();
sf.createS43(shotPrototype).exe();
sf.createS70(shotPrototype).exe();
sf.createS50(shotPrototype).exe();
System.out.println("");
RunFactory rf = new RunFactory();
rf.createR80(runPrototype).exe();
rf.createR999(runPrototype).exe();
rf.createR47(runPrototype).exe();
}
}
运行结果