Design Pattern

在專案上的應用

Emily

2021.05.01

About me

  • Emily Wang
  • R&D in 工程顧問公司 
  • Experience in Software Integration(軟體整合)
  • Experience in Web Developement

Agenda

 

  • Introduction to my project
  • System architecture - implemented by Bridge pattern
  • Features requirement 1 - implemented by Visitor pattern
  • Features requirement 2 - implemented by Factory pattern
  • Conclusion

Introduction to My project

鋼結構設計流程自動化

  • 此流程仰賴不同職責的軟體資訊交換
  • 透過軟體提供的API,可輸出不同物件或型態的資料

鋼構設計流程自動化

ref:

https://bit.ly/3e58D9I;    https://bit.ly/3gTVIJt;    https://bit.ly/3aUQglT

結構分析

BIM 整合

接頭檢核

  • 每種功能類型的軟體可以被替換
  • 主要的設計流程不仰賴特定軟體

鋼構設計流程自動化

結構分析

BIM 整合

接頭檢核

software1

software2

...

software_A

software_B

software_C

...

software_x

software_y

software_z

...

ref:

https://bit.ly/3e58D9I;    https://bit.ly/3gTVIJt;    https://bit.ly/3aUQglT;

  • 資料物件定義,達到軟體間之資訊傳遞媒介之一致性

鋼構設計流程自動化

結構分析軟體

BIM 整合軟體

鋼接頭檢核軟體

Data Standardlization

Via API

ref:

https://bit.ly/3e58D9I;    https://bit.ly/3gTVIJt;    https://bit.ly/3aUQglT

  • Mainframe
  • Coordinate
  • Connection

System Architecture Design

Implemented

By Bridge Pattern

應用橋接模式(Bridge pattern),讓系統架構可抽換不同的軟體,主流程不與特定軟體耦合。

應用橋接模式(Bridge pattern),讓系統架構可抽換不同的軟體做整合,主流程不與特定軟體耦合。

應用橋接模式(Bridge pattern),讓系統架構可抽換不同的軟體做整合,主流程不與特定軟體耦合。

Abstraction

public class StructualAnlysisDataLayer : DataLayer
{
        private StrucatualAnalysisConnector _connector;

        public StructualAnlysisDataLayer(StrucatualAnalysisConnector connector)
        {
            _connector = connector;
           
        }

        public List<DesignGroup> GetDesignGroup()
        {
            return _connector.GetDesignGroup();
        }

        public List<SteelFrame> GetSteelFrameGroup(bool confirmSlopeBeam = false)
        {
            return _connector.GetSteelFrames(confirmSlopeBeam);
        }
        
}

Abstraction

public class StructualAnlysisDataLayer : DataLayer
{
        private StrucatualAnalysisConnector _connector;

        public StructualAnlysisDataLayer(StrucatualAnalysisConnector connector)
        {
            _connector = connector;
           
        }

        public List<DesignGroup> GetDesignGroup()
        {
            return _connector.GetDesignGroup();
        }

        public List<SteelFrame> GetSteelFrameGroup(bool confirmSlopeBeam = false)
        {
            return _connector.GetSteelFrames(confirmSlopeBeam);
        }
        
}

Concrete Implementor

using SpecificSoftwareAPI;
using DAL;

public class StaadproConnector : StrucatualAnalysisConnector
    {
        // Identified some properties

        public override List<DesignGroup> GetDesignGroup()
        {
            // implementied via software api
            // ....
            return groups;
        }

        public override List<SteelFrame> GetSteelFrames(bool configuration)
        {
           // implementied via software api
           // ....
            return steelFrames;
        }

        public override void SetLoadInfo()
        {
            // implementied via software api
            // ....
        }
    }
}

Client

using XXXWrapper;
using XXXXXWrapper;
using DAL;

static class Program
    {
        static void Main()
        {
            StrucatualAnalysisConnector AnalysisConnector = new StaadproConnector();
            StructualAnlysisDataLayer AnalysisDataLayer = new StructualAnlysisDataLayer(AnalysisConnector);
            
            List<Member> members = AnalysisDataLayer.GetSteelFrameGroup();
            
            ConnectionDesignConnector teklaConnector = new TeklaConnector();
            ConnectionDesignDataLayer = new ConnectionDesignDataLayer(teklaConnector);
            
            ConnectionDesignDataLayer.CreateMember(members);
        }
    }                
static void Main()
{
     StrucatualAnalysisConnector AnalysisConnector = new StaadproConnector();
     StructualAnlysisDataLayer AnalysisDataLayer = new StructualAnlysisDataLayer(AnalysisConnector);
            
     List<Member> members = AnalysisDataLayer.GetSteelFrameGroup();
            
     ConnectionDesignConnector teklaConnector = new TeklaConnector();
     ConnectionDesignDataLayer = new ConnectionDesignDataLayer(teklaConnector);
            
     ConnectionDesignDataLayer.CreateMember(members);
}               

