1. 程式人生 > >設計模式簡單小例子(二)結構型模式

設計模式簡單小例子(二)結構型模式

簡單小例子

原始碼已經上傳到了GitHub.

https://github.com/tanglonghui/DesignPatterns

設計模式簡單小例子(一) 建立型模式:

https://blog.csdn.net/qq_40687864/article/details/81064917

設計模式簡單小例子(三)行為型模式:

https://blog.csdn.net/qq_40687864/article/details/82148887

一、介面卡模式

package StructuralPatterns.Adapter;



/*
 * 介面卡模式(有時候也稱包裝樣式或者包裝)將一個類的介面適配成使用者所期待的。
 * 一個適配允許通常因為介面不相容而不能在一起工作的類工作在一起,
 * 做法是將類自己的介面包裹在一個已存在的類中。
 */
/*
 * 包含角色:
 * Target(目標抽象類)
 * Adapter(介面卡類)
 * Adaptee(適配者類)
 * 簡單說:
 * 使Target通過Adapter(介面卡類)適配後可以自己類中使用 Adaptee(適配者類)中的方法
 * 我們假設target儲存Stirng型別的資料的類;
 * 而Adaptee是用int儲存
 */
class Test {
	public static void main(String[] args) {
		//
		Adaptee adaptee=new Adaptee();
		adaptee.msg=11;
		Target target=new Adapter(adaptee);
		target.show();
		System.out.println(""+target.msg.getClass());
		
	}
	

}
abstract class Target{
	 String msg;
	 void show() {
		 System.out.println("我展示的是:"+msg);
		 
	}
}
class Adaptee{
	int msg;
	void show() {
		System.out.println("我展示的是:"+msg);
	}
	
}
class Adapter extends  Target{
	Adaptee adaptee;
	public Adapter(Adaptee adaptee) {
		// TODO Auto-generated constructor stub
		this.adaptee=adaptee;
	}
	
	@Override
	void show() {
		// TODO Auto-generated method stub
		//介面卡做操作將String型別資料變成 int 型別
		super.msg=String.valueOf(adaptee.msg);
		super.show();
	}
	
}

二、橋接模式

package StructuralPatterns.Bridge;
/*
 * 橋接模式是將抽象部分與它的實現部分分離,使它們都可以獨立地變化。
 * 它是一種物件結構型模式,又稱為柄體(Handle and Body)模式或介面(Interface)模式。
 */
/*
 * 包含角色:
 * Abstraction(抽象類) 抽象   Color
 * RefinedAbstraction(擴充抽象類) 例項   Red Yellow Green
 * Implementor(實現類介面)  抽象    Shape
 * ConcreteImplementor(具體實現類 ) 例項  A B C
 * 
 * 我們用形狀和顏色來做個例子 形狀我就假設ABC了
 */
public class Test {
	public static void main(String[] args) {
		Shape shape;
		shape=new A();
		shape.draw(new Red());
		shape.draw(new Green());
	}

}
interface Color{
	<T extends Shape> void paint(T t);
}
class Red implements Color{
   private String msg="red";

@Override
	public <T extends Shape> void paint(T t) {
		// TODO Auto-generated method stub
			System.out.println("形狀:"+t.getShape()+"  顏色:"+msg);
	}
}
class Green implements Color{
	   private String msg="green";

	@Override
		public <T extends Shape> void paint(T t) {
			// TODO Auto-generated method stub
				System.out.println("形狀:"+t.getShape()+"  顏色:"+msg);
		}
	}


interface  Shape{
	String getShape();
	void draw(Color color);
	
}
class A implements Shape{
	private Color color;
	private String shape="A";
	@Override
	public String getShape() {
		// TODO Auto-generated method stub
		return shape;
	}

	@Override
	public void draw(Color color) {
		// TODO Auto-generated method stub
		this.color=color;
		color.paint(this);
	}
	
}
class B implements Shape{
	private Color color;
	private String shape="A";
	@Override
	public String getShape() {
		// TODO Auto-generated method stub
		return shape;
	}

	@Override
	public void draw(Color color) {
		// TODO Auto-generated method stub
		this.color=color;
		color.paint(this);
	}
	
}



三、組合模式

package StructuralPatterns.Composite;

import java.util.ArrayList;

