Skip to main content
added 16 characters in body
Source Link
candied_orange
  • 119.7k
  • 27
  • 233
  • 369

Notice what this function doesn't know. It doesn't know how to get the user. It doesn't know how to get the group. It doesn't know how to get the license. You have to tell it. It's because it doesn't knowof that not knowing that it can still be reused as is when any of that changes.

Notice what this function doesn't know. It doesn't know how to get the user. It doesn't know how to get the group. It doesn't know how to get the license. You have to tell it. It's because it doesn't know that it can be reused when any of that changes.

Notice what this function doesn't know. It doesn't know how to get the user. It doesn't know how to get the group. It doesn't know how to get the license. You have to tell it. It's because of that not knowing that it can still be reused as is when any of that changes.

added 130 characters in body
Source Link
candied_orange
  • 119.7k
  • 27
  • 233
  • 369

There is a pattern that describes this separation. It's named functional core imperative shellFunctional Core Imperative Shell.

It also gives you a business logic free space to dump all the other noise. That noise is not as easy to test. But, without the business logic, it doesn't need much testing.

Fowler was onto a similar idea when he introduced us to the Humble Object.

There is a pattern that describes this separation. It's named functional core imperative shell.

It also gives you a business logic free space to dump all the other noise. That noise is not as easy to test. But, without the business logic, it doesn't need much testing.

There is a pattern that describes this separation. It's named Functional Core Imperative Shell.

It also gives you a business logic free space to dump all the other noise. That noise is not as easy to test. But, without the business logic, it doesn't need much testing.

Fowler was onto a similar idea when he introduced us to the Humble Object.

added 57 characters in body
Source Link
candied_orange
  • 119.7k
  • 27
  • 233
  • 369

When should a function be given an argument vs getting the data itself?

When it has a job besides getting the data.

I can see why you'd be confused about this. None of your functions are named after what they are for. They're named after what you plan to do next. This is a very strange naming style that I don't think is serving you well. It's encouraging you to duplicate code pointlessly.

Consider a style where, rather then telling the caller what to do next, you're telling them what to expect.

$availableLicenses = Get-AvailableLicenses $license = Prompt-Menu $availableLicenses Grant-License -User $user -License $license Revoke-License -User $user -License $license 

Here we see functions so named. They aren't ours but they don't tell us what to do next. Just what we're going to get out of them.

What's missing from your question is anything for your custom function to do. We really need that to be able to properly answer this question.

So let me make up something for it to do. Lets say only members of the dev group should be granted licenses. That way there is some business logic to care about here.

function GrantLicenseToMember($username, $group, $license) { $Authorizatized = Get-ADGroupMember -Identity $group | Where-Object {$_.name -eq $Username} if ($Authorizatized){ Grant-License -User $username -License $license } } 

Notice what this function doesn't know. It doesn't know how to get the user. It doesn't know how to get the group. It doesn't know how to get the license. You have to tell it. It's because it doesn't know that it can be reused when any of that changes.

Now something, somewhere, has to know that stuff. Or none of this works.

function GrantSelectedDevLicense { $Credentials = Get-Credential $Username = $Credentials.UserName $group = 'Dev' $availableLicenses = Get-AvailableLicenses $selection = Prompt-Menu $availableLicenses GrantLicenseToMember $Username $group $selection } 

This can be called with no arguments. Which means it needed a very particular name because it resolves the dependencies in a very particular way. There can be many such functions that call GrantLicenseToMember. Ones that care about different groups. They'll all need different names.

The difference is GrantSelectedDevLicense focuses on it's job of knowing where to get all the needed info. GrantLicenseToMember focuses on it's job of knowing when to grant and not grant the license.

There is a pattern that describes this separation. It's named functional core imperative shell.

By making this separation you are free to keep an area of your code reserved for pure functions that are easy to test and reason about. Functions that are unaware of the world around them and so don't care when it changes. This lets you express your business logic as simply as possible.

It also gives you a simple business logic free space to dump all the other noise. That noise is not as easy to test. But, without the business logic, it doesn't need much testing.

It all comes at the cost of having to think up these names. Don't do it without a good name. A bad name will make me wish you hadn't created any new functions at all.

When should a function be given an argument vs getting the data itself?

When it has a job besides getting the data.

I can see why you'd be confused about this. None of your functions are named after what they are for. They're named after what you plan to do next. This is a very strange naming style that I don't think is serving you well. It's encouraging you to duplicate code pointlessly.

Consider a style where, rather then telling the caller what to do next, you're telling them what to expect.

$availableLicenses = Get-AvailableLicenses $license = Prompt-Menu $availableLicenses Grant-License -User $user -License $license Revoke-License -User $user -License $license 

Here we see functions so named. They aren't ours but they don't tell us what to do next. Just what we're going to get out of them.

