vendredi 20 novembre 2020

Design Pattern to make logging available without breaking abstractions

Currently I'm working within a framework that was developed by someone else at a company I'm doing work for so I have some restrictions with regards to the architecture. I was hoping there is a design pattern or some way I can handle my logging with the way it's set up now, without breaking abstractions.

So, there is a TestCase class. This class is the base for all test cases I write, and any test case I develop must inherit from it. The test case has logging methods, such as LogInfo, LogConfirmation etc.

Now I have another class called SignalGroup which contains one or more Signals. The SignalGroup has a Set method which abstracts the logic behind how the one or more values are set. It does this by knowing which mode the system is in etc etc. So for instance, keeping it simple, a SignalGroup's set method may just be the following in a mode that will result in setting all signals in a group to a value:

public void Set(int value){
   foreach (Signal signal in Signals){
    signal.Set(value)
   }
}

Now, in that set method, I need to log the value that each signal was set to, using the LogInfo method from the TestCase base class. My problem is, now I either need to

  1. have my Signal or SignalGroup know about TestCase base so it can keep its abstractions around setting the value but also call the LogInfo method
  2. Have my test case base know about the Signals within SignalGroup so I can implement the logging at its layer. But this means I have to make the TestCase include logic about the individual signals that I really would like to be abstracted away.

Is there any way I can make the logging available to the SignalGroup with a bit looser coupling so it doesn't need to directly know about the TestCase class?

OLAP cube designing: runtime generated measures

I'm facing a requirement that I'm not entirely sure that can be achieved by pure OLAP designing (anyway, my OLAP knowledge is SO small).

I have a dimension table such as

DROP TABLE IF EXISTS TMP_DEBUG_OLAP_44_BUILDING;
CREATE TABLE TMP_DEBUG_OLAP_44_BUILDING AS
SELECT 1 AS building_id,'Building 1' AS building_name
UNION ALL
SELECT 2 AS building_id,'Building 2' AS building_name
;

and a table fact (fact-1) such as

DROP TABLE IF EXISTS TMP_DEBUG_OLAP_44_FACTS;
CREATE TABLE TMP_DEBUG_OLAP_44_FACTS AS
SELECT 1 AS building_id,10 AS budget_amount,11 AS estimate_amount
UNION ALL
SELECT 2 AS building_id,12 AS budget_amount,13 AS estimate_amount
;

and a factor-conversion fact table (fact-2) such as

DROP TABLE IF EXISTS TMP_DEBUG_OLAP_44_FACT_FACTORS;
CREATE TABLE TMP_DEBUG_OLAP_44_FACT_FACTORS AS
SELECT 'DK' AS country_id,1.0 AS FACTOR
UNION ALL
SELECT 'MX' AS country_id,1.5 AS FACTOR
;

I've been asked to generate a measure per tuple [Measures].[Budget amount]_vs_country, so that it adds, per tuple in fact-2, a measure, multipling [Measures].[Budget amount] * factor_value.

Example: fact-table-1 first row is building_id=1, I need 3 measures: [Measures].[Budget amount], budget-amount1.0(DK) and budget-amount1.5(MX).

Now, if another country is added into the tables, there's a new tuple, hence, a new measure.

Is there any way this could be achieved without modifying the cube?

Thanks and regards!

Convert the interface implementation object from one namespace to another since both are having the same interface but different namespace

Is there way to convert the interface implementation object from one namespace to another since both are having the same interface but only the namespace is differing?

Use case is like below

namespace namespaceA
{
Public Interface IInterface
{
Method1();
Method2();
}
}

namespace namespaceB
{
Public Interface IInterface
{
Method1();
Method2();
}
}

We get two kind of objects.

namespaceA.IInterface object - new implementation

namespaceB.IInterface object. - exists as a part of legacy implementation.

We wanted to handle only one object in the code i.e. namespaceA.IInterface object, based on the new implementation. But due to legacy implementation we get namespaceB.IInterface object also. But we don’t want to any specific handling for legacy object and we wanted to handle in the same way as new object and implementation.