/*
 * 組合模式,將物件組合成樹形結構以表示“部分-整體”的層次結構,
 * 組合模式使得使用者對單個物件和組合物件的使用具有一致性。
 * 掌握組合模式的重點是要理解清楚 “部分/整體” 還有 ”單個物件“ 與 "組合物件" 的含義。
 */
/*
 * 包含角色:
 * Component(抽象構件)
 * Leaf(葉子構件)
 * Composite(容器構件)
 */
public class Test {
	public static void main(String[] args) {
		Conposite c1=new Conposite();
		Conposite c2=new Conposite();
		Conposite c3=new Conposite();
		Conposite c4=new Conposite();
		Leaf1 l1=new Leaf1();
		Leaf2 l2=new Leaf2();
		Leaf1 l3=new Leaf1();
		Leaf1 l4=new Leaf1();
		c1.add(c2);
		c1.add(c4);
		c1.add(l3);
		c2.add(c3);
		c3.add(l1);
		c3.add(l2);
		c4.add(l4);
		//c1.operation();
		c4.operation();
		
		
	}
}
interface Component{
	void add(Component component);
	void remove(Component component);
	Component getChild(int i);
	void operation();
}
class Conposite implements Component{
	private ArrayList<Component> list=new ArrayList<>();

	@Override
	public void add(Component component) {
		// TODO Auto-generated method stub
		list.add(component);
	}

	@Override
	public void remove(Component component) {
		// TODO Auto-generated method stub
		list.remove(component);
	}

	@Override
	public Component getChild(int i) {
		// TODO Auto-generated method stub
		return list.get(i);
	}

	@Override
	public void operation() {
		// TODO Auto-generated method stub
		for(Object object:list) {
			((Component)object).operation();
		}
	}
	
}
class Leaf1 implements Component{
// 因葉子構件不再包含子構件 ,所以前三個方法應該包含錯誤提示;
	@Override
	public void add(Component component) {
		// TODO Auto-generated method stub
		System.out.println("葉子構件無法新增子構件");
	}

	@Override
	public void remove(Component component) {
		// TODO Auto-generated method stub
		System.out.println("葉子構件無子構件");
	}

	@Override
	public Component getChild(int i) {
		// TODO Auto-generated method stub
		System.out.println("葉子構件無子構件");
		return null;
	}

	@Override
	public void operation() {
		// TODO Auto-generated method stub
		System.out.println("子構件1");
	}
	
}
class Leaf2 implements Component{
	// 因葉子構件不再包含子構件 ,所以前三個方法應該包含錯誤提示;
		@Override
		public void add(Component component) {
			// TODO Auto-generated method stub
			System.out.println("葉子構件無法新增子構件");
		}

		@Override
		public void remove(Component component) {
			// TODO Auto-generated method stub
			System.out.println("葉子構件無子構件");
		}

		@Override
		public Component getChild(int i) {
			// TODO Auto-generated method stub
			System.out.println("葉子構件無子構件");
			return null;
		}

		@Override
		public void operation() {
			// TODO Auto-generated method stub
			System.out.println("子構件2");
		}
		
	}

四、裝飾模式

package StructuralPatterns.Decorator;
/*
 * 裝飾模式指的是在不必改變原類檔案和使用繼承的情況下,
 * 動態地擴充套件一個物件的功能。
 * 它是通過建立一個包裝物件,
 * 也就是裝飾來包裹真實的物件。
 */
/*
 * 包含角色:
 * Component(抽象構件類)
 * ConcreteComponent(具體構件類)
 * Decorator(抽象裝飾類)
 * ConcreteDecorator(具體裝飾類)
 * 簡單說:就是具體裝飾類接收一個具體構件為其增加功能。
 */
public class Test {
public static void main(String[] args) {
	ConcreteComponent cc=new ConcreteComponent();
	ConcreteDecorator1 decorator=new ConcreteDecorator1(cc);
	decorator.functionA();
	decorator.functionB();
	ConcreteDecorator2 c2=new ConcreteDecorator2(decorator);
	c2.functionC();
}
}
interface Component{
	void functionA();
}
class ConcreteComponent implements Component{

