java 策略模式是什么?
策略模式定义了一组算法,并将每一个算法封装起来,让它们可以相互替换。 策略模式让算法的变化独立于使用算法的客户。策略类超过四个,可以考虑混合模式。
java 策略模式的组成部分有哪些?
策略模式的组成部分:
- 抽象策略角色:策略类,通常由一个接口或者抽象类实现。
- 具体策略角色:包装了相关的算法和行为。
- 环境角色:持有一个策略类引用,给客户端调用。
java 策略模式的缺点是什么?
java 策略模式的缺点:
- 客户端自行决定用哪个策略类。只适用于客户端知道所有的算法或行为的情况。
- 造成很多的策略类。要用享元模式来减少对象的数量。
实例如下:
interface Strategy{ int count( int num1, int num2 ); } // 策略接口
class AdditionStrategy implements Strategy{ // 加法策略
public int count( int num1, int num2 ){
return num1 + num2;
}
}
class SubtractionStrategy implements Strategy{ // 减法策略
public int count( int num1, int num2 ){
return num1 - num2;
}
}
class Counter{ // 计算器
private Strategy strategy; // 策略引用类型变量,用于多态地调用算法
public Counter( Strategy strategy ){ // 构造器创建对象传入策略对象
this.strategy = strategy;
}
public int count( int num1, int num2 ){ // 同名目的方法
return strategy.count( num1, num2 ); // 多态地调用方法执行算法。
}
}
public class Test0521{ // 测试类
public static void main( String[] args ){
int result;
result = new Counter( new AdditionStrategy() ).count( 50, 20 );
System.out.println( " 50 + 20 = " + result );
result = new Counter( new SubtractionStrategy() ).count( 50, 20 );
System.out.println( " 50 - 20 = " + result );
}
}
--------------------------------------------------------------------------------
E:\java>java Test0521
50 + 20 = 70
50 - 20 = 30
interface Strategy{ int count( int num1, int num2 ); }
class AdditionStrategy implements Strategy{
public int count( int num1, int num2 ){
return num1 + num2;
}
}
class SubtractionStrategy implements Strategy{
public int count( int num1, int num2 ){
return num1 - num2;
}
}
class Counter{
static void count( int num1, int num2, Strategy s ){ // 策略引用当做参数传入实现多态调用
if( s.getClass().getSimpleName().equals( "AdditionStrategy" ) )
System.out.format( "%d + %d = %d\n", num1, num2, s.count( num1, num2) );
else System.out.format( "%d - %d = %d\n", num1, num2, s.count( num1, num2) );
}
}
public class Test0524{
public static void main( String[] args ){
Counter.count( 50, 20, new AdditionStrategy() );
Counter.count( 50, 20, new SubtractionStrategy() );
}
}
-----------------------------------------------------------------------------------------------------
E:\java>java Test0524
50 + 20 = 70
50 - 20 = 30
/*
策略设计模式:创建一个方法,它能够根据策略的不同而做出不同的行为。这类方法包含所要执行的算法中固定不变的部分,而策略包含变化
的部分。策略就是传递进去的参数对象,它包含要执行的代码。
*/
// 普通版本
import java.util.*;
class Processor{
String name(){ return getClass().getSimpleName(); }
Object process( Object input ){ return input; }
}
class Upcase extends Processor{
String process( Object input ){ return (( String ) input ).toUpperCase(); }
}
class Downcase extends Processor{
String process( Object input ){ return (( String ) input ).toLowerCase(); }
}
class Splitter extends Processor{
String process( Object input ){ return Arrays.toString((( String ) input ).split( "" )); }
}
class Apply{
static void process( Processor p, Object s ){ // Processor对象就是一个策略。
System.out.println( "Using Processor " + p.name() );
System.out.println( p.process( s ) );
}
static String s = "Disagreement with beliefs is by definition incorrect" ;
public static void main( String[] args ){
process( new Upcase(), s );
process( new Downcase(), s );
process( new Splitter(), s );
}
}
public class Test0521{
public static void main( String[] args ){
Apply.main( args );
}
}
----------------------------------------------------------------------------
E:\java>java Test0521
Using Processor Upcase
DISAGREEMENT WITH BELIEFS IS BY DEFINITION INCORRECT
Using Processor Downcase
disagreement with beliefs is by definition incorrect
Using Processor Splitter
[Disagreement, with, beliefs, is, by, definition, incorrect]
// 修改版本
import java.util.*;
// 有了抽象类为何还要用接口?为何要优先接口,非常明确的地步才用抽象类?
// 因为为了适应变化啊。不为别的,就为了以后可以用上接口的多继承。
interface Processor{ // 处理器
String name(); // 名称方法
Object process( Object input ); // 处理方法
}
abstract class StringProcessor implements Processor{ // 字符串处理器
public String name(){ return getClass().getSimpleName(); } // 具体方法
public abstract String process( Object input ); // 抽象方法
// static变量,方便传入参数
static String s = "Disagreement with beliefs is by definition incorrect" ;
public static void main( String[] args ){ // 测试
Apply.process( new Upcase(), s );
Apply.process( new Downcase(), s );
Apply.process( new Splitter(), s );
}
}
class Upcase extends StringProcessor{ // 大写
public String process( Object input ){
return (( String ) input ).toUpperCase();
}
}
class Downcase extends StringProcessor{ // 小写
public String process( Object input ){
return (( String ) input ).toLowerCase();
}
}
class Splitter extends StringProcessor{ // 分离器
public String process( Object input ){
return Arrays.toString((( String ) input ).split( " " ));
}
}
class Apply{ // 应用
static void process( Processor p, Object s ){ // 策略引用当做参数传入方法,调用方法返回String,方便输出
System.out.println( "Using Processor " + p.name() );
System.out.println( p.process( s ) );
}
}
public class Test0521{ // 测试
public static void main( String[] args ){
StringProcessor.main( args );
}
}
------------------------------------------------------------------------
E:\java>java Test0521
Using Processor Upcase
DISAGREEMENT WITH BELIEFS IS BY DEFINITION INCORRECT
Using Processor Downcase
disagreement with beliefs is by definition incorrect
Using Processor Splitter
[Disagreement, with, beliefs, is, by, definition, incorrect]
// 模拟鸭子游戏
abstract class Duck{ // 鸭子类
// 为行为接口类型声明两个引用变量,所有鸭子子类都继承它们。
FlyBehavior flyBehavior; // 封装飞行行为
QuackBehavior quackBehavior; // 封装呱呱叫行为
public Duck(){
}
public void setFlyBehavior( FlyBehavior fb ){ // 动态设定飞行行为
flyBehavior = fb;
}
public void setQuackBehavior( QuackBehavior qb ){ // 动态设定呱呱叫行为
quackBehavior = qb;
}
public void performFly(){
flyBehavior.fly(); // 委托给flyBehavior引用的对象
}
public void performQuack(){
quackBehavior.quack(); // 委托给quackBehavior引用的对象
}
public void swim(){
System.out.println( "All ducks float, even decoys!" );
}
abstract void display(); // 外观
}
interface FlyBehavior{ // 所有飞行行为类必须实现的接口
public void fly();
}
class FlyNoWay implements FlyBehavior{ // 飞行行为的实现:不会飞的鸭子
public void fly(){
System.out.println( "I can't fly" );
}
}
class FlyWithWings implements FlyBehavior{ // 飞行行为的实现:会飞的鸭子
public void fly(){
System.out.println( "I'm flying!!" );
}
}
class FlyRocketPowered implements FlyBehavior{ // 飞行行为的实现:火箭动力的飞行
public void fly(){
System.out.println( "I'm flying with a rocket" );
}
}
interface QuackBehavior{ // 所有呱呱叫行为类必须实现的接口
public void quack();
}
class FakeQuack implements QuackBehavior{ // 飞行行为的实现:假叫
public void quack(){
System.out.println( "FakeQuack" );
}
}
class Quack implements QuackBehavior{ // 飞行行为的实现:呱呱叫
public void quack(){
System.out.println( "Quack" );
}
}
class Squeak implements QuackBehavior{ // 飞行行为的实现:吱吱叫
public void quack(){
System.out.println( "Squeak" );
}
}
class MuteQuack implements QuackBehavior{ // 飞行行为的实现:不叫
public void quack(){
System.out.println( "<< Silence >>" );
}
}
class MallardDuck extends Duck{ // 绿头鸭
public MallardDuck(){
quackBehavior = new Quack();
flyBehavior = new FlyWithWings();
}
public void display(){
System.out.println( "I'm a real Mallard duck" );
}
}
class RubberDuck extends Duck{ // 橡皮鸭
public RubberDuck(){
flyBehavior = new FlyNoWay();
// quackBehavior = () -> System.out.println( "Squeak" );
quackBehavior = new Squeak();
}
public RubberDuck( FlyBehavior flyBehavior, QuackBehavior quackBehavior ){
this.flyBehavior = flyBehavior;
this.quackBehavior = quackBehavior;
}
public void display(){
System.out.println( "I'm a rubber duckie" );
}
}
class DecoyDuck extends Duck{ // 诱饵鸭
public DecoyDuck(){
setFlyBehavior( new FlyNoWay() );
setQuackBehavior( new MuteQuack() );
}
public void display(){
System.out.println( "I'm a duck Decoy" );
}
}
class ModelDuck extends Duck{ // 模型鸭
public ModelDuck(){
flyBehavior = new FlyNoWay();
quackBehavior = new Quack();
}
public void display(){
System.out.println( "I'm a model duck" );
}
}
class RedHeadDuck extends Duck{ // 红头鸭
public RedHeadDuck(){
flyBehavior = new FlyWithWings();
quackBehavior = new Quack();
}
public void display(){
System.out.println( "I'm a real Red Headed duck" );
}
}
class MiniDuckSimulator{ // 测试类
public static void main( String[] args ){
MallardDuck mallard = new MallardDuck();
// FlyBehavior cantFly = () -> System.out.println( "I can't fly" );
// QuackBehavior squeak = () -> System.out.println( "Squeak" );
FlyBehavior cantFly = new FlyNoWay();
QuackBehavior squeak = new Squeak();
RubberDuck rubberDuckie = new RubberDuck( cantFly, squeak );
DecoyDuck decoy = new DecoyDuck();
Duck model = new ModelDuck();
mallard.performQuack();
rubberDuckie.performQuack();
decoy.performQuack();
model.performFly();
model.setFlyBehavior( new FlyRocketPowered() );
model.performFly();
}
}
class MiniDuckSimulator1{ // 测试类
public static void main( String[] args ){
Duck mallard = new MallardDuck();
mallard.performQuack();
mallard.performFly();
Duck model = new ModelDuck();
model.performFly();
model.setFlyBehavior( new FlyRocketPowered() );
model.performFly();
}
}
public class Test0521{
public static void main( String[] args ){
MiniDuckSimulator.main( args );
MiniDuckSimulator1.main( args );
}
}
--------------------------------------------------------------------
E:\java>java Test0521
Quack
Squeak
<< Silence >>
I can't fly
I'm flying with a rocket
Quack
I'm flying!!
I can't fly
I'm flying with a rocket
import java.util.Scanner;
abstract class PhoneCameraApp { // 手机摄像头应用程序
ShareStrategy shareStrategy;
public void setShareStrategy( ShareStrategy shareStrategy ) {
this.shareStrategy = shareStrategy;
}
public void share() {
shareStrategy.share();
}
public void take() {
System.out.println("Taking the photo");
}
public void save() {
System.out.println("Saving the photo");
}
public abstract void edit();
}
class BasicCameraApp extends PhoneCameraApp { // 基本摄像头应用程序
public void edit() {
System.out.println( "Basic editing features" );
}
}
class CameraPlusApp extends PhoneCameraApp { // 优秀的摄像头应用程序
public void edit() {
System.out.println("Extra snazzy photo editing features");
}
}
@FunctionalInterface
interface ShareStrategy { // 分享策略
public void share();
}
class Social implements ShareStrategy { // 社交网络媒介
public void share() {
System.out.println("I'm posting the photo on social media");
}
}
class Txt implements ShareStrategy { // 手机发送
public void share() {
System.out.println("I'm txting the photo");
}
}
class Email implements ShareStrategy { // 用电邮发送
public void share() {
System.out.println("I'm emailing the photo");
}
}
class PhotoWithPhone { // 手机拍摄
public static void main( String[] args ) {
PhoneCameraApp cameraApp = new BasicCameraApp();
String share = getSharing();
switch ( share ) {
case( "t" ): cameraApp.setShareStrategy( new Txt() ); break;
case( "e" ): cameraApp.setShareStrategy( new Email() ); break;
case( "s" ): cameraApp.setShareStrategy( new Social() ); break;
default: cameraApp.setShareStrategy( new Txt() );
}
cameraApp.take();
cameraApp.edit();
cameraApp.save();
cameraApp.share();
}
public static String getSharing() {
Scanner scanner = new Scanner( System.in );
System.out.println( "Share with txt (t), email (e), or social media (s)?" );
String appName = scanner.next();
scanner.close();
return appName;
}
}