Feature Implements 1

Implemented

By Visitor Pattern

Feature Implements 1

Intersect
- position(X,Y,Z)
- Members

BCFJoints

CBVBJoints

.

.

.

VXRJoints

Feature Implements 1

Feature Implements 1

  • 一個交集點可能會被判斷成不同種的接合樣式
  • 目標是:給定一組桿件與接頭類型,找到這組桿件可以被assign這個接合形式的交點

Input

  • Members
  • Connection Type

Intersects

JointType

Output

  • Specific Type Joints
  • 應用Visitor Pattern個別實作每種Joint type的判斷條件,接收Intersect依照不同訪問者的條件輸出不同數量的特定物件。
Concrete Visitor 1 Concrete Visitor 2
Concrete Element A
Concrete Element B
  • 應用Visitor Pattern個別實作每種Joint type的判斷條件,接收Intersect依照不同訪問者的條件輸出不同數量的特定物件。
  • 訪問對象(接收者)穩定
  • 訪問者類型眾多且易於擴充與新增
BCFVisitor BCWVisitor CBVBVisitor ....
Intersect ....

Element

public class Intersect
    {
        public Node position { get; set; }
        public List<Member> memberGroup { get; set; }

        public void Accept(Visitor visitor)
        {
            visitor.Identify(this);
        }
    }

Visitor

public abstract class Visitor
{
        protected List<Joint> Joints = new List<Joint>();
        
        public Visitor() { }
        
        public abstract void Identify(Intersect intersect);

        public virtual List<Joint> GetJoints()
        {
            return Joints;
        }
        public virtual List<Joint> GetJoints(Intersect intersect)
        {
            
            this.Identify(intersect);
            return Joints;
        }
}

Concrete Visitor

public class BCWVisitor:Visitor
{
	//  ...
	public override void Identify(Intersect intersect)
    	{
       		// get the properties of intersect to implement each BCWJoint
       		// ....
            
       		// add the result to Joints inheriated from base class
       		Joints.Add(...);
            
    	}
}
public class VXRVisitor:Visitor
{
	//  ...
	public override void Identify(Intersect intersect)
    	{
       		// get the properties of intersect to implement each VXRJoint
       		// ....
            
       		// add the result to Joints inheriated from base class
       		Joints.Add(...);
            
    	}
}

Client

public override List<Joint> GetJoints(string group, Visitor visitor)
    {
            
            List<Member> steelFrames = BeamApp.GetSteelFramesByGroup(group);
            JointService jointService = new JointService(steelFrames);
            List<Intersect> intersects = jointService.GetIntersects();

            foreach(Intersect intersect in intersects)
            {
                intersect.Accept(visitor); 
            }
            
            return visitor.GetJoints();
     }

Feature Implements 2

Implemented

By Factory Pattern

Factory Pattern

將宣告一個物件類型這樣的操作封裝到Factory class中,就可以在執行期動態決定要new 哪個class

Myclass myclass = new Myclass();

Simple Factory

public class JointVisitorFactory
    {
        public Visitor CreateVisitor(ConnectionBase connection)
        {
            switch (connection.ConnectionJoint.JointType)
            {
                case Model.Connection.Joint.JointType.BCF:
                    return new BCFVisitor();
                case Model.Connection.Joint.JointType.BCW:
                    return new BCWVisitor();
                case Model.Connection.Joint.JointType.BG:
                    return new BGVisitor();
                case Model.Connection.Joint.JointType.BS:
                    return new BSVisitor();
                default:
                    return null;
            }
            
         }
         
     }

Factory presented by Reflection

public class ConnectionFactory
    {
        public ConnectionBase Create(JointType jointType, string name)
        {
            var type = Type.GetType(
            	"DAL.Model.ConnectionByJoint" +
                "." + jointType.ToString() + 
                "Connection", throwOnError: false);
                
            if (type == null)
            {
                throw new InvalidOperationException(
                	jointType.ToString() + "is not a known joint type");
            }
            
            if (!typeof(ConnectionBase).IsAssignableFrom(type))
            {
                throw new InvalidOperationException(
                	type.Name + 
                    "does not inferit from abstract connectionbase class");
            }

            Object[] args = { name, jointType };

            return (ConnectionBase)Activator.CreateInstance(type, args);
        }
     }

Conclusion

  • 如何理解並開始將Design pattern實現在專案中?
    • 善用class diagram
    • 繪製與自己專案相關的class diagram
    • 與你的同事、朋友討論

Thank you!

Reference:

  • Design guru:
    • https://bit.ly/3e8Ao1p
  • Bridge pattern:
    • https://bit.ly/3nCgS0d
  • Visitor pattern:
    • https://bit.ly/3eOTxnW
    • https://bit.ly/2SmVlxb
  • Factory pattern:
    • https://bit.ly/2PF5Zyd
 

Design pattern 在專案上的應用

By Emily W

Design pattern 在專案上的應用

  • 542