	@Override
	public void functionA() {
		// TODO Auto-generated method stub
		System.out.println("我是基礎功能A");
	}
	
}
abstract class Decorator implements Component{
	private Component component;
	public Decorator(Component component) {
		// TODO Auto-generated constructor stub
		this.component=component;
	}
	@Override
	public void functionA() {
		// TODO Auto-generated method stub
		component.functionA();
	}
	
}
class ConcreteDecorator1 extends Decorator{

	public ConcreteDecorator1(Component component) {
		super(component);
		// TODO Auto-generated constructor stub
	}
	void functionB() {
		System.out.println("我是新增功能B");
	}
}
class ConcreteDecorator2 extends Decorator{

	public ConcreteDecorator2(Component component) {
		super(component);
		// TODO Auto-generated constructor stub
	}
	void functionC() {
		System.out.println("我是新增功能C");
	}
}

五、外觀模式

package StructuralPatterns.Facade;
/*
 * 外觀模式(Facade),亦稱“過程模式”。學校課程評價模式之一。
 * 美國教育學者斯泰克1967 年在所著《教育評價的外觀》中提出。
*按照描述和判斷資料來評價課程,關鍵的活動是在課程實施的全過程中進行觀察和蒐集意見,以瞭解人們對課程的不同看法。
*這種模式不限於檢查教學的成果,重視描述和判斷教學過程中各種複雜、動態的現象和事物。
*/
/*
 * 包含角色:
 * Facade(外觀角色)
 * SubSystem(子系統角色)
 * 簡單說:通過Facade 實現 子系統方法的呼叫,類似於總的控制器。
 * 
 */
public class Test {
public static void main(String[] args) {
	Facade facade=new Facade();
	facade.control1();
	facade.control2();
}
}
class Facade{
	SubSystem1 s1=new SubSystem1();
	SubSystem2 s2=new SubSystem2();
	//在這裡可以自定義組合功能鍵
	void control1(){
		s1.on();
		s2.move();
	}
	void control2() {
		s1.off();
		s2.say();
	}
}
class SubSystem1{
	void on() {
		System.out.println("燈開了");
	}
	void off() {
		System.out.println("燈關了");
	}
}
class SubSystem2{
	void move() {
		System.out.println("移動");
	}
	void say() {
		System.out.println("說話");
	}
}

六、享元模式

package StructuralPatterns.Flyweight;


import java.util.HashMap;

/*
 * 享元模式(Flyweight Pattern)主要用於減少建立物件的數量,
 * 以減少記憶體佔用和提高效能。這種型別的設計模式屬於結構型模式,
 * 它提供了減少物件數量從而改善應用所需的物件結構的方式。
 */
/*
 * 包含模式:
 * Flyweight(抽象享元類)
 * ConcreteFlyweight(具體享元類)  單例設計
 * UnsharedConcreteFlyWeight(非共享具體享元類) 非單例設計
 * FlyweightFactory(享元工廠類)ps:可以定義ArrayList等 它是一個享員池
 * ps:這東西這麼看上去這麼像是設計資料庫連線池的東東。
 *   簡單說:享元工廠類中有一個享元池,外部物件可以通過他獲得具體享員類的物件 若享元池有,直接給,若沒有,
 *   新建一個給它並把這個物件加入享元池。
 *   內部狀態,可以相同無所謂
 * 外部狀態,例如分配的埠號不一樣需要提取出來
 */
public class Test {
	public static void main(String[] args) {
		FlyweightFactory factory=new FlyweightFactory();
		System.out.println("路由器最大序列號:"+factory.getLyCount()); 
		System.out.println("交換機最大序列號:"+factory.getJhjCount());
		Flyweight flyweight=factory.getDevice("路由器", 0);
		Flyweight flyweight1=factory.getDevice("路由器", 2);
		Flyweight flyweight2=factory.getDevice("路由器", 10);
		Flyweight flyweight3=factory.getDevice("交換機", 0);
		Port p=new Port();
		p.setPort("1");
		flyweight.Say(p);
		p.setPort("2");
		flyweight1.Say(p);
		System.out.println("路由器最大序列號:"+factory.getLyCount()); 
		System.out.println("交換機最大序列號:"+factory.getJhjCount());
	}
}
interface Flyweight{
	void Say(Port port);
	void move();
}
class Port{
	//提取出來的外部狀態 
	private  String port;
	public String getPort() {
		return port;
	}
	public void setPort(String port) {
		this.port = port;
	}
}
class ConcreteFlyweight1 implements Flyweight{
	private String type;//內部狀態標識碼
	public ConcreteFlyweight1(String type) {
		// TODO Auto-generated constructor stub
		this.type=type;
	}
	void jump() {
		System.out.println("專屬跳躍");
	}