What's missing from your question is anything for your custom function to do. We really need that to be able to properly answer this question.

So let me make up something for it to do. Lets say only members of the dev group should be granted licenses. That way there is some business logic to care about here.

function GrantLicenseToMember($username, $group, $license) { $Authorizatized = Get-ADGroupMember -Identity $group | Where-Object {$_.name -eq $Username} if ($Authorizatized){ Grant-License -User $username -License $license } } 

Notice what this function doesn't know. It doesn't know how to get the user. It doesn't know how to get the group. It doesn't know how to get the license. You have to tell it. It's because it doesn't know that it can be reused when any of that changes.

Now something, somewhere, has to know that stuff. Or none of this works.

function GrantSelectedDevLicense { $Credentials = Get-Credential $Username = $Credentials.UserName $group = 'Dev' $availableLicenses = Get-AvailableLicenses $selection = Prompt-Menu $availableLicenses GrantLicenseToMember $Username $group $selection } 

This can be called with no arguments. Which means it needed a very particular name because it resolves the dependencies in a very particular way. There can be many such functions that call GrantLicenseToMember. Ones that care about different groups. They'll all need different names.

The difference is GrantSelectedDevLicense focuses on it's job of knowing where to get all the needed info. GrantLicenseToMember focuses on it's job of knowing when to grant and not grant the license.

There is a pattern that describes this separation. It's named functional core imperative shell.

By making this separation you are free to keep an area of your code reserved for pure functions that are easy to test and reason about. Functions that are unaware of the world around them and so don't care when it changes.

It also gives you a simple business logic free space to dump all the other noise. That noise is not as easy to test. But, without the business logic, it doesn't need much testing.

It all comes at the cost of having to think up these names. Don't do it without a good name. A bad name will make me wish you hadn't created any new functions at all.

When should a function be given an argument vs getting the data itself?

When it has a job besides getting the data.

I can see why you'd be confused about this. None of your functions are named after what they are for. They're named after what you plan to do next. This is a very strange naming style that I don't think is serving you well. It's encouraging you to duplicate code pointlessly.

Consider a style where, rather then telling the caller what to do next, you're telling them what to expect.

$availableLicenses = Get-AvailableLicenses $license = Prompt-Menu $availableLicenses Grant-License -User $user -License $license Revoke-License -User $user -License $license 

Here we see functions so named. They aren't ours but they don't tell us what to do next. Just what we're going to get out of them.

What's missing from your question is anything for your custom function to do. We really need that to be able to properly answer this question.

So let me make up something for it to do. Lets say only members of the dev group should be granted licenses. That way there is some business logic to care about here.

function GrantLicenseToMember($username, $group, $license) { $Authorizatized = Get-ADGroupMember -Identity $group | Where-Object {$_.name -eq $Username} if ($Authorizatized){ Grant-License -User $username -License $license } } 

Notice what this function doesn't know. It doesn't know how to get the user. It doesn't know how to get the group. It doesn't know how to get the license. You have to tell it. It's because it doesn't know that it can be reused when any of that changes.

Now something, somewhere, has to know that stuff. Or none of this works.

function GrantSelectedDevLicense { $Credentials = Get-Credential $Username = $Credentials.UserName $group = 'Dev' $availableLicenses = Get-AvailableLicenses $selection = Prompt-Menu $availableLicenses GrantLicenseToMember $Username $group $selection } 

This can be called with no arguments. Which means it needed a very particular name because it resolves the dependencies in a very particular way. There can be many such functions that call GrantLicenseToMember. Ones that care about different groups. They'll all need different names.

The difference is GrantSelectedDevLicense focuses on it's job of knowing where to get all the needed info. GrantLicenseToMember focuses on it's job of knowing when to grant and not grant the license.

There is a pattern that describes this separation. It's named functional core imperative shell.

By making this separation you are free to keep an area of your code reserved for pure functions that are easy to test and reason about. Functions that are unaware of the world around them and so don't care when it changes. This lets you express your business logic as simply as possible.

It also gives you a business logic free space to dump all the other noise. That noise is not as easy to test. But, without the business logic, it doesn't need much testing.

It all comes at the cost of having to think up these names. Don't do it without a good name. A bad name will make me wish you hadn't created any new functions at all.

added 106 characters in body
Source Link
candied_orange
  • 119.7k
  • 27
  • 233
  • 369
Loading
added 11 characters in body
Source Link
candied_orange
  • 119.7k
  • 27
  • 233
  • 369
Loading
added 47 characters in body
Source Link
candied_orange
  • 119.7k
  • 27
  • 233
  • 369
Loading
deleted 4 characters in body
Source Link
candied_orange
  • 119.7k
  • 27
  • 233
  • 369
Loading
Source Link
candied_orange
  • 119.7k
  • 27
  • 233
  • 369
Loading