So if we get an namespaceB.IInterface object, is there way to convert/cast it to namespaceA.IInterface object provided that interface definitions are same but only exists in a different namespace?

So the code need not worry only about the handling of legacy object.

What pattern to use?: Chain of handlers where next handler needs to know the result of previos handler

I am working on a solution where I have implemented chain of responsibility pattern. All handlers in chain work independently and in some cases based on the input the chain is broken by a handler since there is no need to continue with the next handler. This has been working prefect until a new change request came in.:(

Now I have a case where I need to make a decision based on the result of my previous handler. Example: We have an object that based on FirstName and Last we build email and notify manager

First handler: Builds Email address (if it does not exists)

Second handler: if email has been created(and is not a new one) we need to notify manager

So the Second handler depends on the action/result of the First Handler

Choosing Chain of Responsibility: Am I breaking the pattern by wrapping the input and add some more data and use it as an input for my next handler?

Choosing Decorator: Am I breaking the pattern by breaking the chain in cases where I do not want the process to go further?

Or is there a third option?

what is General hierarchy pattern in software engineering?

I am searching on google and youtube for 3 days and didn't understand and unable to find a single solution for this pattern. (General hierarchy pattern) I have some questions about this pattern explanation of pattern? why it is used? how it is used in the UML class diagram? what are the benefits that we will achieve by using this pattern?

How to manage multiple version compatibility for single library?

How to manage multiple version compatibility for single library?

Working in an iOS app. My application MyApp is using a library MyLib which has a dependency in a 3rd party library OpenSSL v1.1. MyApp also needs to use that other version v1.2 of OpenSSL lib for other purpose in the app. Now, the team that is developer of MyLib needs to keep a version of OpenSSL v1.1 lib which might not be compatible with MyApps OpenSSL v1.2. How to handle this kind of dependency version controlling?

How to use interfaces as listeners from and Dialoge in Android?

Good morning Ladies and Gentlemen,

I have a really big problem and can't go on. I don't know how I can use a interface in android as an event listener. I defined an interface ProfilePictureTakenEvent with the method onProfilePictureTaken. In an dialog, which is opened by a button click on a fragment, the user can take an Image with the camera. I used the method startActivityForResult for it. The result (the image) of this action I get in the fragment (the overriden method onActivityResult). Now my question: How can I show this picture in my dialog when I get the result in my fragment? I thought that I can use an event listener, but I don't know how and didn't find any Explanation.

Here my code:

UserFragment.tk

class UserFragment() : Fragment() {
    private var userFragment: UserFragment? = null
    private var profilePictureTakenEvent: ProfilePictureTakenEvent? = null

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_user, container, false)
    }

    override fun onViewCreated(
        view: View,
        savedInstanceState: Bundle?
    ) {
        super.onViewCreated(view, savedInstanceState)

        this.userFragment = this

        val database = UserManagerDatabase(view.context)
        val repository = UserRepository(database)
        val factory = UserViewModelFactory(repository)

        val viewModel = ViewModelProviders.of(this, factory).get(UserViewModel::class.java)
        val adapter = UserAdapter(listOf(), viewModel)

        rvUsers.layoutManager = LinearLayoutManager(view.context)
        rvUsers.adapter = adapter

        var emailAddresses: List<String> = emptyList()

        viewModel.getAll().observe(viewLifecycleOwner, { userList ->
            adapter.users = userList
            emailAddresses = userList.map { user -> user.email }

            adapter.notifyDataSetChanged()
        })

        viewModel.getEmailAddresses().observe(viewLifecycleOwner, {emailAddresses = it })

        fBtnAddUser.setOnClickListener {
            AddUserDialog(view.context,
            object: UserCreateEvent {
                override fun onAddButtonClicked(user: User) {
                    viewModel.insert(user)
                }
            }, emailAddresses, userFragment).show()
        }
    }

    fun setProfilePictureTakenEvent(profilePictureTakenEvent: ProfilePictureTakenEvent) {
        this.profilePictureTakenEvent = profilePictureTakenEvent
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)

        if (requestCode == AddUserDialog.REQUEST_IMAGE_CAPTURE) {
            this.profilePictureTakenEvent?.onProfilePictureTaken(data)
        }
    }
}