	@Override
	public void Say(Port port) {
		// TODO Auto-generated method stub
		System.out.println("網路連線,路由器type:"+this.type+"  埠port:"+port.getPort());
	}

	@Override
	public void move() {
		// TODO Auto-generated method stub
		System.out.println("通用移動");
	}
	
}
class ConcreteFlyweight2 implements Flyweight{
	private String type;//內部狀態標識碼
	public ConcreteFlyweight2(String type) {
		// TODO Auto-generated constructor stub
		this.type=type;
	}
	void fly() {
		System.out.println("專屬飛翔");
	}

	@Override
	public void Say(Port port) {
		// TODO Auto-generated method stub
		System.out.println("網路連線,路由器type:"+this.type+"  埠port:"+port.getPort());
	}

	@Override
	public void move() {
		// TODO Auto-generated method stub
		System.out.println("通用移動");
	}
	
}
class FlyweightFactory{
	//private ArrayList<Flyweight> device=new ArrayList<>();
	/*
	 * 這裡用map應該舒服一些
	 */
	private HashMap<String, Flyweight> device=new HashMap<>();
	//設定一個指標
	private int lyCount;
	private int jhjCount;
	private Flyweight flyweight;
	public int getLyCount() {
		return lyCount-1;
	}
	public int getJhjCount() {
		return jhjCount-1;
	}
	public FlyweightFactory() {
		// TODO Auto-generated constructor stub
		lyCount=0;
		jhjCount=0;
		ConcreteFlyweight1 c1=new ConcreteFlyweight1("路由器"+lyCount);
		device.put("路由器"+lyCount++, c1);
		ConcreteFlyweight2 c2=new ConcreteFlyweight2("交換機1"+jhjCount);
		device.put("交換機"+jhjCount++, c2);
	}
	public Flyweight getDevice(String type,int count) {
		if((flyweight=device.get(type+count))!=null) {
			System.out.println("已找到,為你返回");
			return flyweight;
		}else {
			switch (type) {
			case "路由器":
				
				flyweight=new ConcreteFlyweight1(type+lyCount);
				device.put("路由器"+lyCount++, flyweight);
				System.out.println("無你指定的裝置已經為你新建,序列號為:"+lyCount);
				return flyweight;
			
			case "交換機":
				flyweight=new ConcreteFlyweight2(type+jhjCount);
				device.put("交換機"+jhjCount++, flyweight);
				System.out.println("無你指定的裝置已經為你新建,序列號為:"+jhjCount);
				return flyweight;

			default:
				return null;
			}
		}
		
	
		
	}
}



七、代理模式

package StructuralPatterns.Proxy;
/*
 * 在代理模式(Proxy Pattern)中,一個類代表另一個類的功能。
 * 這種型別的設計模式屬於結構型模式。
 * 在代理模式中,我們建立具有現有物件的物件,以便向外界提供功能介面。
 */
/*
 * 包含角色:
 * Subject(抽象主題角色)
 * Proxy(代理主題角色)
 * RealSubject(真實主題角色)
 * 簡單說:
 * 通過 Proxy 可以在一定程度上的操作 RealSubject
 */
public class Test {
	public static void main(String[] args) {
		Proxy proxy=new Proxy();
		/*
		 * 正常情況下需要設定許可權的限制Proxy的使用範圍,這裡省略了
		 */
		proxy.move();
		proxy.jump();
	}
}
interface Subject{
	void move();
	void jump();
}
class RealSubject implements Subject{

	@Override
	public void move() {
		// TODO Auto-generated method stub
		System.out.println("移動");
	}

	@Override
	public void jump() {
		// TODO Auto-generated method stub
		System.out.println("跳");
	}
}
class Proxy implements Subject{
	private RealSubject r=new RealSubject();

	@Override
	public void move() {
		// TODO Auto-generated method stub
		r.move();
	}

	@Override
	public void jump() {
		// TODO Auto-generated method stub
		r.jump();
	}
	
}

參考資料:

《設計模式》 劉偉主編

  菜鳥教程 :http://www.runoob.com/

   百度百科