AddUserDialog.kt:

class AddUserDialog(
    context: Context,
    private var userCreateEvents: UserCreateEvent,
    private var emails: List<String>,
    private var parentFragment: UserFragment?
) : AppCompatDialog(context), ProfilePictureTakenEvent {

    companion object {
        const val REQUEST_IMAGE_CAPTURE = 1
    }

    private var imageData: Bitmap? = null

    override fun onProfilePictureTaken(data: Intent?) {
        this.ivProfilePicture.setImageBitmap(data?.extras?.get("data") as Bitmap)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.dialog_add_user)
        setTitle(context.getString(R.string.title_add_user))

        val editTextViews: Map<String, EditText> = mapOf(
            "first_name"            to dAddUserEdFirstName,
            "last_name"             to dAddUserEdLastName,
            "email"                 to dAddUserEdEmail,
            "password"              to dAddUserEdPassword,
            "password_confirmation" to dAddUserEdPasswordConfirmation
        )

        dAddUserBtnSave.setOnClickListener {
            val firstName               = dAddUserEdFirstName.text.toString()
            val lastName                = dAddUserEdLastName.text.toString()
            val username                = "${firstName.toLowerCase(Locale.GERMAN)}-${lastName.toLowerCase(Locale.GERMAN)}"
            val email                   = dAddUserEdEmail.text.toString()
            val password                = dAddUserEdPassword.text.toString()
            val passwordConfirmation    = dAddUserEdPasswordConfirmation.text.toString()

            var error = false
            val emptyFields: StringBuilder = StringBuilder()

            // Check if any EditText is empty
            editTextViews.forEach {(key, editTextView) ->
                val textEmpty: Boolean = editTextView.text.toString().isEmpty()

                if (textEmpty) {
                    error = true
                    emptyFields.append("${context.getString(AppHelper.stringTranslation(key))}, ")
                }

                AppHelper.updateBackground(context, editTextView, if (textEmpty) R.drawable.input_field_error else R.drawable.input_field)
            }

            if (error) {
                //AppHelper.showToastLong(context, context.getString(R.string.error_field_not_filled, AppHelper.commaStringToCorrectGrammatical(context, emptyFields.toString())))
                return@setOnClickListener
            }

            // Check if E-Mail address is valid
            if (AppHelper.invalidEmail(email)) {
                AppHelper.showToastShort(context, R.string.error_invalid_email)
                return@setOnClickListener
            }

            // Check if supplied E-Mail address is unique
            if (emails.contains(email)) {
                AppHelper.showToastShort(context, R.string.error_email_already_taken)
                return@setOnClickListener
            }

            // Check if password and password confirmation match
            if (password != passwordConfirmation) {
                AppHelper.showToastShort(context, R.string.error_password_confirmation_not_matching)
                return@setOnClickListener
            }

            //TODO: Password hashing

            // Creating the User
            val user = User(firstName, lastName, username, email, password)
            userCreateEvents.onAddButtonClicked(user)

            // Closing the dialog after calling the onClickEvent and data is valid
            dismiss()
        }

        btnTakeProfilePicture.setOnClickListener {
            val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)

            try {
                parentFragment?.startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE)
            } catch (e: ActivityNotFoundException) {
                AppHelper.showToastLong(context, "Fehler")
            }
        }

        // Close dialog when cancel Button is clicked
        dAddUserBtnCancel.setOnClickListener { cancel() }
    }

}

ProfilePictureTakenEvent.kt:

interface ProfilePictureTakenEvent {
    fun onProfilePictureTaken(data: Intent?)
}

Thanks for your Help. Best regards,

Daniel